summaryrefslogtreecommitdiff
path: root/msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:55:07 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:56:55 +0200
commitd98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch)
tree267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c
parent869e68986aa8f69af6e7842260a68d1e5c6f796f (diff)
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c')
-rwxr-xr-xmsp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c939
1 files changed, 939 insertions, 0 deletions
diff --git a/msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c b/msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c
new file mode 100755
index 0000000..5e49716
--- /dev/null
+++ b/msp340/AndreiLEDs/driverlib/MSP430FR5xx_6xx/cs.c
@@ -0,0 +1,939 @@
+/* --COPYRIGHT--,BSD
+ * Copyright (c) 2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * --/COPYRIGHT--*/
+//*****************************************************************************
+//
+// cs.c - Driver for the cs Module.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup cs_api cs
+//! @{
+//
+//*****************************************************************************
+
+#include "inc/hw_regaccess.h"
+#include "inc/hw_memmap.h"
+
+#if defined(__MSP430_HAS_CS__) || defined(__MSP430_HAS_SFR__)
+#include "cs.h"
+
+#include <assert.h>
+
+//*****************************************************************************
+//
+// The following value is used by CS_getACLK, CS_getSMCLK, CS_getMCLK to
+// determine the operating frequency based on the available DCO frequencies.
+//
+//*****************************************************************************
+#define CS_DCO_FREQ_1 1000000
+#define CS_DCO_FREQ_2 2670000
+#define CS_DCO_FREQ_3 3330000
+#define CS_DCO_FREQ_4 4000000
+#define CS_DCO_FREQ_5 5330000
+#define CS_DCO_FREQ_6 6670000
+#define CS_DCO_FREQ_7 8000000
+#define CS_DCO_FREQ_8 16000000
+#define CS_DCO_FREQ_9 20000000
+#define CS_DCO_FREQ_10 24000000
+
+//*****************************************************************************
+//
+// Internal very low power VLOCLK, low frequency oscillator with 10kHz typical
+// frequency, internal low-power oscillator MODCLK with 5 MHz typical
+// frequency and LFMODCLK is MODCLK divided by 128.
+//
+//*****************************************************************************
+#define CS_VLOCLK_FREQUENCY 10000
+#define CS_MODCLK_FREQUENCY 5000000
+#define CS_LFMODCLK_FREQUENCY 39062
+
+//*****************************************************************************
+//
+// The following value is used by CS_XT1Start, CS_bypassXT1,
+// CS_XT1StartWithTimeout, CS_bypassXT1WithTimeout to properly set the XTS
+// bit. This frequnecy threshold is specified in the User's Guide.
+//
+//*****************************************************************************
+#define LFXT_FREQUENCY_THRESHOLD 50000
+
+//*****************************************************************************
+//
+// LFXT crystal frequency. Should be set with
+// CS_externalClockSourceInit if LFXT is used and user intends to invoke
+// CS_getSMCLK, CS_getMCLK, CS_getACLK and
+// CS_turnOnLFXT, CS_LFXTByPass, CS_turnOnLFXTWithTimeout,
+// CS_LFXTByPassWithTimeout.
+//
+//*****************************************************************************
+static uint32_t privateLFXTClockFrequency = 0;
+
+//*****************************************************************************
+//
+// The HFXT crystal frequency. Should be set with
+// CS_externalClockSourceInit if HFXT is used and user intends to invoke
+// CS_getSMCLK, CS_getMCLK, CS_getACLK,
+// CS_turnOnLFXT, CS_LFXTByPass, CS_turnOnLFXTWithTimeout,
+// CS_LFXTByPassWithTimeout.
+//
+//*****************************************************************************
+static uint32_t privateHFXTClockFrequency = 0;
+
+static uint32_t privateCSASourceClockFromDCO(uint8_t clockdivider)
+{
+ uint32_t CLKFrequency = 0;
+
+ if(HWREG16(CS_BASE + OFS_CSCTL1) & DCORSEL)
+ {
+ switch(HWREG16(CS_BASE + OFS_CSCTL1) & DCOFSEL_7)
+ {
+ case DCOFSEL_0:
+ CLKFrequency = CS_DCO_FREQ_1 / clockdivider;
+ break;
+ case DCOFSEL_1:
+ CLKFrequency = CS_DCO_FREQ_5 / clockdivider;
+ break;
+ case DCOFSEL_2:
+ CLKFrequency = CS_DCO_FREQ_6 / clockdivider;
+ break;
+ case DCOFSEL_3:
+ CLKFrequency = CS_DCO_FREQ_7 / clockdivider;
+ break;
+ case DCOFSEL_4:
+ CLKFrequency = CS_DCO_FREQ_8 / clockdivider;
+ break;
+ case DCOFSEL_5:
+ CLKFrequency = CS_DCO_FREQ_9 / clockdivider;
+ break;
+ case DCOFSEL_6:
+ case DCOFSEL_7:
+ CLKFrequency = CS_DCO_FREQ_10 / clockdivider;
+ break;
+ default:
+ CLKFrequency = 0;
+ break;
+ }
+ }
+ else
+ {
+ switch(HWREG16(CS_BASE + OFS_CSCTL1) & DCOFSEL_7)
+ {
+ case DCOFSEL_0:
+ CLKFrequency = CS_DCO_FREQ_1 / clockdivider;
+ break;
+ case DCOFSEL_1:
+ CLKFrequency = CS_DCO_FREQ_2 / clockdivider;
+ break;
+ case DCOFSEL_2:
+ CLKFrequency = CS_DCO_FREQ_3 / clockdivider;
+ break;
+ case DCOFSEL_3:
+ CLKFrequency = CS_DCO_FREQ_4 / clockdivider;
+ break;
+ case DCOFSEL_4:
+ CLKFrequency = CS_DCO_FREQ_5 / clockdivider;
+ break;
+ case DCOFSEL_5:
+ CLKFrequency = CS_DCO_FREQ_6 / clockdivider;
+ break;
+ case DCOFSEL_6:
+ case DCOFSEL_7:
+ CLKFrequency = CS_DCO_FREQ_7 / clockdivider;
+ break;
+ default:
+ CLKFrequency = 0;
+ break;
+ }
+ }
+
+ return (CLKFrequency);
+}
+
+static uint32_t privateCSAComputeCLKFrequency(uint16_t CLKSource,
+ uint16_t CLKSourceDivider)
+{
+ uint32_t CLKFrequency = 0;
+ uint8_t CLKSourceFrequencyDivider = 1;
+ uint8_t i = 0;
+
+ // Determine Frequency divider
+ for(i = 0; i < CLKSourceDivider; i++)
+ {
+ CLKSourceFrequencyDivider *= 2;
+ }
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ // Determine clock source based on CLKSource
+ switch(CLKSource)
+ {
+ // If LFXT is selected as clock source
+ case SELM__LFXTCLK:
+ CLKFrequency = (privateLFXTClockFrequency /
+ CLKSourceFrequencyDivider);
+
+ //Check if LFXTOFFG is not set. If fault flag is set
+ //VLO is used as source clock
+ if(HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG)
+ {
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG);
+ //Clear OFIFG fault flag
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+
+ if(HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG)
+ {
+ CLKFrequency = CS_LFMODCLK_FREQUENCY;
+ }
+ }
+ break;
+
+ case SELM__VLOCLK:
+ CLKFrequency =
+ (CS_VLOCLK_FREQUENCY / CLKSourceFrequencyDivider);
+ break;
+
+ case SELM__LFMODOSC:
+ CLKFrequency =
+ (CS_LFMODCLK_FREQUENCY / CLKSourceFrequencyDivider);
+
+ break;
+
+ case SELM__DCOCLK:
+ CLKFrequency =
+ privateCSASourceClockFromDCO(CLKSourceFrequencyDivider);
+
+ break;
+
+ case SELM__MODOSC:
+ CLKFrequency =
+ (CS_MODCLK_FREQUENCY / CLKSourceFrequencyDivider);
+
+ break;
+
+ case SELM__HFXTCLK:
+ CLKFrequency =
+ (privateHFXTClockFrequency / CLKSourceFrequencyDivider);
+
+ if(HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG)
+ {
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~HFXTOFFG;
+ //Clear OFIFG fault flag
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ if(HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG)
+ {
+ CLKFrequency = CS_MODCLK_FREQUENCY;
+ }
+ break;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+
+ return (CLKFrequency);
+}
+
+void CS_setExternalClockSource(uint32_t LFXTCLK_frequency,
+ uint32_t HFXTCLK_frequency)
+{
+ privateLFXTClockFrequency = LFXTCLK_frequency;
+ privateHFXTClockFrequency = HFXTCLK_frequency;
+}
+
+void CS_initClockSignal(uint8_t selectedClockSignal,
+ uint16_t clockSource,
+ uint16_t clockSourceDivider)
+{
+ //Verify User has selected a valid Frequency divider
+ assert(
+ (CS_CLOCK_DIVIDER_1 == clockSourceDivider) ||
+ (CS_CLOCK_DIVIDER_2 == clockSourceDivider) ||
+ (CS_CLOCK_DIVIDER_4 == clockSourceDivider) ||
+ (CS_CLOCK_DIVIDER_8 == clockSourceDivider) ||
+ (CS_CLOCK_DIVIDER_16 == clockSourceDivider) ||
+ (CS_CLOCK_DIVIDER_32 == clockSourceDivider)
+ );
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ switch(selectedClockSignal)
+ {
+ case CS_ACLK:
+ assert(
+ (CS_LFXTCLK_SELECT == clockSource) ||
+ (CS_VLOCLK_SELECT == clockSource) ||
+ (CS_LFMODOSC_SELECT == clockSource)
+ );
+
+ clockSourceDivider = clockSourceDivider << 8;
+ clockSource = clockSource << 8;
+
+ HWREG16(CS_BASE + OFS_CSCTL2) &= ~(SELA_7);
+ HWREG16(CS_BASE + OFS_CSCTL2) |= (clockSource);
+ HWREG16(CS_BASE + OFS_CSCTL3) &= ~(DIVA0 + DIVA1 + DIVA2);
+ HWREG16(CS_BASE + OFS_CSCTL3) |= clockSourceDivider;
+ break;
+ case CS_SMCLK:
+ assert(
+ (CS_LFXTCLK_SELECT == clockSource) ||
+ (CS_VLOCLK_SELECT == clockSource) ||
+ (CS_DCOCLK_SELECT == clockSource) ||
+ (CS_HFXTCLK_SELECT == clockSource) ||
+ (CS_LFMODOSC_SELECT == clockSource)||
+ (CS_MODOSC_SELECT == clockSource)
+ );
+
+ clockSource = clockSource << 4;
+ clockSourceDivider = clockSourceDivider << 4;
+
+ HWREG16(CS_BASE + OFS_CSCTL2) &= ~(SELS_7);
+ HWREG16(CS_BASE + OFS_CSCTL2) |= clockSource;
+ HWREG16(CS_BASE + OFS_CSCTL3) &= ~(DIVS0 + DIVS1 + DIVS2);
+ HWREG16(CS_BASE + OFS_CSCTL3) |= clockSourceDivider;
+ break;
+ case CS_MCLK:
+ assert(
+ (CS_LFXTCLK_SELECT == clockSource) ||
+ (CS_VLOCLK_SELECT == clockSource) ||
+ (CS_DCOCLK_SELECT == clockSource) ||
+ (CS_HFXTCLK_SELECT == clockSource) ||
+ (CS_LFMODOSC_SELECT == clockSource)||
+ (CS_MODOSC_SELECT == clockSource)
+ );
+
+ HWREG16(CS_BASE + OFS_CSCTL2) &= ~(SELM_7);
+ HWREG16(CS_BASE + OFS_CSCTL2) |= clockSource;
+ HWREG16(CS_BASE + OFS_CSCTL3) &= ~(DIVM0 + DIVM1 + DIVM2);
+ HWREG16(CS_BASE + OFS_CSCTL3) |= clockSourceDivider;
+ break;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_turnOnLFXT(uint16_t lfxtdrive)
+{
+ assert(privateLFXTClockFrequency != 0);
+
+ assert((lfxtdrive == CS_LFXT_DRIVE_0) ||
+ (lfxtdrive == CS_LFXT_DRIVE_1) ||
+ (lfxtdrive == CS_LFXT_DRIVE_2) ||
+ (lfxtdrive == CS_LFXT_DRIVE_3));
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch ON LFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~LFXTOFF;
+
+ //Highest drive setting for LFXTstartup
+ HWREG16(CS_BASE + OFS_CSCTL4_L) |= LFXTDRIVE1_L + LFXTDRIVE0_L;
+
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~LFXTBYPASS;
+
+ //Wait for Crystal to stabilize
+ while(HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG)
+ {
+ //Clear OSC flaut Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG);
+
+ //Clear OFIFG fault flag
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ //set requested Drive mode
+ HWREG16(CS_BASE + OFS_CSCTL4) = (HWREG16(CS_BASE + OFS_CSCTL4) &
+ ~(LFXTDRIVE_3)
+ ) |
+ (lfxtdrive);
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_bypassLFXT(void)
+{
+ //Verify user has set frequency of LFXT with SetExternalClockSource
+ assert(privateLFXTClockFrequency != 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ assert(privateLFXTClockFrequency < LFXT_FREQUENCY_THRESHOLD);
+
+ // Set LFXT in LF mode Switch off LFXT oscillator and enable BYPASS mode
+ HWREG16(CS_BASE + OFS_CSCTL4) |= (LFXTBYPASS + LFXTOFF);
+
+ //Wait until LFXT stabilizes
+ while(HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG)
+ {
+ //Clear OSC flaut Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG);
+
+ // Clear the global fault flag. In case the LFXT caused the global fault
+ // flag to get set this will clear the global error condition. If any
+ // error condition persists, global flag will get again.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+bool CS_turnOnLFXTWithTimeout(uint16_t lfxtdrive,
+ uint32_t timeout)
+{
+ assert(privateLFXTClockFrequency != 0);
+
+ assert((lfxtdrive == CS_LFXT_DRIVE_0) ||
+ (lfxtdrive == CS_LFXT_DRIVE_1) ||
+ (lfxtdrive == CS_LFXT_DRIVE_2) ||
+ (lfxtdrive == CS_LFXT_DRIVE_3));
+
+ assert(timeout > 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch ON LFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~LFXTOFF;
+
+ //Highest drive setting for LFXTstartup
+ HWREG16(CS_BASE + OFS_CSCTL4_L) |= LFXTDRIVE1_L + LFXTDRIVE0_L;
+
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~LFXTBYPASS;
+
+ while((HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG) && --timeout)
+ {
+ //Clear OSC fault Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG);
+
+ // Clear the global fault flag. In case the LFXT caused the global fault
+ // flag to get set this will clear the global error condition. If any
+ // error condition persists, global flag will get again.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ if(timeout)
+ {
+ //set requested Drive mode
+ HWREG16(CS_BASE + OFS_CSCTL4) = (HWREG16(CS_BASE + OFS_CSCTL4) &
+ ~(LFXTDRIVE_3)
+ ) |
+ (lfxtdrive);
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+ return (STATUS_SUCCESS);
+ }
+ else
+ {
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+ return (STATUS_FAIL);
+ }
+}
+
+bool CS_bypassLFXTWithTimeout(uint32_t timeout)
+{
+ assert(privateLFXTClockFrequency != 0);
+
+ assert(privateLFXTClockFrequency < LFXT_FREQUENCY_THRESHOLD);
+
+ assert(timeout > 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ // Set LFXT in LF mode Switch off LFXT oscillator and enable BYPASS mode
+ HWREG16(CS_BASE + OFS_CSCTL4) |= (LFXTBYPASS + LFXTOFF);
+
+ while((HWREG8(CS_BASE + OFS_CSCTL5) & LFXTOFFG) && --timeout)
+ {
+ //Clear OSC fault Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG);
+
+ // Clear the global fault flag. In case the LFXT caused the global fault
+ // flag to get set this will clear the global error condition. If any
+ // error condition persists, global flag will get again.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+
+ if(timeout)
+ {
+ return (STATUS_SUCCESS);
+ }
+ else
+ {
+ return (STATUS_FAIL);
+ }
+}
+
+void CS_turnOffLFXT(void)
+{
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch off LFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) |= LFXTOFF;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_turnOnHFXT(uint16_t hfxtdrive)
+{
+ assert(privateHFXTClockFrequency != 0);
+
+ assert((hfxtdrive == CS_HFXT_DRIVE_4MHZ_8MHZ) ||
+ (hfxtdrive == CS_HFXT_DRIVE_8MHZ_16MHZ) ||
+ (hfxtdrive == CS_HFXT_DRIVE_16MHZ_24MHZ)||
+ (hfxtdrive == CS_HFXT_DRIVE_24MHZ_32MHZ));
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ // Switch ON HFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~HFXTOFF;
+
+ //Disable HFXTBYPASS mode and Switch on HFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~HFXTBYPASS;
+
+ //If HFFrequency is 16MHz or above
+ if(privateHFXTClockFrequency > 16000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_3;
+ }
+ //If HFFrequency is between 8MHz and 16MHz
+ else if(privateHFXTClockFrequency > 8000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_2;
+ }
+ //If HFFrequency is between 0MHz and 4MHz
+ else if(privateHFXTClockFrequency < 4000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_0;
+ }
+ //If HFFrequency is between 4MHz and 8MHz
+ else
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_1;
+ }
+
+ while(HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG)
+ {
+ //Clear OSC flaut Flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(HFXTOFFG);
+
+ //Clear OFIFG fault flag
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ HWREG16(CS_BASE + OFS_CSCTL4) = (HWREG16(CS_BASE + OFS_CSCTL4) &
+ ~(CS_HFXT_DRIVE_24MHZ_32MHZ)
+ ) |
+ (hfxtdrive);
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_bypassHFXT(void)
+{
+ //Verify user has initialized value of HFXTClock
+ assert(privateHFXTClockFrequency != 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch off HFXT oscillator and set it to BYPASS mode
+ HWREG16(CS_BASE + OFS_CSCTL4) |= (HFXTBYPASS + HFXTOFF);
+
+ //Set correct HFFREQ bit for FR58xx/FR59xx devices
+
+ //If HFFrequency is 16MHz or above
+ if(privateHFXTClockFrequency > 16000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_3;
+ }
+ //If HFFrequency is between 8MHz and 16MHz
+ else if(privateHFXTClockFrequency > 8000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_2;
+ }
+ //If HFFrequency is between 0MHz and 4MHz
+ else if(privateHFXTClockFrequency < 4000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_0;
+ }
+ //If HFFrequency is between 4MHz and 8MHz
+ else
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_1;
+ }
+
+ while(HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG)
+ {
+ //Clear OSC fault Flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(HFXTOFFG);
+
+ //Clear OFIFG fault flag
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+bool CS_turnOnHFXTWithTimeout(uint16_t hfxtdrive,
+ uint32_t timeout)
+{
+ //Verify user has initialized value of HFXTClock
+ assert(privateHFXTClockFrequency != 0);
+
+ assert(timeout > 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch on HFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~HFXTOFF;
+
+ // Disable HFXTBYPASS mode
+ HWREG16(CS_BASE + OFS_CSCTL4) &= ~HFXTBYPASS;
+
+ //Set correct HFFREQ bit for FR58xx/FR59xx devices based
+ //on HFXTClockFrequency
+
+ //If HFFrequency is 16MHz or above
+ if(privateHFXTClockFrequency > 16000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_3;
+ }
+ //If HFFrequency is between 8MHz and 16MHz
+ else if(privateHFXTClockFrequency > 8000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_2;
+ }
+ //If HFFrequency is between 0MHz and 4MHz
+ else if(privateHFXTClockFrequency < 4000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_0;
+ }
+ //If HFFrequency is between 4MHz and 8MHz
+ else
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_1;
+ }
+
+ while((HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG) && --timeout)
+ {
+ //Clear OSC fault Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(HFXTOFFG);
+
+ // Clear the global fault flag. In case the LFXT caused the global fault
+ // flag to get set this will clear the global error condition. If any
+ // error condition persists, global flag will get again.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ if(timeout)
+ {
+ //Set drive strength for HFXT
+ HWREG16(CS_BASE + OFS_CSCTL4) = (HWREG16(CS_BASE + OFS_CSCTL4) &
+ ~(CS_HFXT_DRIVE_24MHZ_32MHZ)
+ ) |
+ (hfxtdrive);
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+ return (STATUS_SUCCESS);
+ }
+ else
+ {
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+ return (STATUS_FAIL);
+ }
+}
+
+bool CS_bypassHFXTWithTimeout(uint32_t timeout)
+{
+ //Verify user has initialized value of HFXTClock
+ assert(privateHFXTClockFrequency != 0);
+
+ assert(timeout > 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //If HFFrequency is 16MHz or above
+ if(privateHFXTClockFrequency > 16000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_3;
+ }
+ //If HFFrequency is between 8MHz and 16MHz
+ else if(privateHFXTClockFrequency > 8000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_2;
+ }
+ //If HFFrequency is between 0MHz and 4MHz
+ else if(privateHFXTClockFrequency < 4000000)
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_0;
+ }
+ //If HFFrequency is between 4MHz and 8MHz
+ else
+ {
+ HWREG16(CS_BASE + OFS_CSCTL4) = HFFREQ_1;
+ }
+
+ //Switch off HFXT oscillator and enable BYPASS mode
+ HWREG16(CS_BASE + OFS_CSCTL4) |= (HFXTBYPASS + HFXTOFF);
+
+ while((HWREG8(CS_BASE + OFS_CSCTL5) & HFXTOFFG) && --timeout)
+ {
+ //Clear OSC fault Flags fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(HFXTOFFG);
+
+ // Clear the global fault flag. In case the LFXT caused the global fault
+ // flag to get set this will clear the global error condition. If any
+ // error condition persists, global flag will get again.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+ }
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+
+ if(timeout)
+ {
+ return (STATUS_SUCCESS);
+ }
+ else
+ {
+ return (STATUS_FAIL);
+ }
+}
+
+void CS_turnOffHFXT(void)
+{
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ //Switch off HFXT oscillator
+ HWREG16(CS_BASE + OFS_CSCTL4) |= HFXTOFF;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_enableClockRequest(uint8_t selectClock)
+{
+ assert(
+ (CS_ACLK == selectClock)||
+ (CS_SMCLK == selectClock)||
+ (CS_MCLK == selectClock)||
+ (CS_MODOSC == selectClock));
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ HWREG8(CS_BASE + OFS_CSCTL6) |= selectClock;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+void CS_disableClockRequest(uint8_t selectClock)
+{
+ assert(
+ (CS_ACLK == selectClock)||
+ (CS_SMCLK == selectClock)||
+ (CS_MCLK == selectClock)||
+ (CS_MODOSC == selectClock));
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ HWREG8(CS_BASE + OFS_CSCTL6) &= ~selectClock;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+uint8_t CS_getFaultFlagStatus(uint8_t mask)
+{
+ assert(
+ (CS_HFXTOFFG == mask)||
+ (CS_LFXTOFFG == mask)
+ );
+ return (HWREG8(CS_BASE + OFS_CSCTL5) & mask);
+}
+
+void CS_clearFaultFlag(uint8_t mask)
+{
+ assert(
+ (CS_HFXTOFFG == mask)||
+ (CS_LFXTOFFG == mask)
+ );
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~mask;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+uint32_t CS_getACLK(void)
+{
+ //Find ACLK source
+ uint16_t ACLKSource = (HWREG16(CS_BASE + OFS_CSCTL2) & SELA_7);
+ ACLKSource = ACLKSource >> 8;
+
+ //Find ACLK frequency divider
+ uint16_t ACLKSourceDivider = HWREG16(CS_BASE + OFS_CSCTL3) & SELA_7;
+ ACLKSourceDivider = ACLKSourceDivider >> 8;
+
+ return (privateCSAComputeCLKFrequency(
+ ACLKSource,
+ ACLKSourceDivider));
+}
+
+uint32_t CS_getSMCLK(void)
+{
+ //Find SMCLK source
+ uint16_t SMCLKSource = HWREG8(CS_BASE + OFS_CSCTL2) & SELS_7;
+
+ SMCLKSource = SMCLKSource >> 4;
+
+ //Find SMCLK frequency divider
+ uint16_t SMCLKSourceDivider = HWREG16(CS_BASE + OFS_CSCTL3) & SELS_7;
+ SMCLKSourceDivider = SMCLKSourceDivider >> 4;
+
+ return (privateCSAComputeCLKFrequency(
+ SMCLKSource,
+ SMCLKSourceDivider)
+ );
+}
+
+uint32_t CS_getMCLK(void)
+{
+ //Find MCLK source
+ uint16_t MCLKSource = (HWREG16(CS_BASE + OFS_CSCTL2) & SELM_7);
+ //Find MCLK frequency divider
+ uint16_t MCLKSourceDivider = HWREG16(CS_BASE + OFS_CSCTL3) & SELM_7;
+
+ return (privateCSAComputeCLKFrequency(
+ MCLKSource,
+ MCLKSourceDivider)
+ );
+}
+
+void CS_turnOffVLO(void)
+{
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ HWREG16(CS_BASE + OFS_CSCTL4) |= VLOOFF;
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+uint16_t CS_clearAllOscFlagsWithTimeout(uint32_t timeout)
+{
+ assert(timeout > 0);
+
+ // Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ do
+ {
+ // Clear all osc fault flags
+ HWREG8(CS_BASE + OFS_CSCTL5) &= ~(LFXTOFFG + HFXTOFFG);
+
+ // Clear the global osc fault flag.
+ HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
+
+ // Check LFXT fault flags
+ }
+ while((HWREG8(SFR_BASE + OFS_SFRIFG1) & OFIFG) && --timeout);
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+
+ return (HWREG8(CS_BASE + OFS_CSCTL5) & (LFXTOFFG + HFXTOFFG));
+}
+
+void CS_setDCOFreq(uint16_t dcorsel,
+ uint16_t dcofsel)
+{
+ assert(
+ (dcofsel == CS_DCOFSEL_0)||
+ (dcofsel == CS_DCOFSEL_1)||
+ (dcofsel == CS_DCOFSEL_2)||
+ (dcofsel == CS_DCOFSEL_3)||
+ (dcofsel == CS_DCOFSEL_4)||
+ (dcofsel == CS_DCOFSEL_5)||
+ (dcofsel == CS_DCOFSEL_6)
+ );
+
+ //Verify user has selected a valid DCO Frequency Range option
+ assert(
+ (dcorsel == CS_DCORSEL_0)||
+ (dcorsel == CS_DCORSEL_1));
+
+ //Unlock CS control register
+ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY;
+
+ // Set user's frequency selection for DCO
+ HWREG16(CS_BASE + OFS_CSCTL1) = (dcorsel + dcofsel);
+
+ // Lock CS control register
+ HWREG8(CS_BASE + OFS_CSCTL0_H) = 0x00;
+}
+
+#endif
+//*****************************************************************************
+//
+//! Close the doxygen group for cs_api
+//! @}
+//
+//*****************************************************************************