1 //*******************************************************************************
\r
2 // Provides Functions to Initialize the UCS/FLL and clock sources
\r
10 // V1.0 Initial Version
\r
11 // V1.1 Added timeout function
\r
12 // V1.1 Added parameter for XTDrive
\r
13 //*******************************************************************************
\r
16 #include "hal_UCS.h"
\r
18 //************************************************************************
\r
19 // Check and define required Defines
\r
20 //************************************************************************
\r
22 #ifndef XT1LFOFFG // Defines if not available in header file
\r
25 #ifndef XT1HFOFFG // Defines if not available in header file
\r
28 #ifndef XT2OFFG // Defines if not available in header file
\r
31 #ifndef XTS // Defines if not available in header file
\r
34 #ifndef XT2DRIVE_3 // Defines if not available in header file
\r
35 #define XT2DRIVE_3 0
\r
38 //====================================================================
\r
40 * Startup routine for 32kHz Cristal on LFXT1
\r
43 void LFXT_Start(uint16_t xtdrive)
\r
45 UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1 startup
\r
47 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
48 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
\r
49 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
51 UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode
\r
54 //====================================================================
\r
56 * Startup routine for 32kHz Cristal on LFXT1 with timeout counter
\r
59 uint16_t LFXT_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
\r
61 UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1 startup
\r
63 while ((SFRIFG1 & OFIFG) && timeout--){ // check OFIFG fault flag
\r
64 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
\r
65 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
67 UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode
\r
69 return (UCS_STATUS_OK);
\r
71 return (UCS_STATUS_ERROR);
\r
75 //====================================================================
\r
77 * Startup routine for XT1
\r
80 void XT1_Start(uint16_t xtdrive)
\r
82 UCSCTL6 &= ~(XT1OFF | XT1DRIVE_3); // enable XT1
\r
83 UCSCTL6 |= (XTS | xtdrive); // enable XT1 and set XT1Drive
\r
85 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
86 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
87 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
91 //====================================================================
\r
93 * Startup routine for XT1 with timeout counter
\r
96 uint16_t XT1_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
\r
98 UCSCTL6 &= ~(XT1OFF | XT1DRIVE_3); // enable XT1
\r
99 UCSCTL6 |= (XTS | xtdrive); // enable XT1 and set XT1Drive
\r
101 while ((SFRIFG1 & OFIFG) && timeout--) { // check OFIFG fault flag
\r
102 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
103 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
106 return (UCS_STATUS_OK);
\r
108 return (UCS_STATUS_ERROR);
\r
111 //====================================================================
\r
113 * Use XT1 in Bypasss mode
\r
116 void XT1_Bypass(void)
\r
118 UCSCTL6 |= XT1BYPASS;
\r
120 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
121 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
122 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
126 //====================================================================
\r
128 * Startup routine for XT2
\r
131 void XT2_Start(uint16_t xtdrive)
\r
133 UCSCTL6 &= ~(XT2OFF | XT2DRIVE_3); // enable XT2
\r
134 UCSCTL6 |= (xtdrive); // Set XT2Drive
\r
136 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
137 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
138 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
143 //====================================================================
\r
145 * Startup routine for XT2 with timeout counter
\r
148 uint16_t XT2_Start_Timeout(uint16_t xtdrive, uint16_t timeout)
\r
150 UCSCTL6 &= ~XT2OFF; // Set XT2 On
\r
151 UCSCTL6 &= ~XT2DRIVE_3; // enable XT2
\r
152 UCSCTL6 |= (xtdrive); // Set XT2Drive
\r
154 while ((SFRIFG1 & OFIFG) && timeout--){ // check OFIFG fault flag
\r
155 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
156 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
159 return (UCS_STATUS_OK);
\r
161 return (UCS_STATUS_ERROR);
\r
164 //====================================================================
\r
166 * Use XT2 in Bypasss mode
\r
169 void XT2_Bypass(void)
\r
171 #ifdef XT2BYPASS // on devices without XT2 this function will be empty
\r
172 UCSCTL6 |= XT2BYPASS;
\r
174 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
175 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
176 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
181 //====================================================================
\r
183 * Initializes FLL of the UCS and wait till settled
\r
185 * \param fsystem required system frequency (MCLK) in kHz
\r
186 * \param ratio ratio between MCLK and FLLREFCLK
\r
188 void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio)
\r
190 volatile uint16_t x = ratio * 32;
\r
191 // save actual state of FLL loop control
\r
192 uint16_t globalInterruptState = __get_SR_register() & SCG0;
\r
194 __bic_SR_register(SCG0); // Enable FLL loop control
\r
196 Init_FLL(fsystem, ratio);
\r
200 __delay_cycles(30);
\r
203 __bis_SR_register(globalInterruptState); // restore previous state
\r
207 //====================================================================
\r
209 * Initializes FLL of the UCS
\r
211 * \param fsystem required system frequency (MCLK) in kHz
\r
212 * \param ratio ratio between fsystem and FLLREFCLK
\r
214 static void Init_FLL(uint16_t fsystem, uint16_t ratio)
\r
216 uint16_t d, dco_div_bits;
\r
220 dco_div_bits = FLLD__2; // Have at least a divider of 2
\r
221 if (fsystem > 16000){
\r
226 fsystem <<= 1; // fsystem = fsystem * 2
\r
230 dco_div_bits = dco_div_bits + FLLD0; // set next higher div level
\r
234 UCSCTL0 = 0x000; // Set DCO to lowest Tap
\r
236 UCSCTL2 &= ~(0x3FF); // Reset FN bits
\r
237 UCSCTL2 = dco_div_bits | (d - 1);
\r
239 if (fsystem <= 630) // fsystem < 0.63MHz
\r
240 UCSCTL1= DCORSEL_0 ;
\r
241 else if (fsystem < 1250) // 0.63MHz < fsystem < 1.25MHz
\r
242 UCSCTL1= DCORSEL_1 ;
\r
243 else if (fsystem < 2500) // 1.25MHz < fsystem < 2.5MHz
\r
244 UCSCTL1= DCORSEL_2 ;
\r
245 else if (fsystem < 5000) // 2.5MHz < fsystem < 5MHz
\r
246 UCSCTL1= DCORSEL_3 ;
\r
247 else if (fsystem < 10000) // 5MHz < fsystem < 10MHz
\r
248 UCSCTL1= DCORSEL_4 ;
\r
249 else if (fsystem < 20000) // 10MHz < fsystem < 20MHz
\r
250 UCSCTL1= DCORSEL_5 ;
\r
251 else if (fsystem < 40000) // 20MHz < fsystem < 40MHz
\r
252 UCSCTL1= DCORSEL_6 ;
\r
254 UCSCTL1= DCORSEL_7 ;
\r
256 while (SFRIFG1 & OFIFG) { // check OFIFG fault flag
\r
257 UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
\r
258 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
\r
261 if (mode == 1) // fsystem > 16000
\r
262 SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK); // select DCOCLK
\r
264 SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // selcet DCODIVCLK
\r
267 } // End of fll_init()
\r