/****************************************************************************** * Filename: hal_mcu.c * * Description: Configuration of MCU core registers * * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Modified by Edward Longman for the MSP430FR5994 * *******************************************************************************/ #include "msp430.h" // TODO Provide the define statements needed from this file. #include "../radio_drv/hal_spi_rf.h" #if defined (__MSP430F5438A__) /******************************************************************************* * @brief Setup all the peripherals of the MSP430, set the CPU speed to 16MHz, * enable the 32KHz and configure WDT for a 1 sec tick speed. * * (MSP430F5438 version) * * @param none * * @return none *******************************************************************************/ void msp_setup(void) { BUTTON_DIR &= ~BUTTON_PIN; // Set output direction BUTTON_OUT = BUTTON_PIN; // Set output direction BUTTON_PxIE |= BUTTON_PIN; // interrupt enabled BUTTON_PxIES |= BUTTON_PIN; // Hi/lo edge BUTTON_REN |= BUTTON_PIN; // Pull up resistor BUTTON_PxIFG &= ~BUTTON_PIN; // IFG cleared // Setup the XTAL ports to use the external 32K oscillilator P7SEL |= 0x03; // Select XT1 UCSCTL6 |= XCAP_3; // Internal load cap // 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 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive // Set up clock system on MCU to fit your system // Target specific implementation UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_6; // Select suitable range UCSCTL2 = 488; // DCO = 488 * 32768Hz ~= 16MHz UCSCTL4 = SELA__XT1CLK | SELS__DCOCLK | SELM__DCOCLK ; // Setup Watch dog timer for 1 second tick using 32Khz XTAL on MSP430F5438A WDTCTL = WDT_ADLY_1000; // WDT 15.6ms, ACLK, interval timer SFRIE1 |= WDTIE; // Enable WDT interrupt } #endif #if defined (__MSP430F5529__) /******************************************************************************* * @brief Setup all the peripherals of the MSP430, set the CPU speed to 16MHz, * enable the 32KHz and configure WDT for a 1 sec tick speed. * * (MSP430F5529 version) * * @param none * * @return none *******************************************************************************/ void msp_setup(void) { // Enable the interupts on port 2 to catch the user button (TRXEB) BUTTON_DIR &= ~BUTTON_PIN; // input direction BUTTON_OUT |= BUTTON_PIN; // set high on port BUTTON_PxIE |= BUTTON_PIN; // enable interupt BUTTON_PxIES |= BUTTON_PIN; // Hi/lo edge BUTTON_REN |= BUTTON_PIN; // Pull up resistor BUTTON_PxIES &= ~BUTTON_PIN; // IFG cleared // Setup the XTAL ports to use the external 32K oscillilator P5SEL |= BIT4+BIT5; // Select XT1 UCSCTL6 |= XCAP_3; // Internal load cap // Loop until XT1,XT2 & DCO stabilizes do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags } while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive // Set up clock system on MCU to fit your system // Target specific implementation UCSCTL0 = 0x00; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_6; // Select suitable range UCSCTL2 = 488; // DCO = 488 * 32768Hz ~= 16MHz UCSCTL4 = SELA__XT1CLK | SELS__DCOCLK | SELM__DCOCLK ; // Setup Watch dog timer for 1 second tick using 32Khz XTAL on MSP430F5438A WDTCTL = WDT_ADLY_1000; // WDT 15.6ms, ACLK, interval timer SFRIE1 |= WDTIE; // Enable WDT interrupt } #endif #if defined (__MSP430G2553__) /******************************************************************************* * @brief Setup all the peripherals of the MSP430, set the CPU speed to 16MHz, * enable the 32KHz and configure WDT for a 1 sec tick speed. * * (MSP430G2553 version) * * @param none * * @return none *******************************************************************************/ void msp_setup(void) { BUTTON_DIR &= ~BUTTON_PIN; // Set output direction BUTTON_OUT = BUTTON_PIN; // Set output direction BUTTON_PxIE |= BUTTON_PIN; // interrupt enabled BUTTON_PxIES |= BUTTON_PIN; // Hi/lo edge BUTTON_REN |= BUTTON_PIN; // Pull up resistor BUTTON_PxIFG &= ~BUTTON_PIN; // IFG cleared // set system clock to 16MHz DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; // Setup Watch dog timer for a 1 second tick using a 32KHz external XTAL BCSCTL1 |= DIVA_0; // ACLK/1 = 32.768KHz WDTCTL = WDT_ADLY_1000; // WDT 1s interval timer IE1 |= WDTIE; // Enable WDT interrupt } #endif #if defined (__MSP430FR5994__) //Define the Main Clock setup options. Done here for the delay function setup #define DCO_RANGE_SEL DCORSEL #define DCO_FREQ_SEL DCOFSEL_4 #define F_CPU_SCALE DIVM_0 /** * @defgroup Delay_function * @brief Directives to create the _delay_us macro. * @{ */ /** * @def _delay_us(__us) * @brief Delay for a specified time using the __delay_cycles primitive. * * @param[in] __us - time to delay for * @return none * @note Assumes using the internal DCO. Will need modification to work with * XTAL. VLO is two innacurate (6%) for this to be a good delay anyway. * Max possible delay is (2**32-1)*F_CPU * That would be 178s for 24MHz. * helped by https://docs.microsoft.com/en-us/cpp/preprocessor/hash-if-hash-elif-hash-else-and-hash-endif-directives-c-cpp?view=vs-2019 * and https://github.com/ab2tech/msp430/blob/master/include/msp/delay.h * */ #if DCO_RANGE_SEL==DCORSEL #define F_CPU_RANGE 16000000UL #else #define F_CPU_RANGE 5330000UL #endif #if DCO_FREQ_SEL==DCOFSEL_0 #define F_CPU F_CPU_RANGE*1.0 #elif DCO_FREQ_SEL==DCOFSEL_1 #define F_CPU F_CPU_RANGE*1.25 #elif DCO_FREQ_SEL==DCOFSEL_2 #define F_CPU F_CPU_RANGE*1.0 #else //DCO_FREQ_SEL==DCOFSEL_3 #define F_CPU F_CPU_RANGE*1.5 #endif #define F_CPU_SCALED_US F_CPU/(1<<F_CPU_SCALE)/1000000.0 /* Number of CPU cycles per us */ #define _delay_us(__us) \ if((uint32_t) (F_CPU_SCALED_US * __us) != F_CPU_SCALED_US * __us)\ __delay_cycles((uint32_t) ( F_CPU_SCALED_US * __us)+1);\ else __delay_cycles((uint32_t) ( F_CPU_SCALED_US * __us)) /** @} */ /******************************************************************************* * @brief Setup all the peripherals of the MSP430, set the CPU speed to 16MHz, * enable the 250kHz and configure WDT for a 1 sec tick speed. * * (MSP430FR5994 version) * * @param none * * @return none *******************************************************************************/ void msp_setup(void) { // Enable the interupts on port 2 to catch the user button (TRXEB) BUTTON_DIR &= ~BUTTON_PIN; // input direction BUTTON_OUT |= BUTTON_PIN; // set high on port BUTTON_PxIE |= BUTTON_PIN; // enable interupt BUTTON_PxIES |= BUTTON_PIN; // Hi/lo edge BUTTON_REN |= BUTTON_PIN; // Pull up resistor BUTTON_PxIES &= ~BUTTON_PIN; // IFG cleared // Removed XTAL configuration and DCO Fault detection as not on exp430_fr5994 // Unlock CS registers. CSCTL0_H = 0xA5; // Set DCO to 24MHz. CSCTL1 = DCO_RANGE_SEL + DCO_FREQ_SEL; // ACLK = VLO, SMCLK = MCLK = DCO CSCTL2 = SELA_1 + SELS_3 + SELM_3; // ACLK/1, SMCLK/8, MCLK/1 CSCTL3 = DIVA_0 + DIVS_0 + F_CPU_SCALE; // Power down unused clocks. CSCTL4 = HFXTOFF + VLOOFF; // Lock clock registers. CSCTL0_H = 0; // Setup Watch dog timer for 0.5 second tick using 16MHz DCO on MSP430FR5994 // WDT 0.5s @ 16mHz, SMCLK, interval timer WDTCTL= WDTPW0 + WDTSSEL_0 + WDTTMSEL + WDTIS_2; SFRIE1 |= WDTIE; // Enable WDT interrupt // Unlock the system. PM5CTL0 &= ~LOCKLPM5; } #endif