]> git.sur5r.net Git - freertos/blob - Demo/MSP430X_MSP430F5438_IAR/F5XX_6XX_Core_Lib/hal_UCS.c
Remove unnecessary calls to fflush() in MSP430X/IAR demo.
[freertos] / Demo / MSP430X_MSP430F5438_IAR / F5XX_6XX_Core_Lib / hal_UCS.c
1 //*******************************************************************************\r
2 //  Provides Functions to Initialize the UCS/FLL and clock sources\r
3 //    File: hal_ucs.c\r
4 //\r
5 //    Texas Instruments\r
6 //\r
7 //    Version 1.2\r
8 //    11/24/09\r
9 //\r
10 //    V1.0  Initial Version\r
11 //    V1.1  Added timeout function\r
12 //    V1.1  Added parameter for XTDrive\r
13 //*******************************************************************************\r
14 \r
15 #include "msp430.h"\r
16 #include "hal_UCS.h"\r
17 \r
18 //************************************************************************\r
19 // Check and define required Defines\r
20 //************************************************************************\r
21 \r
22 #ifndef XT1LFOFFG               // Defines if not available in header file\r
23 #define XT1LFOFFG 0\r
24 #endif\r
25 #ifndef XT1HFOFFG               // Defines if not available in header file\r
26 #define XT1HFOFFG 0\r
27 #endif\r
28 #ifndef XT2OFFG                 // Defines if not available in header file\r
29 #define XT2OFFG 0\r
30 #endif\r
31 #ifndef XTS                    // Defines if not available in header file\r
32 #define XTS 0\r
33 #endif\r
34 #ifndef XT2DRIVE_3             // Defines if not available in header file\r
35 #define XT2DRIVE_3  0\r
36 #endif\r
37 \r
38 //====================================================================\r
39 /**\r
40  * Startup routine for 32kHz Cristal on LFXT1\r
41  *\r
42 */\r
43 void LFXT_Start(uint16_t xtdrive)\r
44 {\r
45   UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1 startup\r
46 \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
50   }\r
51   UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode\r
52 }\r
53 \r
54 //====================================================================\r
55 /**\r
56  * Startup routine for 32kHz Cristal on LFXT1 with timeout counter\r
57  *\r
58 */\r
59 uint16_t LFXT_Start_Timeout(uint16_t xtdrive, uint16_t timeout)\r
60 {\r
61   UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1 startup\r
62 \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
66   }\r
67   UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode\r
68   if (timeout)\r
69     return (UCS_STATUS_OK);\r
70   else\r
71     return (UCS_STATUS_ERROR);\r
72 }\r
73 \r
74 \r
75 //====================================================================\r
76 /**\r
77  * Startup routine for  XT1\r
78  *\r
79 */\r
80 void XT1_Start(uint16_t xtdrive)\r
81 {\r
82   UCSCTL6 &= ~(XT1OFF | XT1DRIVE_3);  // enable XT1\r
83   UCSCTL6 |= (XTS | xtdrive);         // enable XT1 and set XT1Drive\r
84 \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
88   }\r
89 }\r
90 \r
91 //====================================================================\r
92 /**\r
93  * Startup routine for XT1 with timeout counter\r
94  *\r
95 */\r
96 uint16_t XT1_Start_Timeout(uint16_t xtdrive, uint16_t timeout)\r
97 {\r
98   UCSCTL6 &= ~(XT1OFF | XT1DRIVE_3);  // enable XT1\r
99   UCSCTL6 |= (XTS | xtdrive);         // enable XT1 and set XT1Drive\r
100 \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
104   }\r
105   if (timeout)\r
106     return (UCS_STATUS_OK);\r
107   else\r
108     return (UCS_STATUS_ERROR);\r
109 }\r
110 \r
111 //====================================================================\r
112 /**\r
113  * Use  XT1 in Bypasss mode\r
114  *\r
115 */\r
116 void XT1_Bypass(void)\r
117 {\r
118   UCSCTL6 |= XT1BYPASS;\r
119 \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
123   }\r
124 }\r
125 \r
126 //====================================================================\r
127 /**\r
128  * Startup routine for  XT2\r
129  *\r
130 */\r
131 void XT2_Start(uint16_t xtdrive)\r
132 {\r
133   UCSCTL6 &= ~(XT2OFF | XT2DRIVE_3);  // enable XT2\r
134   UCSCTL6 |= (xtdrive);               // Set XT2Drive\r
135 \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
139   }\r
140 \r
141 }\r
142 \r
143 //====================================================================\r
144 /**\r
145  * Startup routine for XT2 with timeout counter\r
146  *\r
147 */\r
148 uint16_t XT2_Start_Timeout(uint16_t xtdrive, uint16_t timeout)\r
149 {\r
150   UCSCTL6 &= ~XT2OFF;                       // Set XT2 On\r
151   UCSCTL6 &= ~XT2DRIVE_3;                   // enable XT2\r
152   UCSCTL6 |= (xtdrive);                     // Set XT2Drive\r
153 \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
157   }\r
158   if (timeout)\r
159     return (UCS_STATUS_OK);\r
160   else\r
161     return (UCS_STATUS_ERROR);\r
162 }\r
163 \r
164 //====================================================================\r
165 /**\r
166  * Use XT2 in Bypasss mode\r
167  *\r
168 */\r
169 void XT2_Bypass(void)\r
170 {\r
171 #ifdef XT2BYPASS              // on devices without XT2 this function will be empty\r
172   UCSCTL6 |= XT2BYPASS;\r
173 \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
177   }\r
178 #endif\r
179 }\r
180 \r
181 //====================================================================\r
182 /**\r
183   * Initializes FLL of the UCS and wait till settled\r
184   *\r
185   * \param fsystem  required system frequency (MCLK) in kHz\r
186   * \param ratio    ratio between MCLK and FLLREFCLK\r
187   */\r
188 void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio)\r
189 {\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
193                                                                 \r
194   __bic_SR_register(SCG0);      // Enable FLL loop control\r
195 \r
196   Init_FLL(fsystem, ratio);\r
197   \r
198   while(x--)\r
199   {\r
200    __delay_cycles(30); \r
201   }\r
202   \r
203   __bis_SR_register(globalInterruptState);      // restore previous state\r
204 \r
205 }\r
206 \r
207 //====================================================================\r
208 /**\r
209   * Initializes FLL of the UCS\r
210   *\r
211   * \param fsystem  required system frequency (MCLK) in kHz\r
212   * \param ratio    ratio between fsystem and FLLREFCLK\r
213   */\r
214 static void Init_FLL(uint16_t fsystem, uint16_t ratio)\r
215 {\r
216   uint16_t d, dco_div_bits;\r
217   uint16_t mode = 0;\r
218 \r
219   d = ratio;\r
220   dco_div_bits = FLLD__2;        // Have at least a divider of 2\r
221   if (fsystem > 16000){\r
222     d >>= 1 ;\r
223     mode = 1;\r
224   }\r
225   else\r
226     fsystem <<= 1;               // fsystem = fsystem * 2\r
227 \r
228   while (d > 512)\r
229   {\r
230     dco_div_bits = dco_div_bits + FLLD0;  // set next higher div level\r
231     d >>= 1;\r
232   }\r
233 \r
234   UCSCTL0 = 0x000;               // Set DCO to lowest Tap\r
235 \r
236   UCSCTL2 &= ~(0x3FF);           // Reset FN bits\r
237   UCSCTL2 = dco_div_bits | (d - 1);\r
238 \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
253   else\r
254         UCSCTL1= DCORSEL_7 ;\r
255 \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
259   }\r
260 \r
261   if (mode == 1)                                          // fsystem > 16000\r
262     SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK);       // select DCOCLK\r
263   else\r
264    SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // selcet DCODIVCLK\r
265 \r
266   \r
267 } // End of fll_init()\r