1*1664436fSMatthias Ringwald /**
2*1664436fSMatthias Ringwald * @file hal_board.c
3*1664436fSMatthias Ringwald *
4*1664436fSMatthias Ringwald * Copyright 2008 Texas Instruments, Inc.
5*1664436fSMatthias Ringwald ******************************************************************************/
6*1664436fSMatthias Ringwald #include "hal_board.h"
7*1664436fSMatthias Ringwald
8*1664436fSMatthias Ringwald #include "msp430.h"
9*1664436fSMatthias Ringwald
10*1664436fSMatthias Ringwald #include "hal_compat.h"
11*1664436fSMatthias Ringwald // #include "hal_adc.h"
12*1664436fSMatthias Ringwald // #include "hal_usb.h"
13*1664436fSMatthias Ringwald
14*1664436fSMatthias Ringwald static void halBoardSetVCoreUp(unsigned char level);
15*1664436fSMatthias Ringwald static void halBoardSetVCoreDown(unsigned char level);
16*1664436fSMatthias Ringwald static void halBoardGetSystemClockSettings(unsigned char systemClockSpeed,
17*1664436fSMatthias Ringwald unsigned char *setDcoRange,
18*1664436fSMatthias Ringwald unsigned char *setVCore,
19*1664436fSMatthias Ringwald unsigned int *setMultiplier);
20*1664436fSMatthias Ringwald
21*1664436fSMatthias Ringwald /************************************************************************
22*1664436fSMatthias Ringwald * @brief Increments the VCore setting.
23*1664436fSMatthias Ringwald *
24*1664436fSMatthias Ringwald * @param level The target VCore setting
25*1664436fSMatthias Ringwald *
26*1664436fSMatthias Ringwald * @return none
27*1664436fSMatthias Ringwald *************************************************************************/
halBoardSetVCoreUp(unsigned char level)28*1664436fSMatthias Ringwald static void halBoardSetVCoreUp (unsigned char level)
29*1664436fSMatthias Ringwald {
30*1664436fSMatthias Ringwald // Open PMM module registers for write access
31*1664436fSMatthias Ringwald PMMCTL0_H = 0xA5;
32*1664436fSMatthias Ringwald
33*1664436fSMatthias Ringwald // Set SVS/M high side to new level
34*1664436fSMatthias Ringwald SVSMHCTL = (SVSMHCTL & ~(SVSHRVL0*3 + SVSMHRRL0)) | \
35*1664436fSMatthias Ringwald (SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level);
36*1664436fSMatthias Ringwald
37*1664436fSMatthias Ringwald // Set SVM new Level
38*1664436fSMatthias Ringwald SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
39*1664436fSMatthias Ringwald // Set SVS/M low side to new level
40*1664436fSMatthias Ringwald SVSMLCTL = (SVSMLCTL & ~(SVSMLRRL_3)) | (SVMLE + SVSMLRRL0 * level);
41*1664436fSMatthias Ringwald
42*1664436fSMatthias Ringwald while ((PMMIFG & SVSMLDLYIFG) == 0); // Wait till SVM is settled (Delay)
43*1664436fSMatthias Ringwald PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x
44*1664436fSMatthias Ringwald PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags
45*1664436fSMatthias Ringwald
46*1664436fSMatthias Ringwald if ((PMMIFG & SVMLIFG))
47*1664436fSMatthias Ringwald while ((PMMIFG & SVMLVLRIFG) == 0); // Wait till level is reached
48*1664436fSMatthias Ringwald
49*1664436fSMatthias Ringwald // Set SVS/M Low side to new level
50*1664436fSMatthias Ringwald SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0*3 + SVSMLRRL_3)) | \
51*1664436fSMatthias Ringwald (SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level);
52*1664436fSMatthias Ringwald
53*1664436fSMatthias Ringwald // Lock PMM module registers from write access
54*1664436fSMatthias Ringwald PMMCTL0_H = 0x00;
55*1664436fSMatthias Ringwald }
56*1664436fSMatthias Ringwald
57*1664436fSMatthias Ringwald /************************************************************************
58*1664436fSMatthias Ringwald * @brief Decrements the VCore setting.
59*1664436fSMatthias Ringwald *
60*1664436fSMatthias Ringwald * @param level The target VCore.
61*1664436fSMatthias Ringwald *
62*1664436fSMatthias Ringwald * @return none
63*1664436fSMatthias Ringwald *************************************************************************/
halBoardSetVCoreDown(unsigned char level)64*1664436fSMatthias Ringwald static void halBoardSetVCoreDown(unsigned char level)
65*1664436fSMatthias Ringwald {
66*1664436fSMatthias Ringwald // Open PMM module registers for write access
67*1664436fSMatthias Ringwald PMMCTL0_H = 0xA5;
68*1664436fSMatthias Ringwald
69*1664436fSMatthias Ringwald // Set SVS/M low side to new level
70*1664436fSMatthias Ringwald SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0*3 + SVSMLRRL_3)) | \
71*1664436fSMatthias Ringwald (SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level);
72*1664436fSMatthias Ringwald
73*1664436fSMatthias Ringwald while ((PMMIFG & SVSMLDLYIFG) == 0); // Wait till SVM is settled (Delay)
74*1664436fSMatthias Ringwald PMMCTL0_L = (level * PMMCOREV0); // Set VCore to new level
75*1664436fSMatthias Ringwald // Lock PMM module registers for write access
76*1664436fSMatthias Ringwald
77*1664436fSMatthias Ringwald PMMCTL0_H = 0x00;
78*1664436fSMatthias Ringwald }
79*1664436fSMatthias Ringwald
80*1664436fSMatthias Ringwald /************************************************************************
81*1664436fSMatthias Ringwald * @brief Get function for the DCORSEL, VCORE, and DCO multiplier settings
82*1664436fSMatthias Ringwald * that map to a given clock speed.
83*1664436fSMatthias Ringwald *
84*1664436fSMatthias Ringwald * @param systemClockSpeed Target DCO frequency - SYSCLK_xxMHZ.
85*1664436fSMatthias Ringwald *
86*1664436fSMatthias Ringwald * @param setDcoRange Pointer to the DCO range select bits.
87*1664436fSMatthias Ringwald *
88*1664436fSMatthias Ringwald * @param setVCore Pointer to the VCore level bits.
89*1664436fSMatthias Ringwald *
90*1664436fSMatthias Ringwald * @param setMultiplier Pointer to the DCO multiplier bits.
91*1664436fSMatthias Ringwald *
92*1664436fSMatthias Ringwald * @return none
93*1664436fSMatthias Ringwald ************************************************************************/
halBoardGetSystemClockSettings(unsigned char systemClockSpeed,unsigned char * setDcoRange,unsigned char * setVCore,unsigned int * setMultiplier)94*1664436fSMatthias Ringwald static void halBoardGetSystemClockSettings(unsigned char systemClockSpeed,
95*1664436fSMatthias Ringwald unsigned char *setDcoRange,
96*1664436fSMatthias Ringwald unsigned char *setVCore,
97*1664436fSMatthias Ringwald unsigned int *setMultiplier)
98*1664436fSMatthias Ringwald {
99*1664436fSMatthias Ringwald switch (systemClockSpeed)
100*1664436fSMatthias Ringwald {
101*1664436fSMatthias Ringwald case SYSCLK_1MHZ:
102*1664436fSMatthias Ringwald *setDcoRange = DCORSEL_1MHZ;
103*1664436fSMatthias Ringwald *setVCore = VCORE_1MHZ;
104*1664436fSMatthias Ringwald *setMultiplier = DCO_MULT_1MHZ;
105*1664436fSMatthias Ringwald break;
106*1664436fSMatthias Ringwald case SYSCLK_4MHZ:
107*1664436fSMatthias Ringwald *setDcoRange = DCORSEL_4MHZ;
108*1664436fSMatthias Ringwald *setVCore = VCORE_4MHZ;
109*1664436fSMatthias Ringwald *setMultiplier = DCO_MULT_4MHZ;
110*1664436fSMatthias Ringwald break;
111*1664436fSMatthias Ringwald case SYSCLK_8MHZ:
112*1664436fSMatthias Ringwald *setDcoRange = DCORSEL_8MHZ;
113*1664436fSMatthias Ringwald *setVCore = VCORE_8MHZ;
114*1664436fSMatthias Ringwald *setMultiplier = DCO_MULT_8MHZ;
115*1664436fSMatthias Ringwald break;
116*1664436fSMatthias Ringwald case SYSCLK_12MHZ:
117*1664436fSMatthias Ringwald *setDcoRange = DCORSEL_12MHZ;
118*1664436fSMatthias Ringwald *setVCore = VCORE_12MHZ;
119*1664436fSMatthias Ringwald *setMultiplier = DCO_MULT_12MHZ;
120*1664436fSMatthias Ringwald break;
121*1664436fSMatthias Ringwald case SYSCLK_16MHZ:
122*1664436fSMatthias Ringwald *setDcoRange = DCORSEL_16MHZ;
123*1664436fSMatthias Ringwald *setVCore = VCORE_16MHZ;
124*1664436fSMatthias Ringwald *setMultiplier = DCO_MULT_16MHZ;
125*1664436fSMatthias Ringwald break;
126*1664436fSMatthias Ringwald }
127*1664436fSMatthias Ringwald }
128*1664436fSMatthias Ringwald
129*1664436fSMatthias Ringwald /************************************************************************
130*1664436fSMatthias Ringwald * @brief Set function for the PMM core voltage (PMMCOREV) setting
131*1664436fSMatthias Ringwald *
132*1664436fSMatthias Ringwald * @param level Target VCore setting
133*1664436fSMatthias Ringwald *
134*1664436fSMatthias Ringwald * @return none
135*1664436fSMatthias Ringwald *************************************************************************/
halBoardSetVCore(unsigned char level)136*1664436fSMatthias Ringwald void halBoardSetVCore(unsigned char level)
137*1664436fSMatthias Ringwald {
138*1664436fSMatthias Ringwald unsigned int currentVCore;
139*1664436fSMatthias Ringwald
140*1664436fSMatthias Ringwald currentVCore = PMMCTL0 & PMMCOREV_3; // Get actual VCore
141*1664436fSMatthias Ringwald // Change VCore step by step
142*1664436fSMatthias Ringwald while (level != currentVCore)
143*1664436fSMatthias Ringwald {
144*1664436fSMatthias Ringwald if (level > currentVCore)
145*1664436fSMatthias Ringwald halBoardSetVCoreUp(++currentVCore);
146*1664436fSMatthias Ringwald else
147*1664436fSMatthias Ringwald halBoardSetVCoreDown(--currentVCore);
148*1664436fSMatthias Ringwald }
149*1664436fSMatthias Ringwald }
150*1664436fSMatthias Ringwald
151*1664436fSMatthias Ringwald /************************************************************************
152*1664436fSMatthias Ringwald * @brief Initialization routine for XT1.
153*1664436fSMatthias Ringwald *
154*1664436fSMatthias Ringwald * Sets the necessary internal capacitor values and loops until all
155*1664436fSMatthias Ringwald * ocillator fault flags remain cleared.
156*1664436fSMatthias Ringwald *
157*1664436fSMatthias Ringwald * @param none
158*1664436fSMatthias Ringwald *
159*1664436fSMatthias Ringwald * @return none
160*1664436fSMatthias Ringwald *************************************************************************/
halBoardStartXT1(void)161*1664436fSMatthias Ringwald void halBoardStartXT1(void)
162*1664436fSMatthias Ringwald {
163*1664436fSMatthias Ringwald /* LFXT can take up to 1000ms to start.
164*1664436fSMatthias Ringwald * Go to the loop below 4 times for a total of 2 sec timout.
165*1664436fSMatthias Ringwald * If a timeout happens due to no XTAL present or a faulty XTAL
166*1664436fSMatthias Ringwald * the clock system will fall back to REFOCLK (~32kHz) */
167*1664436fSMatthias Ringwald P5SEL |= BIT4 + BIT5;
168*1664436fSMatthias Ringwald /* Set XTAL2 pins to output to reduce power consumption */
169*1664436fSMatthias Ringwald P5DIR |= BIT2 + BIT3;
170*1664436fSMatthias Ringwald /* Turn XT1 ON */
171*1664436fSMatthias Ringwald UCSCTL6 &= ~(XT1OFF);
172*1664436fSMatthias Ringwald /* Set XTAL CAPS to 12 pF */
173*1664436fSMatthias Ringwald UCSCTL6 |= XCAP_3;
174*1664436fSMatthias Ringwald
175*1664436fSMatthias Ringwald do {
176*1664436fSMatthias Ringwald /* Clear Oscillator fault flags */
177*1664436fSMatthias Ringwald UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
178*1664436fSMatthias Ringwald /* Clear the Oscillator fault interrupt flag */
179*1664436fSMatthias Ringwald SFRIFG1 &= ~OFIFG;
180*1664436fSMatthias Ringwald /* Test the fault flag */
181*1664436fSMatthias Ringwald __delay_cycles(56250);
182*1664436fSMatthias Ringwald } while (SFRIFG1 & OFIFG);
183*1664436fSMatthias Ringwald /* Reduse drive strength to reduce power consumption */
184*1664436fSMatthias Ringwald UCSCTL6 &= ~(XT1DRIVE_3);
185*1664436fSMatthias Ringwald }
186*1664436fSMatthias Ringwald
187*1664436fSMatthias Ringwald /************************************************************************
188*1664436fSMatthias Ringwald * @brief Set function for MCLK frequency.
189*1664436fSMatthias Ringwald *
190*1664436fSMatthias Ringwald * @param systemClockSpeed Intended frequency of operation - SYSCLK_xxMHZ.
191*1664436fSMatthias Ringwald *
192*1664436fSMatthias Ringwald * @return none
193*1664436fSMatthias Ringwald *************************************************************************/
halBoardSetSystemClock(unsigned char systemClockSpeed)194*1664436fSMatthias Ringwald void halBoardSetSystemClock(unsigned char systemClockSpeed)
195*1664436fSMatthias Ringwald {
196*1664436fSMatthias Ringwald unsigned char setDcoRange = 0;
197*1664436fSMatthias Ringwald unsigned char setVCore = 0;
198*1664436fSMatthias Ringwald unsigned int setMultiplier = 0;
199*1664436fSMatthias Ringwald
200*1664436fSMatthias Ringwald halBoardGetSystemClockSettings( systemClockSpeed, &setDcoRange, \
201*1664436fSMatthias Ringwald &setVCore, &setMultiplier);
202*1664436fSMatthias Ringwald
203*1664436fSMatthias Ringwald if (setVCore > (PMMCTL0 & PMMCOREV_3)) // Only change VCore if necessary
204*1664436fSMatthias Ringwald halBoardSetVCore( setVCore );
205*1664436fSMatthias Ringwald
206*1664436fSMatthias Ringwald UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx
207*1664436fSMatthias Ringwald UCSCTL1 = setDcoRange; // Select suitable range
208*1664436fSMatthias Ringwald
209*1664436fSMatthias Ringwald UCSCTL2 = setMultiplier + FLLD_1; // Set DCO Multiplier
210*1664436fSMatthias Ringwald UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV ;
211*1664436fSMatthias Ringwald
212*1664436fSMatthias Ringwald // Worst-case settling time for the DCO when the DCO range bits have been
213*1664436fSMatthias Ringwald // changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG
214*1664436fSMatthias Ringwald // for optimization.
215*1664436fSMatthias Ringwald // 32 x 32 x / f_FLL_reference (32,768 Hz) = .03125 = t_DCO_settle
216*1664436fSMatthias Ringwald // t_DCO_settle / (1 / 18 MHz) = 562500 = counts_DCO_settle
217*1664436fSMatthias Ringwald
218*1664436fSMatthias Ringwald // __delay_cycles(562500);
219*1664436fSMatthias Ringwald int i;
220*1664436fSMatthias Ringwald for (i=0;i<10;i++){
221*1664436fSMatthias Ringwald __delay_cycles(56250);
222*1664436fSMatthias Ringwald }
223*1664436fSMatthias Ringwald }
224*1664436fSMatthias Ringwald
225*1664436fSMatthias Ringwald /************************************************************************
226*1664436fSMatthias Ringwald * @brief Initializes all GPIO configurations.
227*1664436fSMatthias Ringwald * TI example did set all ports to OUTPUT, we don't.
228*1664436fSMatthias Ringwald * @param none
229*1664436fSMatthias Ringwald *
230*1664436fSMatthias Ringwald * @return none
231*1664436fSMatthias Ringwald *************************************************************************/
halBoardInit(void)232*1664436fSMatthias Ringwald void halBoardInit(void)
233*1664436fSMatthias Ringwald {
234*1664436fSMatthias Ringwald //Tie unused ports
235*1664436fSMatthias Ringwald PAOUT = 0;
236*1664436fSMatthias Ringwald PADIR = 0;
237*1664436fSMatthias Ringwald PASEL = 0;
238*1664436fSMatthias Ringwald PBOUT = 0;
239*1664436fSMatthias Ringwald PBDIR = 0;
240*1664436fSMatthias Ringwald PBSEL = 0;
241*1664436fSMatthias Ringwald PCOUT = 0;
242*1664436fSMatthias Ringwald PCDIR = 0;
243*1664436fSMatthias Ringwald PCSEL = 0;
244*1664436fSMatthias Ringwald PDOUT = 0;
245*1664436fSMatthias Ringwald PDDIR = 0;
246*1664436fSMatthias Ringwald PDSEL = 0;
247*1664436fSMatthias Ringwald PJOUT = 0;
248*1664436fSMatthias Ringwald PJDIR = 0;
249*1664436fSMatthias Ringwald
250*1664436fSMatthias Ringwald // AUDIO_PORT_OUT = AUDIO_OUT_PWR_PIN ;
251*1664436fSMatthias Ringwald // USB_PORT_DIR &= ~USB_PIN_RXD; // USB RX Pin, Input with
252*1664436fSMatthias Ringwald // // ...pulled down Resistor
253*1664436fSMatthias Ringwald // USB_PORT_OUT &= ~USB_PIN_RXD;
254*1664436fSMatthias Ringwald // USB_PORT_REN |= USB_PIN_RXD;
255*1664436fSMatthias Ringwald }
256