-
Edward Longman authoredEdward Longman authored
hal_mcu.c 10.12 KiB
/******************************************************************************
* 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