]> git.karo-electronics.de Git - oswald.git/blob - metawatch/F5xx_F6xx_Core_Lib/HAL_UCS.c
Power saving changes, add new fonts, bitmaps and screens
[oswald.git] / metawatch / F5xx_F6xx_Core_Lib / HAL_UCS.c
1 /*******************************************************************************
2  *
3  * HAL_UCS.c
4  * Provides Functions to Initialize the UCS/FLL and clock sources
5  * 
6  *
7  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
8  * 
9  * 
10  *  Redistribution and use in source and binary forms, with or without 
11  *  modification, are permitted provided that the following conditions 
12  *  are met:
13  *
14  *    Redistributions of source code must retain the above copyright 
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  *    Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the 
19  *    documentation and/or other materials provided with the   
20  *    distribution.
21  *
22  *    Neither the name of Texas Instruments Incorporated nor the names of
23  *    its contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
27  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
28  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
30  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
31  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
32  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
35  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
36  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  * 
38  * Created: Version 1.0 11/24/2009
39  * Updated: Version 2.0 12/15/2010
40  *          Added Functions: XT2_Stop() and XT1_Stop()
41  *          Modified all functions to preserve drive settings
42  *  
43  ******************************************************************************/
44
45 #include "msp430.h"
46 #include "HAL_UCS.h"
47 // #include "hal_calibration.h"
48
49 /*******************************************************************************
50  * Check and define required Defines
51  ******************************************************************************/
52 #ifndef XT1LFOFFG               // Defines if not available in header file
53 #define XT1LFOFFG   0
54 #endif
55
56 #ifndef XT1HFOFFG               // Defines if not available in header file
57 #define XT1HFOFFG   0
58 #endif
59
60 #ifndef XT2OFFG                 // Defines if not available in header file
61 #define XT2OFFG     0
62 #endif
63
64 #ifndef XTS                     // Defines if not available in header file
65 #define XTS         0
66 #endif
67
68 #ifndef XT2DRIVE_3              // Defines if not available in header file
69 #define XT2DRIVE_3  0
70 #endif
71
72
73 /*******************************************************************************
74  * \brief   Initializes FLL of the UCS
75  *
76  * \param fsystem  Required system frequency (MCLK) in kHz
77  * \param ratio    Ratio between fsystem and FLLREFCLK
78  ******************************************************************************/
79 static void Init_FLL(unsigned int fsystem, unsigned int ratio);
80
81
82 #if 0
83 void LFXT_Start(unsigned int xtdrive)
84 {
85   // If the drive setting is not already set to maximum
86   // Set it to max for LFXT startup
87   if ((UCSCTL6 & XT1DRIVE_3)!= XT1DRIVE_3) { 
88     UCSCTL6_L |= XT1DRIVE1_L + XT1DRIVE0_L; // Highest drive setting for XT1startup
89   }
90
91   while (SFRIFG1 & OFIFG) {   // Check OFIFG fault flag
92     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
93     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
94   }
95   
96   UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) | (xtdrive); // set requested Drive mode
97 }
98 #endif
99
100 unsigned int LFXT_Start_Timeout(unsigned int xtdrive, unsigned int timeout)
101 {
102   // add in capacitor setting
103   //SetOscillatorCapacitorValues();
104   
105   // If the drive setting is not already set to maximum
106   // Set it to max for LFXT startup
107   if ((UCSCTL6 & XT1DRIVE_3)!= XT1DRIVE_3) { 
108    UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1startup
109   }
110
111   while ((SFRIFG1 & OFIFG) && timeout--){   // Check OFIFG fault flag
112     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
113     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
114   }
115   
116   UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode
117   
118   // add in capacitor setting
119   //SetOscillatorCapacitorValues();
120   
121   if (timeout)
122     return (UCS_STATUS_OK);
123   else
124     return (UCS_STATUS_ERROR);
125 }
126
127 #if 0
128 void XT1_Start(unsigned int xtdrive)
129 {
130   // Check if drive value is the expected one
131   if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
132     UCSCTL6 &= ~XT1DRIVE_3;                 // Clear XT1drive field
133     UCSCTL6 |= xtdrive;                     // Set requested value
134   }
135   
136   UCSCTL6 &= ~XT1OFF;                       // Enable XT1
137   UCSCTL6 |= XTS;                           // Enable HF mode
138
139   while (SFRIFG1 & OFIFG) {   // Check OFIFG fault flag
140     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
141     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
142   }
143 }
144
145 unsigned int XT1_Start_Timeout(unsigned int xtdrive, unsigned int timeout)
146 {
147   // Check if drive value is the expected one
148   if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
149     UCSCTL6 &= ~XT1DRIVE_3;                 // Clear XT1drive field
150     UCSCTL6 |= xtdrive;                     // Set requested value
151   }
152   
153   UCSCTL6 &= ~XT1OFF;                       // Enable XT1
154   UCSCTL6 |= XTS;                           // Enable HF mode
155
156   while ((SFRIFG1 & OFIFG) && timeout--) {  // Check OFIFG fault flag
157     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
158     SFRIFG1 &= ~OFIFG;                      // Clear OFIFG fault flag
159   }
160   
161   if (timeout) {
162     return UCS_STATUS_OK;
163   }
164   else {
165     return UCS_STATUS_ERROR;
166   }
167 }
168
169 void XT1_Bypass(void)
170 {
171   UCSCTL6 |= XT1BYPASS;
172
173   while (SFRIFG1 & OFIFG) {   // Check OFIFG fault flag
174     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
175     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
176   }
177 }
178 #endif
179
180 void XT1_Stop(void)
181 {
182   UCSCTL6 |= XT1OFF;                         // Switch off XT1 oscillator
183 }
184
185 #if 0
186 void XT2_Start(unsigned int xtdrive)
187 {
188   // Check if drive value is the expected one
189   if ((UCSCTL6 & XT2DRIVE_3) != xtdrive) {
190     UCSCTL6 &= ~XT2DRIVE_3;                 // Clear XT2drive field
191     UCSCTL6 |= xtdrive;                     // Set requested value
192   }
193   
194   UCSCTL6 &= ~XT2OFF; 
195   
196   while (SFRIFG1 & OFIFG) {                 // Check OFIFG fault flag
197     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
198     SFRIFG1 &= ~OFIFG;                      // Clear OFIFG fault flag
199   }
200 }
201
202 unsigned int XT2_Start_Timeout(unsigned int xtdrive, unsigned int timeout)
203 {
204   // Check if drive value is the expected one
205   if ((UCSCTL6 & XT2DRIVE_3) != xtdrive)  {
206     UCSCTL6 &= ~XT2DRIVE_3;                 // Clear XT2drive field
207     UCSCTL6 |= xtdrive;                     // Set requested value
208   }
209   
210   UCSCTL6 &= ~XT2OFF; 
211
212   while ((SFRIFG1 & OFIFG) && timeout--) {  // Check OFIFG fault flag
213     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
214     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
215   }
216   
217   if (timeout) {
218     return UCS_STATUS_OK;
219   }
220   else {
221     return UCS_STATUS_ERROR;
222   }
223 }
224
225 void XT2_Bypass(void)
226 {
227 #ifdef XT2BYPASS              // On devices without XT2 this function will be empty
228   UCSCTL6 |= XT2BYPASS;
229
230   while (SFRIFG1 & OFIFG) {   // Check OFIFG fault flag
231     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
232     SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
233   }
234 #endif
235 }
236
237 void XT2_Stop(void)
238 {
239   UCSCTL6 |= XT2OFF;                         // Switch off XT2 oscillator
240 }
241 #endif
242
243 void Init_FLL_Settle(unsigned int fsystem, unsigned int ratio)
244 {
245   volatile unsigned int x;
246
247   // x = ratio * 32;
248   x = ratio << 5;
249   Init_FLL(fsystem, ratio);
250   
251   /* from changes in Init_FLL we know that fll is now enabled */
252   while (x--) {
253    __delay_cycles(30); 
254   }
255 }
256
257 static void Init_FLL(unsigned int fsystem, unsigned int ratio)
258 {
259   unsigned int d, dco_div_bits;
260   unsigned int mode;
261   
262 #if 0
263   unsigned int srRegisterState;
264 #endif
265   
266   mode = 0;
267
268   /* we only run this at startup and we want the fll enabled on exit */
269 #if 0
270   // Save actual state of FLL loop control, then disable it. This is needed to
271   // prevent the FLL from acting as we are making fundamental modifications to
272   // the clock setup.
273   srRegisterState = __get_SR_register() & SCG0;
274 #endif
275   
276   d = ratio;
277   dco_div_bits = FLLD__2;        // Have at least a divider of 2
278   
279   if (fsystem > 16000) {
280     d >>= 1 ;
281     mode = 1;
282   }
283   else {
284     fsystem <<= 1;               // fsystem = fsystem * 2
285   }
286
287   while (d > 512) {
288     dco_div_bits = dco_div_bits + FLLD0;  // Set next higher div level
289     d >>= 1;
290   }
291
292   // Disable FLL
293   __bis_SR_register(SCG0);  
294   
295   UCSCTL0 = 0x0000;              // Set DCO to lowest Tap
296
297   UCSCTL2 &= ~(0x03FF);          // Reset FN bits
298   UCSCTL2 = dco_div_bits | (d - 1);
299
300   if (fsystem <= 630)            //           fsystem < 0.63MHz
301         UCSCTL1 = DCORSEL_0;
302   else if (fsystem <  1250)      // 0.63MHz < fsystem < 1.25MHz
303         UCSCTL1 = DCORSEL_1;
304   else if (fsystem <  2500)      // 1.25MHz < fsystem <  2.5MHz
305         UCSCTL1 = DCORSEL_2;
306   else if (fsystem <  5000)      // 2.5MHz  < fsystem <    5MHz
307         UCSCTL1 = DCORSEL_3;
308   else if (fsystem <  10000)     // 5MHz    < fsystem <   10MHz
309         UCSCTL1 = DCORSEL_4;
310   else if (fsystem <  20000)     // 10MHz   < fsystem <   20MHz
311         UCSCTL1 = DCORSEL_5;
312   else if (fsystem <  40000)     // 20MHz   < fsystem <   40MHz
313         UCSCTL1 = DCORSEL_6;
314   else
315         UCSCTL1 = DCORSEL_7;
316
317   // Re-enable FLL
318   __bic_SR_register(SCG0);
319   
320   while (SFRIFG1 & OFIFG) {                               // Check OFIFG fault flag
321     UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG);     // Clear OSC flaut Flags
322     SFRIFG1 &= ~OFIFG;                                    // Clear OFIFG fault flag
323   }
324
325   /* Init fll is only run at startup - We want the fll enabled when
326    * this function is complete (so don't save a restore setting)
327    */
328 #if 0
329   // Restore previous SCG0
330   __bis_SR_register(srRegisterState);                     
331 #endif
332   
333   if (mode == 1) {                                                // fsystem > 16000
334     SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK);       // Select DCOCLK
335   }
336   else {
337     SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // Select DCODIVCLK
338   }
339   
340 }