1 /**
2 * @file hal_board.c
3 *
4 * Copyright 2008 Texas Instruments, Inc.
5 ******************************************************************************/
6 #include "hal_board.h"
7
8 #include "msp430x54x.h"
9
10 #include "hal_compat.h"
11 #include "hal_adc.h"
12 #include "hal_usb.h"
13
14 static void halBoardSetVCoreUp(unsigned char level);
15 static void halBoardSetVCoreDown(unsigned char level);
16 static void halBoardGetSystemClockSettings(unsigned char systemClockSpeed,
17 unsigned char *setDcoRange,
18 unsigned char *setVCore,
19 unsigned int *setMultiplier);
20
21 /************************************************************************
22 * @brief Increments the VCore setting.
23 *
24 * @param level The target VCore setting
25 *
26 * @return none
27 *************************************************************************/
halBoardSetVCoreUp(unsigned char level)28 static void halBoardSetVCoreUp (unsigned char level)
29 {
30 // Open PMM module registers for write access
31 PMMCTL0_H = 0xA5;
32
33 // Set SVS/M high side to new level
34 SVSMHCTL = (SVSMHCTL & ~(SVSHRVL0*3 + SVSMHRRL0)) | \
35 (SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level);
36
37 // Set SVM new Level
38 SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
39 // Set SVS/M low side to new level
40 SVSMLCTL = (SVSMLCTL & ~(SVSMLRRL_3)) | (SVMLE + SVSMLRRL0 * level);
41
42 while ((PMMIFG & SVSMLDLYIFG) == 0); // Wait till SVM is settled (Delay)
43 PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x
44 PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags
45
46 if ((PMMIFG & SVMLIFG))
47 while ((PMMIFG & SVMLVLRIFG) == 0); // Wait till level is reached
48
49 // Set SVS/M Low side to new level
50 SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0*3 + SVSMLRRL_3)) | \
51 (SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level);
52
53 // Lock PMM module registers from write access
54 PMMCTL0_H = 0x00;
55 }
56
57 /************************************************************************
58 * @brief Decrements the VCore setting.
59 *
60 * @param level The target VCore.
61 *
62 * @return none
63 *************************************************************************/
halBoardSetVCoreDown(unsigned char level)64 static void halBoardSetVCoreDown(unsigned char level)
65 {
66 // Open PMM module registers for write access
67 PMMCTL0_H = 0xA5;
68
69 // Set SVS/M low side to new level
70 SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0*3 + SVSMLRRL_3)) | \
71 (SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level);
72
73 while ((PMMIFG & SVSMLDLYIFG) == 0); // Wait till SVM is settled (Delay)
74 PMMCTL0_L = (level * PMMCOREV0); // Set VCore to new level
75 // Lock PMM module registers for write access
76
77 PMMCTL0_H = 0x00;
78 }
79
80 /************************************************************************
81 * @brief Get function for the DCORSEL, VCORE, and DCO multiplier settings
82 * that map to a given clock speed.
83 *
84 * @param systemClockSpeed Target DCO frequency - SYSCLK_xxMHZ.
85 *
86 * @param setDcoRange Pointer to the DCO range select bits.
87 *
88 * @param setVCore Pointer to the VCore level bits.
89 *
90 * @param setMultiplier Pointer to the DCO multiplier bits.
91 *
92 * @return none
93 ************************************************************************/
halBoardGetSystemClockSettings(unsigned char systemClockSpeed,unsigned char * setDcoRange,unsigned char * setVCore,unsigned int * setMultiplier)94 static void halBoardGetSystemClockSettings(unsigned char systemClockSpeed,
95 unsigned char *setDcoRange,
96 unsigned char *setVCore,
97 unsigned int *setMultiplier)
98 {
99 switch (systemClockSpeed)
100 {
101 case SYSCLK_1MHZ:
102 *setDcoRange = DCORSEL_1MHZ;
103 *setVCore = VCORE_1MHZ;
104 *setMultiplier = DCO_MULT_1MHZ;
105 break;
106 case SYSCLK_4MHZ:
107 *setDcoRange = DCORSEL_4MHZ;
108 *setVCore = VCORE_4MHZ;
109 *setMultiplier = DCO_MULT_4MHZ;
110 break;
111 case SYSCLK_8MHZ:
112 *setDcoRange = DCORSEL_8MHZ;
113 *setVCore = VCORE_8MHZ;
114 *setMultiplier = DCO_MULT_8MHZ;
115 break;
116 case SYSCLK_12MHZ:
117 *setDcoRange = DCORSEL_12MHZ;
118 *setVCore = VCORE_12MHZ;
119 *setMultiplier = DCO_MULT_12MHZ;
120 break;
121 case SYSCLK_16MHZ:
122 *setDcoRange = DCORSEL_16MHZ;
123 *setVCore = VCORE_16MHZ;
124 *setMultiplier = DCO_MULT_16MHZ;
125 break;
126 /*-------------------------------------
127 * Commented out because fmax = 18 MHz
128 * ------------------------------------
129 case SYSCLK_20MHZ:
130 *setDcoRange = DCORSEL_20MHZ;
131 *setVCore = VCORE_20MHZ;
132 *setMultiplier = DCO_MULT_20MHZ;
133 break;
134 case SYSCLK_25MHZ:
135 *setDcoRange = DCORSEL_25MHZ;
136 *setVCore = VCORE_25MHZ;
137 *setMultiplier = DCO_MULT_25MHZ;
138 break;
139 *-------------------------------------*/
140 }
141 }
142
143 /************************************************************************
144 * @brief Set function for the PMM core voltage (PMMCOREV) setting
145 *
146 * @param level Target VCore setting
147 *
148 * @return none
149 *************************************************************************/
halBoardSetVCore(unsigned char level)150 void halBoardSetVCore(unsigned char level)
151 {
152 unsigned int currentVCore;
153
154 currentVCore = PMMCTL0 & PMMCOREV_3; // Get actual VCore
155 // Change VCore step by step
156 while (level != currentVCore)
157 {
158 if (level > currentVCore)
159 halBoardSetVCoreUp(++currentVCore);
160 else
161 halBoardSetVCoreDown(--currentVCore);
162 }
163 }
164
165 /************************************************************************
166 * @brief Disables all supply voltage supervision and monitoring.
167 *
168 * @param none
169 *
170 * @return none
171 *************************************************************************/
halBoardDisableSVS(void)172 void halBoardDisableSVS(void)
173 {
174 // Open PMM module registers for write access
175 PMMCTL0_H = 0xA5;
176
177 SVSMLCTL &= ~( SVMLE + SVSLE + SVSLFP + SVMLFP ); // Disable Low side SVM
178 SVSMHCTL &= ~( SVMHE + SVSHE + SVSHFP + SVMHFP ); // Disable High side SVM
179 PMMCTL1 = PMMREFMD;
180
181 // Lock PMM module registers for write access
182 PMMCTL0_H = 0x00;
183 }
184
185 /************************************************************************
186 * @brief Enables all supply voltage supervision and monitoring
187 *
188 * @param none
189 *
190 * @return none
191 *************************************************************************/
halBoardEnableSVS(void)192 void halBoardEnableSVS(void)
193 {
194 // Open PMM module registers for write access
195 PMMCTL0_H = 0xA5;
196
197 /*-----------
198 * NOTE: To attain the expected < 6 us wakeup from LPM modes, the following
199 * two lines must be commented out due to the fact that the PMM will hold
200 * the CPU until the reference is fully settled.
201 *----------*/
202 SVSMHCTL &= ~(SVSHFP+SVMHFP); // Disable full-performance mode
203 SVSMLCTL &= ~(SVSLFP+SVMLFP); // Disable full-performance mode
204 SVSMLCTL |= ( SVMLE + SVSLE); // Enable Low side SVM
205 SVSMHCTL |= ( SVMHE + SVSHE); // Enable High side SVM
206 PMMCTL1 &= ~PMMREFMD;
207
208 // Lock PMM module registers for write access
209 PMMCTL0_H = 0x00;
210 }
211
212 /************************************************************************
213 * @brief Initialization routine for XT1.
214 *
215 * Sets the necessary internal capacitor values and loops until all
216 * ocillator fault flags remain cleared.
217 *
218 * @param none
219 *
220 * @return none
221 *************************************************************************/
halBoardStartXT1(void)222 void halBoardStartXT1(void)
223 {
224 // Set up XT1 Pins to analog function, and to lowest drive
225 P7SEL |= 0x03;
226 UCSCTL6 |= XCAP_3 ; // Set internal cap values
227
228 while(SFRIFG1 & OFIFG) { // Check OFIFG fault flag
229 while ( (SFRIFG1 & OFIFG)) // Check OFIFG fault flag
230 {
231 // Clear OSC fault flags
232 UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT1HFOFFG + XT2OFFG);
233 SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
234 }
235 UCSCTL6 &= ~(XT1DRIVE1_L+XT1DRIVE0); // Reduce the drive strength
236 }
237 }
238
239 /************************************************************************
240 * @brief Set function for MCLK frequency.
241 *
242 * @param systemClockSpeed Intended frequency of operation - SYSCLK_xxMHZ.
243 *
244 * @return none
245 *************************************************************************/
halBoardSetSystemClock(unsigned char systemClockSpeed)246 void halBoardSetSystemClock(unsigned char systemClockSpeed)
247 {
248 unsigned char setDcoRange = 0;
249 unsigned char setVCore = 0;
250 unsigned int setMultiplier = 0;
251
252 halBoardGetSystemClockSettings( systemClockSpeed, &setDcoRange, \
253 &setVCore, &setMultiplier);
254
255 if (setVCore > (PMMCTL0 & PMMCOREV_3)) // Only change VCore if necessary
256 halBoardSetVCore( setVCore );
257
258 UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx
259 UCSCTL1 = setDcoRange; // Select suitable range
260
261 UCSCTL2 = setMultiplier + FLLD_1; // Set DCO Multiplier
262 UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV ;
263
264 // Worst-case settling time for the DCO when the DCO range bits have been
265 // changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG
266 // for optimization.
267 // 32 x 32 x / f_FLL_reference (32,768 Hz) = .03125 = t_DCO_settle
268 // t_DCO_settle / (1 / 18 MHz) = 562500 = counts_DCO_settle
269
270 // __delay_cycles(562500);
271 int i;
272 for (i=0;i<10;i++){
273 __delay_cycles(56250);
274 }
275 }
276
277 /************************************************************************
278 * @brief Initializes ACLK, MCLK, SMCLK outputs on P11.0, P11.1,
279 * and P11.2, respectively.
280 *
281 * @param none
282 *
283 * @return none
284 *************************************************************************/
halBoardOutputSystemClock(void)285 void halBoardOutputSystemClock(void)
286 {
287 P11DIR |= 0x07;
288 P11SEL |= 0x07;
289 }
290
291 /************************************************************************
292 * @brief Stops the output of ACLK, MCLK, SMCLK on P11.0, P11.1, and P11.2.
293 *
294 * @param none
295 *
296 * @return none
297 *************************************************************************/
halBoardStopOutputSystemClock(void)298 void halBoardStopOutputSystemClock(void)
299 {
300 P11OUT &= ~0x07;
301 P11DIR |= 0x07;
302 P11SEL &= ~0x07;
303 }
304
305 /************************************************************************
306 * @brief Initializes all GPIO configurations.
307 * TI example did set all ports to OUTPUT, we don't.
308 * @param none
309 *
310 * @return none
311 *************************************************************************/
halBoardInit(void)312 void halBoardInit(void)
313 {
314 #if 0
315 // ORIGINAL EP
316 //Tie unused ports
317 PAOUT = 0;
318 PADIR = 0xFFFF;
319 PASEL = 0;
320 PBOUT = 0;
321 PBDIR = 0xFFFF;
322 PBSEL = 0;
323 PCOUT = 0;
324 PCDIR = 0xFFFF;
325 PCSEL = 0;
326 PDOUT = 0;
327 PDDIR = 0xFFFF;
328 PDSEL = 0;
329 PEOUT = 0;
330 PEDIR = 0xFEFF; // P10.0 to USB RST pin,
331 // ...if enabled with J5
332 PESEL = 0;
333 P11OUT = 0;
334 P11DIR = 0xFF;
335 PJOUT = 0;
336 PJDIR = 0xFF;
337 P11SEL = 0;
338 #else
339 //Tie unused ports
340 PAOUT = 0;
341 PADIR = 0;
342 PASEL = 0;
343 PBOUT = 0;
344 PBDIR = 0;
345 PBSEL = 0;
346 PCOUT = 0;
347 PCDIR = 0;
348 PCSEL = 0;
349 PDOUT = 0;
350 PDDIR = 0;
351 PDSEL = 0;
352 PEOUT = 0;
353 PEDIR = 0;
354 PESEL = 0;
355 P11OUT = 0;
356 P11DIR = 0;
357 PJOUT = 0;
358 PJDIR = 0;
359 P11SEL = 0;
360 #endif
361
362 AUDIO_PORT_OUT = AUDIO_OUT_PWR_PIN ;
363 USB_PORT_DIR &= ~USB_PIN_RXD; // USB RX Pin, Input with
364 // ...pulled down Resistor
365 USB_PORT_OUT &= ~USB_PIN_RXD;
366 USB_PORT_REN |= USB_PIN_RXD;
367 }
368