1 /** 2 * @file hal_board.c 3 * 4 * Copyright 2008 Texas Instruments, Inc. 5 ******************************************************************************/ 6 #include "hal_board.h" 7 8 #include "msp430.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 *************************************************************************/ 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 *************************************************************************/ 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 ************************************************************************/ 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 } 128 129 /************************************************************************ 130 * @brief Set function for the PMM core voltage (PMMCOREV) setting 131 * 132 * @param level Target VCore setting 133 * 134 * @return none 135 *************************************************************************/ 136 void halBoardSetVCore(unsigned char level) 137 { 138 unsigned int currentVCore; 139 140 currentVCore = PMMCTL0 & PMMCOREV_3; // Get actual VCore 141 // Change VCore step by step 142 while (level != currentVCore) 143 { 144 if (level > currentVCore) 145 halBoardSetVCoreUp(++currentVCore); 146 else 147 halBoardSetVCoreDown(--currentVCore); 148 } 149 } 150 151 /************************************************************************ 152 * @brief Initialization routine for XT1. 153 * 154 * Sets the necessary internal capacitor values and loops until all 155 * ocillator fault flags remain cleared. 156 * 157 * @param none 158 * 159 * @return none 160 *************************************************************************/ 161 void halBoardStartXT1(void) 162 { 163 /* LFXT can take up to 1000ms to start. 164 * Go to the loop below 4 times for a total of 2 sec timout. 165 * If a timeout happens due to no XTAL present or a faulty XTAL 166 * the clock system will fall back to REFOCLK (~32kHz) */ 167 P5SEL |= BIT4 + BIT5; 168 /* Set XTAL2 pins to output to reduce power consumption */ 169 P5DIR |= BIT2 + BIT3; 170 /* Turn XT1 ON */ 171 UCSCTL6 &= ~(XT1OFF); 172 /* Set XTAL CAPS to 12 pF */ 173 UCSCTL6 |= XCAP_3; 174 175 do { 176 /* Clear Oscillator fault flags */ 177 UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); 178 /* Clear the Oscillator fault interrupt flag */ 179 SFRIFG1 &= ~OFIFG; 180 /* Test the fault flag */ 181 __delay_cycles(56250); 182 } while (SFRIFG1 & OFIFG); 183 /* Reduse drive strength to reduce power consumption */ 184 UCSCTL6 &= ~(XT1DRIVE_3); 185 } 186 187 /************************************************************************ 188 * @brief Set function for MCLK frequency. 189 * 190 * @param systemClockSpeed Intended frequency of operation - SYSCLK_xxMHZ. 191 * 192 * @return none 193 *************************************************************************/ 194 void halBoardSetSystemClock(unsigned char systemClockSpeed) 195 { 196 unsigned char setDcoRange = 0; 197 unsigned char setVCore = 0; 198 unsigned int setMultiplier = 0; 199 200 halBoardGetSystemClockSettings( systemClockSpeed, &setDcoRange, \ 201 &setVCore, &setMultiplier); 202 203 if (setVCore > (PMMCTL0 & PMMCOREV_3)) // Only change VCore if necessary 204 halBoardSetVCore( setVCore ); 205 206 UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx 207 UCSCTL1 = setDcoRange; // Select suitable range 208 209 UCSCTL2 = setMultiplier + FLLD_1; // Set DCO Multiplier 210 UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV ; 211 212 // Worst-case settling time for the DCO when the DCO range bits have been 213 // changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG 214 // for optimization. 215 // 32 x 32 x / f_FLL_reference (32,768 Hz) = .03125 = t_DCO_settle 216 // t_DCO_settle / (1 / 18 MHz) = 562500 = counts_DCO_settle 217 218 // __delay_cycles(562500); 219 int i; 220 for (i=0;i<10;i++){ 221 __delay_cycles(56250); 222 } 223 } 224 225 /************************************************************************ 226 * @brief Initializes all GPIO configurations. 227 * TI example did set all ports to OUTPUT, we don't. 228 * @param none 229 * 230 * @return none 231 *************************************************************************/ 232 void halBoardInit(void) 233 { 234 //Tie unused ports 235 PAOUT = 0; 236 PADIR = 0; 237 PASEL = 0; 238 PBOUT = 0; 239 PBDIR = 0; 240 PBSEL = 0; 241 PCOUT = 0; 242 PCDIR = 0; 243 PCSEL = 0; 244 PDOUT = 0; 245 PDDIR = 0; 246 PDSEL = 0; 247 PJOUT = 0; 248 PJDIR = 0; 249 250 // AUDIO_PORT_OUT = AUDIO_OUT_PWR_PIN ; 251 // USB_PORT_DIR &= ~USB_PIN_RXD; // USB RX Pin, Input with 252 // // ...pulled down Resistor 253 // USB_PORT_OUT &= ~USB_PIN_RXD; 254 // USB_PORT_REN |= USB_PIN_RXD; 255 } 256