/**********************************************************************//** * @brief Set function for MCLK frequency. * * * @return none *************************************************************************/ void hal430SetSystemClock(unsigned long req_clock_rate, unsigned long ref_clock_rate) { /* Convert a Hz value to a KHz value, as required * by the Init_FLL_Settle() function. */ unsigned long ulCPU_Clock_KHz = req_clock_rate / 1000UL; //Make sure we aren't overclocking if(ulCPU_Clock_KHz > 25000L) { ulCPU_Clock_KHz = 25000L; } //Set VCore to a level sufficient for the requested clock speed. if(ulCPU_Clock_KHz <= 8000L) { SetVCore(PMMCOREV_0); } else if(ulCPU_Clock_KHz <= 12000L) { SetVCore(PMMCOREV_1); } else if(ulCPU_Clock_KHz <= 20000L) { SetVCore(PMMCOREV_2); } else { SetVCore(PMMCOREV_3); } //Set the DCO Init_FLL_Settle( ( unsigned short )ulCPU_Clock_KHz, req_clock_rate / ref_clock_rate ); }
/// /// set dco features /// unsigned long int setDCO(unsigned long int mhz){ unsigned long int risultato; /// set almost high value in V_CORE /// set highest value of V_CORE if (mhz < 5000000) risultato = SetVCore(PMMCOREV_0); else if (mhz < 10000000) risultato = SetVCore(PMMCOREV_2); else risultato = SetVCore(PMMCOREV_3); risultato = mhz / 32768; UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx //UCSCTL1 = DCORSEL_2; // Select DCO range 0.3MHz - 7MHz operation /// set DCO range: 2.5 - 54 MHz UCSCTL1 = DCORSEL_5; //UCSCTL2 = FLLD_0 + 127; // Set DCO Multiplier for 4.1943MHz // (127 + 1) * FLLRef = Fdco // (127 + 1) * 32768 = 4.1943MHz // Set FLL Div = fDCOCLK/1 //UCSCTL2 = FLLD_0 + 511; // Set DCO Multiplier for 16.777216MHz // (511 + 1) * FLLRef = Fdco // (511 + 1) * 32768 = 16.777216MHz // Set FLL Div = fDCOCLK/1 UCSCTL2 = FLLD_0 + risultato - 1; // Set DCO Multiplier for 29.491200MHz // (899 + 1) * FLLRef = Fdco // (899 + 1) * 32768 = 29.491200MHz // Set FLL Div = fDCOCLK/1 __bic_SR_register(SCG0); // Enable the FLL control loop __delay_cycles(1375000); // Loop until XT1,XT2 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); /// fine dell'impostazione del clock. return risultato; }
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT SetVCore(PMMCOREV_2); // Set VCore to 1.8MHz for 20MHz P11DIR = BIT2 + BIT1 + BIT0; // P11.2,1,0 to output direction P11SEL = BIT2 + BIT1 + BIT0; // P11.2 to output SMCLK, P11.1 // to output MCLK and P11.0 to // output ACLK P7SEL |= 0x03; // Port select XT1 UCSCTL3 |= SELREF_2; // FLL Ref = REFO UCSCTL6 &= ~XT1OFF; // Set XT1 On UCSCTL6 |= XT1DRIVE_3 + XTS; // Max drive strength, adjust // according to crystal frequency. // LFXT1 HF mode // Loop until XT1,XT2 & DCO stabilizes do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL4 = SELA_0 + SELS_4 + SELM_0; // Select ACLK = LFXT1 // SMCLK = DCO // MCLK = LFXT1 while(1); // Loop in place }
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer SetVCore(PMMCOREV_2); // Set VCore to 1.8MHz for 20MHz P11DIR = BIT1+BIT2; // P11.1-2 to output direction P11SEL |= BIT1+BIT2; // P11.1-2 to output SMCLK,MCLK P5SEL |= 0x0C; // Port select XT2 UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL3 |= SELREF_2; // FLLref = REFO // Since LFXT1 is not used, // sourcing FLL with LFXT1 can cause // XT1OFFG flag to set UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO // Loop until XT1,XT2 & DCO stabilizes do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to // expected frequency UCSCTL4 |= SELS_5 + SELM_5; // SMCLK=MCLK=XT2 while(1); // Loop in place }
void main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; // Increase PMMCOREV level to 2 in order to avoid low voltage error // when the RF core is enabled SetVCore(2); InitRadio(); InitButtonLeds(); Strobe(RF_SIDLE); Strobe(RF_SRX); // P2.7 for GD02 - synchronous clock from Radio // P2.6 for GDO0 - synchronous data from Radio P2DIR |= BIT6+BIT7; P2SEL |= BIT6+BIT7; PMAPPWD = 0x02D52; // Get write-access to port mapping regs P2MAP6 = PM_RFGDO0; // Map GDO0 to P2.6 P2MAP7 = PM_RFGDO2; // Map GDO2 to P2.7 PMAPPWD = 0x00; // Lock Port mapping while(1); }
unsigned long int setDCO_XTAL(unsigned long int mhz){ unsigned long int risultato; /// set almost high value in V_CORE ///risultato = SetVCore(PMMCOREV_2); /// set highest value of V_CORE if (mhz < 2000000) risultato = SetVCore(PMMCOREV_0); else if (mhz < 10000000) risultato = SetVCore(PMMCOREV_2); else risultato = SetVCore(PMMCOREV_3); risultato = mhz / 32768; /// uso del clock da 32768 quarzato P5SEL |= BIT4+BIT5; // Select XT1 /// abilitazione dell'oscillatore quarzato UCSCTL6 &= ~(XT1OFF); // XT1 On //UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL3 = 0; // Set DCO FLL reference = XTAL1 UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx //UCSCTL1 = DCORSEL_2; // Select DCO range 0.3MHz - 7MHz operation /// set DCO range: 2.5 - 54 MHz UCSCTL1 = DCORSEL_5; // Set FLL Div = fDCOCLK/1 UCSCTL2 = FLLD_0 + risultato - 1; // Set DCO Multiplier for 29.491200MHz // (899 + 1) * FLLRef = Fdco // (899 + 1) * 32768 = 29.491200MHz // Set FLL Div = fDCOCLK/1 __bic_SR_register(SCG0); // Enable the FLL control loop __delay_cycles(1375000); // Loop until XT1,XT2 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive strength /// fine dell'impostazione del clock. return risultato; }
/** * setVcoreMCLK * * Config VCORE and MCLK registers * * @param vCore VCORE level * @param dcorsel CPU DCORSEL value * @param flln MCLK multiplier bits */ void __inline__ CC430CORE::setVcoreMCLK(uint8_t vCore, uint16_t dcorsel, uint16_t flln) { // Configure PMM SetVCore(vCore); // Set MCLK setMCLK(dcorsel, flln); }
static void init8(void) { /* Stop watchdog timer */ WDTCTL = WDTPW + WDTHOLD; /* Configure PMM */ SetVCore(3); /* Set global high power request enable */ { PMMCTL0_H = 0xA5; PMMCTL0_L |= PMMHPMRE; PMMCTL0_H = 0x00; } /* Enable 32kHz ACLK */ initialize_aclk(); /* Configure CPU clock for 12MHz */ initialize_cpu_12mhz(); /* Configure buttons for input */ initialize_buttons(); /* Initialize LCD */ initialize_lcd(); /* Write 'boot' to the screen without using display functions */ LCDM2 = 199; /* 'b' */ LCDM3 = 198; /* 'o' */ LCDM4 = 198; /* 'o' */ LCDM6 = 135; /* 't' */ /* configure watchdog interrupt timer, used for polling buttons */ { /* ACLK timer source, 250ms timer mode, resume watchdog */ WDTCTL = WDT_ADLY_250; /* Enable watchdog timer interrupts */ SFRIE1 |= WDTIE; } /* Enable global interrupts */ __enable_interrupt(); /* loop if no button is pressed, enter RFBSL if backlight is pressed */ do { _BIS_SR(LPM3_bits | GIE); if ((P2IN & ALL_BUTTONS) == BTN_BL_PIN) jump_to_rfbsl(); } while ((P2IN & ALL_BUTTONS) == 0); /* Disable them again, they will be re-enabled later on in main() */ __disable_interrupt(); }
void SetupClockAndPowerManagementModule(void) { // see Frequency vs Supply Voltage in MSP4305438A data sheet SetVCore(PMMCOREV_2); // setup pins for XT1 P7SEL |= BIT0 + BIT1; // Startup LFXT1 32 kHz crystal while (LFXT_Start_Timeout(XT1DRIVE_0, 50000) == UCS_STATUS_ERROR); // select the sources for the FLL reference and ACLK SELECT_ACLK(SELA__XT1CLK); SELECT_FLLREF(SELREF__XT1CLK); // 512 * 32768 = 16777216 / 1024 Init_FLL_Settle(configCPU_CLOCK_HZ/configTICK_RATE_HZ, ACLK_MULTIPLIER); // Disable FLL loop control __bis_SR_register(SCG0); // setup for quick wake up from interrupt and // minimal power consumption in sleep mode DISABLE_SVSL(); // SVS Low side is turned off DISABLE_SVSL_RESET(); DISABLE_SVML(); // Monitor low side is turned off DISABLE_SVML_INTERRUPT(); DISABLE_SVMH(); // Monitor high side is turned off DISABLE_SVMH_INTERRUPT(); ENABLE_SVSH(); // SVS High side is turned on ENABLE_SVSH_RESET(); // Enable POR on SVS Event SVSH_ENABLED_IN_LPM_FULL_PERF(); // SVS high side Full perf mode, // stays on in LPM3,enhanced protect // Wait until high side, low side settled while ((PMMIFG & SVSMLDLYIFG) == 0 && (PMMIFG & SVSMHDLYIFG) == 0); CLEAR_PMM_IFGS(); #if CHECK_FOR_PMM15 /* make sure error pmm15 does not exist */ while (PMM15Check()); #endif if (Errata()) { /* Errata PMM17 - automatic prolongation mechanism * SVSLOW is disabled */ *(unsigned int*)(0x0110) = 0x9602; *(unsigned int*)(0x0112) |= 0x0800; } }
VOID Init_StartUp(VOID) { __disable_interrupt(); // Disable global interrupts Init_Ports(); // Init ports (do first ports because clocks do change ports) SetVCore(3); // USB core requires the VCore set to 1.8 volt, independ of CPU clock frequency Init_Clock(); __enable_interrupt(); // enable global interrupts }
void main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; // Increase PMMCOREV level to 2 for proper radio operation SetVCore(2); ResetRadioCore(); InitButtonLeds(); InitTimer(); // Clean out the RX Buffer rxPosition = PACKET_LEN+2; while(rxPosition--) { RxBuffer[rxPosition] = 0; } InitRadio(); ReceiveOn(); //Check RSSI here while (1) { P1IE |= BIT7; // Enable button interrupt __bis_SR_register( LPM3_bits + GIE ); __no_operation(); if (buttonPressed) // Process a button press->transmit { ReceiveOff(); // Button means TX, stop RX receiving = 0; TransmitPacket(); buttonPressed = 0; // Re-enable button press } if(receiving) { ReceivePacket(); __no_operation(); // Check CRC if(RxBuffer[CRC_LQI_IDX] & CRC_OK) //Got it! P1OUT ^= BIT0; // Toggle LED1 in celebration } if(!transmitting) { ReceiveOn(); } } }
void init_RF(void){ // Increase PMMCOREV level to 2 for proper radio operation SetVCore(2); ResetRadioCore(); InitRadio(); ReceiveOn(); receiving = 1; transmitting = 0; ADDRESS = 0x03; }
//***************************************************************************** // //! initClk //! //! @param None //! //! @return none //! //! @brief Init the device with 16 MHz DCOCLCK. // //***************************************************************************** void initClk(void) { // Set Vcore to accomodate for max. allowed system speed SetVCore(3); // Use 32.768kHz XTAL as reference LFXT_Start(XT1DRIVE_0); // Set system clock to max (25MHz) Init_FLL_Settle(25000, 762); SFRIFG1 = 0; SFRIE1 |= OFIE; }
void Init_RF(void){ // Increase PMMCOREV level to 2 in order to avoid low voltage error // when the RF core is enabled SetVCore(2); ResetRadioCore(); WriteBurstReg(IOCFG2, (unsigned char*)RF1A_REGISTER_CONFIG, CONF_REG_SIZE); WritePATable(); InitButtonLed(); ReceiveOn(); //Wait for RX status to be reached while((Strobe(RF_SNOP) & 0x70) != 0x10); }
void SysInit(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer Board_init(); // Basic GPIO initialization SetVCore(3); // Set Vcore to accomodate for max. allowed system speed LFXT_Start(XT1DRIVE_0); // Use 32.768kHz XTAL as reference, ACLK: SELA = 000, DIVA = 000 Init_FLL_Settle(25000, 762); // Set system clock to max (25MHz) LcdInit(); LcdClear(); //display_rect(); AD9954Init(); P4SEL = 0x00; P4DIR = 0x00; P4REN = 0xff; }
void init_clock() { WDTCTL = WDTPW+WDTHOLD; SetVCore(PMMCOREV_3); __bis_SR_register(SCG0); // Disable the FLL control loop //UCSCTL0 = DCO0 * 20; // 24mHz - 204 uart divider //UCSCTL0 = DCO0 * 19; // 22.2 mHz - 193 uart divider //UCSCTL0 = DCO0 * 18; // 20.6 mHz - 179 uart divider UCSCTL0 = DCO0 * 16; // 18mHz - 156 uart divider //UCSCTL0 = DCO0 * 8; // 11mHz - 96 uart divider UCSCTL1 = DCORSEL_7; // Set it for the fastest __delay_cycles(100000); // So it can settle in, maybe unneeded }
int main(void) { volatile unsigned int i; WDTCTL = WDTPW+WDTHOLD; // Stop WDT SetVCore(PMMCOREV_1); // Set VCore = 1.6V for 12MHz clock P1DIR |= BIT1; // P1.1 output P1DIR |= BIT0; // ACLK set out to pins P1SEL |= BIT0; P3DIR |= BIT4; // SMCLK set out to pins P3SEL |= BIT4; UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_5; // Select DCO range 24MHz operation UCSCTL2 = FLLD_1 + 374; // Set DCO Multiplier for 12MHz // (N + 1) * FLLRef = Fdco // (374 + 1) * 32768 = 12MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 6xx // UG for optimization. // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle __delay_cycles(375000); // Loop until XT1,XT2 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag while(1) { P1OUT ^= BIT1; // Toggle P1.1 __delay_cycles(600000); // Delay } }
void init_clock() { //TODO: Implement correct usage of watchdog WDTCTL = WDTPW+WDTHOLD; // Raise the internal Core voltage to enable higher clock rates SetVCore(PMMCOREV_3); __bis_SR_register(SCG0); // Disable the FLL control loop //UCSCTL0 = DCO0 * 20; // 24mHz - 204 uart divider //UCSCTL0 = DCO0 * 19; // 22.2 mHz - 193 uart divider //UCSCTL0 = DCO0 * 18; // 20.6 mHz - 179 uart divider UCSCTL0 = DCO0 * 16; // 18mHz - 156 uart divider //UCSCTL0 = DCO0 * 8; // 11mHz - 96 uart divider UCSCTL1 = DCORSEL_7; // Set it for the fastest __delay_cycles(100000); // So it can settle in, maybe unneeded }
/*-----------------------------------------------------------*/ static void prvSetupHardware( void ) { taskDISABLE_INTERRUPTS(); /* Disable the watchdog. */ WDTCTL = WDTPW + WDTHOLD; //halBoardInit(); Board_init(); // Set Vcore to accomodate for max. allowed system speed SetVCore(3); // Use 32.768kHz XTAL as reference LFXT_Start(XT1DRIVE_0); // Set system clock to max (25MHz) Init_FLL_Settle(25000, 762); SFRIFG1 = 0; SFRIE1 |= OFIE; //LFXT_Start( XT1DRIVE_0 ); //hal430SetSystemClock( configCPU_CLOCK_HZ, configLFXT_CLOCK_HZ ); //halButtonsInit( BUTTON_ALL ); Buttons_init(BUTTON_ALL); //halButtonsInterruptEnable( BUTTON_SELECT ); Buttons_interruptEnable(BUTTON_S2); /* Initialise the LCD, but note that the backlight is not used as the library function uses timer A0 to modulate the backlight, and this file defines vApplicationSetupTimerInterrupt() to also use timer A0 to generate the tick interrupt. If the backlight is required, then change either the halLCD library or vApplicationSetupTimerInterrupt() to use a different timer. Timer A1 is used for the run time stats time base6. */ //halLcdInit(); //halLcdSetContrast( 100 ); //halLcdClearScreen(); //halLcdPrintLine( " www.FreeRTOS.org", 0, OVERWRITE_TEXT ); }
VOID Init_StartUp(VOID) { unsigned short bGIE; bGIE = (__get_SR_register() &GIE); //save interrupt status __disable_interrupt(); // Disable global interrupts # ifdef __MSP430F6638 // only for F663x devices! while (BAKCTL & LOCKBAK) // check if bit for backup subsystem is cleared { BAKCTL &= ~LOCKBAK; // clear lock backup bit for backup subsystem } # endif Init_Ports(); // Init ports (do first ports because clocks do change ports) SetVCore(3); // USB core requires the VCore set to 1.8 volt, independ of CPU clock frequency Init_Clock(); __bis_SR_register(bGIE); //restore interrupt status }
void usb_printf_init(void) { SetVCore(3); init_clock(); //Init USB USB_init(); //Enable various USB event handling routines USB_setEnabledEvents(kUSB_VbusOnEvent + kUSB_VbusOffEvent + kUSB_receiveCompletedEvent + kUSB_dataReceivedEvent + kUSB_UsbSuspendEvent + kUSB_UsbResumeEvent + kUSB_UsbResetEvent); // See if we're already attached physically to USB, and if so, // connect to it. Normally applications don't invoke the event // handlers, but this is an exception. if(USB_connectionInfo() & kUSB_vbusPresent) { usb_printf_state = USB_ENABLED; USB_handleVbusOnEvent(); } }
/** * init * * Initialize CC430 core * VCORE = 1 and SCLK = 8 MHz when no argument is passed * * @param vCore VCORE level * @param dcorsel CPU DCORSEL value * @param flln MCLK multiplier bits */ void CC430CORE::init(uint8_t vCore, uint16_t dcorsel, uint16_t flln) { // Configure PMM SetVCore(vCore); // Set the High-Power Mode Request Enable bit so LPM3 can be entered // with active radio enabled PMMCTL0_H = 0xA5; PMMCTL0_L |= PMMHPMRE_L; PMMCTL0_H = 0x00; /* * Select internal RC oscillator as FLL reference */ UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO /* * Configure CPU clock */ setMCLK(dcorsel, flln); /* * Select Interrupt edge for PA_PD and SYNC signal: * Interrupt Edge select register: 1 == Interrupt on High to Low transition. */ RF1AIES = BIT0 | BIT9; // POWER: Turn ADC and reference voltage off to conserve power ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 &= ~ADC12ON; ADC12CTL0 &= ~ADC12REFON; REFCTL0 &= ~REFON; REFCTL0 |= REFTCOFF; // Temp sensor disabled // Config pins as outputs by default except P2, wich contains the ADC inputs P1DIR = 0xFF; P3DIR = 0xFF; PJDIR = 0xFF; }
//---------------------------------------------------------------------------- VOID Init_StartUp(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer __disable_interrupt(); // Disable global interrupts Init_Ports(); // Init ports (do first ports because clocks do change ports) SetVCore(3); // USB core requires the VCore set to 1.8 volt, independ of CPU clock frequency Init_Clock(); __enable_interrupt(); // enable global interrupts Port_Mapping(); #ifdef UART0_INTFNUM InitUart0(9600); #endif #ifdef UART1_INTFNUM InitUart1(9600); #endif }
VOID Init_StartUp(VOID) { unsigned short bGIE; bGIE = (__get_SR_register() &GIE); //save interrupt status __disable_interrupt(); // Disable global interrupts # ifdef __MSP430F6638 // only for F663x devices! while (BAKCTL & LOCKBAK) // check if bit for backup subsystem is cleared { BAKCTL &= ~LOCKBAK; // clear lock backup bit for backup subsystem } # endif Init_Ports(); // Init ports (do first ports because clocks do change ports) SetVCore(3); // USB core requires the VCore set to 1.8 volt, independ of CPU clock frequency Init_Clock(); # if 0 // Use for FET boards // Configure P1.6 as a button input P1DIR &= ~BIT6; // Input P1OUT |= BIT6; P1REN |= BIT6; // Together with P1OUT, creates a pullup P1IFG &= ~BIT6; // Clear the flag P1IE |= BIT6; // Enable interrupts # else // Use for F5529 EXP board P1DIR &= ~BIT7; // Input P1OUT |= BIT7; P1REN |= BIT7; // Together with P1OUT, creates a pullup P1IFG &= ~BIT7; // Clear the flag P1IE |= BIT7; // Enable interrupts # endif __bis_SR_register(bGIE); //restore interrupt status }
/************************************************************************************************** * @fn Bsp_SetVCore * * @brief Setup the core voltage. * * @param none * * @return none ************************************************************************************************** */ static void Bsp_SetVCore(void) { SetVCore(3); }
/* * ======== main ======== */ VOID main (VOID) { WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer Init_Ports(); //Init ports (do first ports because clocks do change ports) SetVCore(3); Init_Clock(); //Init clocks USB_init(); //Init USB Init_TimerA1(); //Enable various USB event handling routines USB_setEnabledEvents( kUSB_VbusOnEvent + kUSB_VbusOffEvent + kUSB_receiveCompletedEvent + kUSB_dataReceivedEvent + kUSB_UsbSuspendEvent + kUSB_UsbResumeEvent + kUSB_UsbResetEvent); //See if we're already attached physically to USB, and if so, connect to it //Normally applications don't invoke the event handlers, but this is an exception. if (USB_connectionInfo() & kUSB_vbusPresent){ USB_handleVbusOnEvent(); } __enable_interrupt(); //Enable interrupts globally while (1) { BYTE i; //Check the USB state and directly main loop accordingly switch (USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts enabled _NOP(); //For Debugger break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: __bis_SR_register(LPM0_bits + GIE); //Enter LPM0 (can't do LPM3 when active) _NOP(); //For Debugger //Exit LPM on USB receive and perform a receive //operation if (bCDCDataReceived_event){ //Some data is in the buffer; begin receiving a //command char pieceOfString[MAX_STR_LENGTH] = ""; //Holds the new addition to the string char outString[MAX_STR_LENGTH] = ""; //Holds the outgoing string //Add bytes in USB buffer to theCommand cdcReceiveDataInBuffer((BYTE*)pieceOfString, MAX_STR_LENGTH, CDC0_INTFNUM); //Get the next piece of the string strcat(wholeString,pieceOfString); cdcSendDataInBackground((BYTE*)pieceOfString, strlen(pieceOfString),CDC0_INTFNUM,0); //Echoes back the characters received (needed //for Hyperterm) if (retInString(wholeString)){ //Has the user pressed return yet? if (!(strcmp(wholeString, "LED ON"))){ //Compare to string #1, and respond TA1CTL &= ~MC_1; //Turn off Timer P1OUT |= BIT0; //Turn on LED P1.0 strcpy(outString,"\r\nLED is ON\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED OFF"))){ //Compare to string #2, and respond TA1CTL &= ~MC_1; //Turn off Timer P1OUT &= ~BIT0; //Turn off LED P1.0 strcpy(outString,"\r\nLED is OFF\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED TOGGLE - SLOW"))){ //Compare to string #3, and respond TA1CTL &= ~MC_1; //Turn off Timer TA1CCR0 = SlowToggle_Period; //Set Timer Period for slow LED toggle TA1CTL |= MC_1; //Start Timer strcpy(outString, "\r\nLED is toggling slowly\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED TOGGLE - FAST"))){ //Compare to string #4, and respond TA1CTL &= ~MC_1; //Turn off Timer TA1CCR0 = FastToggle_Period; //Set Timer Period for fast LED toggle TA1CTL |= MC_1; strcpy(outString,"\r\nLED is toggling fast\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else { //Handle other strcpy(outString,"\r\nNo such command!\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } for (i = 0; i < MAX_STR_LENGTH; i++){ //Clear the string in preparation for the next //one wholeString[i] = 0x00; } } bCDCDataReceived_event = FALSE; } break; case ST_ENUM_SUSPENDED: P1OUT &= ~BIT0; //When suspended, turn off LED __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts _NOP(); break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: P1OUT &= ~BIT0; __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } //while(1) } //main()
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop the watchdog __enable_interrupt(); // Enable general interrupts Board_init(); // Configure's the F5529 EXP board's I/Os // Initialize power/clocks for use with USB SetVCore(3); // The USB module requires that VCore be set to highest setting, independent of MCLK freq ClockUSB(); disk_initialize(0); // SD-cards must go through a setup sequence after powerup. This FatFs call does this. USB_init(); // Initializes the USB API, and prepares the USB module to detect USB insertion/removal events USB_setEnabledEvents(kUSB_allUsbEvents); // Enable all USB events // The data interchange buffer (used when handling SCSI READ/WRITE) is declared by the application, and // registered with the API using this function. This allows it to be assigned dynamically, giving // the application more control over memory management. USBMSC_registerBufInfo(&RW_dataBuf[0], NULL, sizeof(RW_dataBuf)); // The API maintains an instance of the USBMSC_RWbuf_Info structure. If double-buffering were used, it would // maintain one for both the X and Y side. (This version of the API only supports single-buffering, // so only one structure is maintained.) This is a shared resource between the API and application; the // application must request the pointers. RWbuf_info = USBMSC_fetchInfoStruct(); // USBMSC_updateMediaInfo() must be called prior to USB connection. We check if the card is present, and if so, pull its size // and bytes per block. // LUN0 mediaInfo.mediaPresent = 0x01; // The medium is present, because internal flash is non-removable. mediaInfo.mediaChanged = 0x00; // It can't change, because it's in internal memory, which is always present. mediaInfo.writeProtected = 0x00; // It's not write-protected mediaInfo.lastBlockLba = 774; // 774 blocks in the volume. (This number is also found twice in the volume itself; see mscFseData.c. They should match.) mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; // 512 bytes per block. (This number is also found in the volume itself; see mscFseData.c. They should match.) USBMSC_updateMediaInfo(0, &mediaInfo); // LUN1 if(detectCard()) mediaInfo.mediaPresent = kUSBMSC_MEDIA_PRESENT; else mediaInfo.mediaPresent = kUSBMSC_MEDIA_NOT_PRESENT; mediaInfo.mediaChanged = 0x00; mediaInfo.writeProtected = 0x00; disk_ioctl(0,GET_SECTOR_COUNT,&mediaInfo.lastBlockLba); // Returns the number of blocks (sectors) in the media. mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; // Block size will always be 512 USBMSC_updateMediaInfo(1, &mediaInfo); // At compile-time for this demo, there will be one file on the volume. The root directory and data cluster // for this file need to be initialized. //flashWrite_LBA(Root_Dir, (BYTE*)Root_Dir_init); //flashWrite_LBA(Data559, (BYTE*)Data559_init); // Configure Timer_A0 to prompt detection of the SD card every second TA0CCTL0 = CCIE; // Enable interrupt TA0CCR0 = 32768; // Clock will be 32kHz, so we set the int to occur when it counts to 32768 TA0CTL = TASSEL_1 + MC_1 + TACLR; // ACLK = 32kHz, up mode, clear TAR... go! // If USB is already connected when the program starts up, then there won't be a USB_handleVbusOnEvent(). // So we need to check for it, and manually connect if the host is already present. if (USB_connectionInfo() & kUSB_vbusPresent) { if (USB_enable() == kUSB_succeed) { USB_reset(); USB_connect(); } } while(1) { BYTE ReceiveError=0, SendError=0; WORD count; switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 until VBUS-on event // Check if the reason we woke was a button press; and if so, log a new piece of data. if(fS1ButtonEvent) { // Build string char str[14] = "Data entry #0\n"; str[12] = logCnt++; // Number the entries 0 through....? memcpy(RW_dataBuf, Data559, BYTES_PER_BLOCK); // Copy data block 559 from flash to RAM buffer memcpy(&RW_dataBuf[DataCnt], str, sizeof(str)); // Write the new entry to the RAM buffer flashWrite_LBA((PBYTE)Data559, RW_dataBuf); // Copy it back to flash DataCnt += sizeof(str); // Increment the index past the new entry if((DataCnt + sizeof(str)>= BYTES_PER_BLOCK)) // Roll index back to 0, if no more room in the block DataCnt = 0; fS1ButtonEvent = 0; } break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: // Call USBMSC_poll() to initiate handling of any received SCSI commands. Disable interrupts // during this function, to avoid conflicts arising from SCSI commands being received from the host // AFTER decision to enter LPM is made, but BEFORE it's actually entered (in other words, avoid // sleeping accidentally). __disable_interrupt(); if((USBMSC_poll() == kUSBMSC_okToSleep) && (!bDetectCard)) { __bis_SR_register(LPM0_bits + GIE); // Enable interrupts atomically with LPM0 entry } __enable_interrupt(); // If the API needs the application to process a buffer, it will keep the CPU awake by returning kUSBMSC_processBuffer // from USBMSC_poll(). The application should then check the 'operation' field of all defined USBMSC_RWbuf_Info // structure instances. If any of them is non-null, then an operation needs to be processed. A value of // kUSBMSC_READ indicates the API is waiting for the application to fetch data from the storage volume, in response // to a SCSI READ command from the USB host. After the application does this, it must indicate whether the // operation succeeded, and then close the buffer operation by calling USBMSC_bufferProcessed(). while(RWbuf_info->operation == kUSBMSC_READ) { switch(RWbuf_info->lun) { case 0: RWbuf_info->returnCode = Read_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Fetch a block from the medium, using file system emulation USBMSC_bufferProcessed(); // Close the buffer operation break; case 1: read_LUN1(); break; } } // Everything in this section is analogous to READs. Reference the comments above. while(RWbuf_info->operation == kUSBMSC_WRITE) { switch(RWbuf_info->lun) { case 0: RWbuf_info->returnCode = Write_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Write the block to the medium, using file system emulation USBMSC_bufferProcessed(); // Close the buffer operation break; case 1: write_LUN1(); break; } } // Every second, the Timer_A ISR sets this flag. The checking can't be done from within the timer ISR, because the // checking enables interrupts, and this is not a recommended practice due to the risk of nested interrupts. if(bDetectCard) { checkInsertionRemoval(); bDetectCard = 0x00; // Clear the flag, until the next timer ISR } if(bHID_DataReceived_event) //Message is received from HID application { bHID_DataReceived_event = FALSE; // Clear flag early -- just in case execution breaks below because of an error count = hidReceiveDataInBuffer((BYTE*)dataBuffer,BUFFER_SIZE,HID0_INTFNUM); strncat(wholeString," \r\nRx->",7); strncat(wholeString,(char*)dataBuffer,count); strncat(wholeString," \r\n ",4); if(cdcSendDataInBackground((BYTE*)wholeString,strlen(wholeString),CDC0_INTFNUM,1)) // Send message to other CDC App { SendError = 0x01; break; } memset(wholeString,0,MAX_STR_LENGTH); // Clear wholeString } if(bCDC_DataReceived_event) //Message is received from CDC application { bCDC_DataReceived_event = FALSE; // Clear flag early -- just in case execution breaks below because of an error cdcReceiveDataInBuffer((BYTE*)wholeString,MAX_STR_LENGTH,CDC0_INTFNUM); ASCII(wholeString); if(hidSendDataInBackground((BYTE*)wholeString,strlen(wholeString),HID0_INTFNUM,1)) // Send message to HID App { SendError = 0x01; // Something went wrong -- exit break; } memset(wholeString,0,MAX_STR_LENGTH); // Clear wholeString } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3, until a resume or VBUS-off event break; case ST_ENUM_IN_PROGRESS: break; case ST_ERROR: break; default:; } if(ReceiveError || SendError) { //TO DO: User can place code here to handle error } } }
/*---------------------------------------------------------------------------*/ void clock_init(void) { /* set clock sources: */ /* FLLREFCLK <- XT1 (low-frequency crystal, 32,768 Hz) */ /* SMCLK <- XT2 (high-frequency crystal, 26 MHz / 8 = 3.25 MHz) */ /* ACLK <- XT1 (low-frequency crystal, 32768 Hz) */ /* MCLK <- XT2 (high-frequency crystal, 26 MHz / 2 = 13 MHz) */ /* set the supply voltage to the 3rd level (there are 4 levels) */ SetVCore(PMMCOREV_2); /* disable oscillator fault interrupt */ SFRIE1 &= ~OFIE; /* enable XT2 and XT1 (ensures that they stay always on) */ ENABLE_XT2(); #if CLOCK_CONF_XT1_ON ENABLE_XT1(); /* set pins 5.0 and 5.1 to analog (XT1 operation) */ P5SEL |= BIT0 + BIT1; /* set internal load capacitor for XT1 * note: the total capacitance seen by the crystal is (XCAP + 2pF) / 2 * where XCAP can be 2 (XCAP_0), 6, 9 or 12pF (XCAP_3) * default value is 3 */ UCSCTL6 &= ~XCAP_3; UCSCTL6 |= CLOCK_CONF_XT1_CAP; #endif /* CLOCK_CONF_XT1_ON */ /* initially, use the internal REFO and DCODIV clock sources */ UCSCTL3 = SELREF__REFOCLK | FLLREFDIV_0; UCSCTL4 = SELA__REFOCLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; /* wait until XT1, XT2, and DCO stabilize */ WAIT_FOR_OSC(); #if CLOCK_CONF_XT1_ON /* XT1 is now stable: reduce its drive strength to save power * for eff. load cap. btw. 6 and 9pF, use DRIVE_1 (see datasheet p.49) */ UCSCTL6 &= ~XT1DRIVE_3; UCSCTL6 |= XT1DRIVE_1; #endif /* CLOCK_CONF_XT1_ON */ /* set the DCO frequency to 3.25 MHz */ /* disable the FLL control loop */ DISABLE_FLL(); #if CLOCK_CONF_FLL_ON #if CLOCK_CONF_XT1_ON UCSCTL3 = SELREF__XT1CLK | FLLREFDIV_0; /* use XT1 as FLL reference */ #endif /* CLOCK_CONF_XT1_ON */ /* set the lowest possible DCOx, MODx */ UCSCTL0 = 0; /* select the suitable DCO frequency range */ UCSCTL1 = DCORSEL_6; /* set the FLL loop divider to 2 and * the multiplier N such that (N + 1) * f_FLLREF = f_DCO --> N = 396 */ UCSCTL2 = FLLD_0 + 396; /* enable the FLL control loop */ ENABLE_FLL(); /* wait until the DCO stabilizes */ /* (up to 1 x 32 x 32 x 13 MHz / 32,768 Hz = 406,250 DCO cycles) */ __delay_cycles(406250); #endif /* CLOCK_CONF_FLL_ON */ /* finally, use the desired clock sources and speeds */ UCSCTL4 = SELA | SELS | SELM; UCSCTL5 = DIVA | DIVS | DIVM; /* note: will automatically use DCOCLKDIV for SMCLK and MCLK if XT2CLK is * not available */ /* oscillator fault flag may be set after switching the clock source */ WAIT_FOR_OSC(); /* enable oscillator fault interrupt (NMI) as well as vacant memory access * interrupt (VMAIE) and flash controller access violation int. (ACCVIE) */ SFRIE1 = OFIE | VMAIE | ACCVIE; }
// ************************************************************************************************* // @fn init_application // @brief Initialize the microcontroller. // @param none // @return none // ************************************************************************************************* void init_application(void) { volatile unsigned char *ptr; #ifndef EMU // --------------------------------------------------------------------- // Enable watchdog // Watchdog triggers after 16 seconds when not cleared #ifdef USE_WATCHDOG WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK; #else WDTCTL = WDTPW + WDTHOLD; #endif // --------------------------------------------------------------------- // Configure PMM SetVCore(3); // Set global high power request enable PMMCTL0_H = 0xA5; PMMCTL0_L |= PMMHPMRE; PMMCTL0_H = 0x00; // --------------------------------------------------------------------- // Enable 32kHz ACLK P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 UCSCTL6 &= ~XT1OFF; // XT1 On, Highest drive strength UCSCTL6 |= XCAP_3; // Internal load cap UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; // --------------------------------------------------------------------- // Configure CPU clock for 12MHz _BIS_SR(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_5; // Select suitable range UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier _BIC_SR(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle __delay_cycles(250000); // Loop until XT1 & DCO stabilizes, use do-while to insure that // body is executed at least once do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); SFRIFG1 &= ~OFIFG; // Clear fault flags } while ((SFRIFG1 & OFIFG)); // --------------------------------------------------------------------- // Configure port mapping // Disable all interrupts __disable_interrupt(); // Get write-access to port mapping registers: PMAPPWD = 0x02D52; // Allow reconfiguration during runtime: PMAPCTL = PMAPRECFG; // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output) ptr = &P2MAP0; *(ptr+7) = PM_TA1CCR0A; P2OUT &= ~BIT7; P2DIR |= BIT7; // P1.5 = SPI MISO input ptr = &P1MAP0; *(ptr+5) = PM_UCA0SOMI; // P1.6 = SPI MOSI output *(ptr+6) = PM_UCA0SIMO; // P1.7 = SPI CLK output *(ptr+7) = PM_UCA0CLK; // Disable write-access to port mapping registers: PMAPPWD = 0; // Re-enable all interrupts __enable_interrupt(); #endif // --------------------------------------------------------------------- // Configure ports // --------------------------------------------------------------------- // Reset radio core radio_reset(); radio_powerdown(); // --------------------------------------------------------------------- // Init acceleration sensor as_init(); // --------------------------------------------------------------------- // Init LCD lcd_init(); // --------------------------------------------------------------------- // Init buttons init_buttons(); // --------------------------------------------------------------------- // Configure Timer0 for use by the clock and delay functions Timer0_Init(); // --------------------------------------------------------------------- // Init pressure sensor ps_init(); }
/************************************************************************************************** * @fn BSP_InitBoard * * @brief Initialize the board. * * @param none * * @return none ************************************************************************************************** */ void BSP_InitBoard(void) { /*unused pins are output low */ //P1, P2 PADIR = 0xF901; //P2.2. P2.3 GD0 GD1, P1.3 P1.2 connected to I2C lines! P1.1 button input PAOUT = 0; PASEL = 0; __bsp_BUTTON1_CONFIG_def__(); // Enable pull-ups //P3, P4 PBDIR = 0xFFFF; PBOUT = 0; PBSEL = 0; //P5, P6 PCDIR = 0xFFFF; PCOUT = 0; PCSEL = 0; //P7, P8 PDDIR = 0xFFFE; //Enable xtal pins PDOUT = (BIT6|BIT5); //ensure LED P7.6 P7.5 off PDSEL = 0x0003; //XT1 crystal //P9, P10 PEDIR = 0xFFFF; PEOUT = 0; PESEL = 0; //P11 P11DIR = 0xFF; P11OUT = 0; P11SEL = 0; /* disable watchdog timer */ WDTCTL = WDTPW+WDTHOLD; /* Setup XT1 crystal */ while ( (SFRIFG1 & OFIFG) ) { UCSCTL7 &= ~(XT1LFOFFG + DCOFFG); SFRIFG1 &= ~OFIFG; } UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive strength /* Set appropriate core voltage */ if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 8) SetVCore(0); else if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 12) SetVCore(1); else if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 20) SetVCore(2); else SetVCore(3); /* Initialize the UCS module*/ __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = BSP_CONFIG_MSP430_DCORSEL; // Select suitable range UCSCTL2 = BSP_CONFIG_MSP430_FLLDx + BSP_CONFIG_MSP430_N; // Select divider, multiplier bits UCSCTL3 = 0; // FLL Reference Clock = XT1 UCSCTL4 = SELS__DCOCLK | SELM__DCOCLK; // MCLK & SMCLK = DCOCLK UCSCTL4 |= SELA__XT1CLK; // ACLK = XT1 (32 kHz REFO) UCSCTL6 &= ~XT1DRIVE_3; // Set DCO drive to consume least power UCSCTL6 |= XCAP_3 ; // Setup internal caps for crystal __bic_SR_register(SCG0); /* Give FLL enough time to settle */ if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 8) __delay_cycles(250000); else if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 12) __delay_cycles(375000); else if(BSP_CONFIG_CLOCK_MHZ_SELECT <= 20) __delay_cycles(625000); else __delay_cycles(812500); //ensure 3.3 V for MSP430 power supply P6DIR |= (BIT7); P6OUT &= ~(BIT7); //enable Vio power supply P8DIR |= (BIT5); P8OUT |= (BIT5); /* Configure TimerA for use by BSP_Delay*/ TA1CTL |= TACLR; // Reset the timer TA1CTL = 0x0; // Clear all settings TA1CTL |= TASSEL_2; // Select the clk source to be // - SMCLK (Sub-Main CLK) //give time for Vio power supplies to settle { int i; for(i = 0; i < 10; i++) BSP_Delay(1000); } }