From 1200ff03100e17e9db46ddb73be579f2e424fd95 Mon Sep 17 00:00:00 2001 From: Edward Longman <el7g15@soton.ac.uk> Date: Thu, 16 May 2019 11:56:04 +0100 Subject: [PATCH] Correct clock control registers and add fr5994 specific setup of device --- source/lib/hal_mcu/hal_fr5_timer.c | 36 +++++++-------- source/lib/hal_mcu/hal_mcu.c | 74 ++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/source/lib/hal_mcu/hal_fr5_timer.c b/source/lib/hal_mcu/hal_fr5_timer.c index bab4722..4232eae 100644 --- a/source/lib/hal_mcu/hal_fr5_timer.c +++ b/source/lib/hal_mcu/hal_fr5_timer.c @@ -64,10 +64,10 @@ void hal_timer_init(unsigned int master_count) { // Start Timer 0 using the ACLK as a source (this enables the use of // various low power modes). Timer 0 will be used to keep RF burst time - TACCR0 = master_count - 1; // Seting for MASTER SCHEDULE - TACCR1 = 0; // will be used for burst alignnment - TACCR2 = 0; // will be used for expiration counter - TACTL = TASSEL_2 + MC_1 + TACLR + ID_0;// SMCLK, Up to CCR0, clear TB0R, div/1 + TA0CCR0 = master_count - 1; // Seting for MASTER SCHEDULE + TA0CCR1 = 0; // will be used for burst alignnment + TA0CCR2 = 0; // will be used for expiration counter + TA0CTL = TASSEL_2 + MC_1 + TACLR + ID_0;// SMCLK, Up to CCR0, clear TB0R, div/1 return; } @@ -171,7 +171,7 @@ unsigned int hal_timer_get_time(unsigned long *sec, unsigned long *ms) { void hal_timer_stop(void) { /* clear timer configuration register, stopping the timer */ - TACTL = 0; + TA0CTL = 0; return; } @@ -194,13 +194,13 @@ void hal_timer_stop(void) { void hal_timer_expire(void) { /* enable timer interrupt */ - TACCTL1 = CCIE; + TA0CCTL1 = CCIE; /* enter low power mode and wait */ _BIS_SR(LPM0_bits + GIE); /* disable interrupt again */ - TACCTL1 = 0; + TA0CCTL1 = 0; return; } @@ -227,20 +227,20 @@ unsigned int hal_timer_wait(unsigned int time) { wait_count = TAR_init + time; // if the requested wait time exceeds the TACCR0 (max value) then make a loop - while(wait_count > TACCR0) { + while(wait_count > TA0CCR0) { // configure the timeout for 1 less than the master clock - TACCR2 = TACCR0-1; + TA0CCR2 = TA0CCR0-1; // calculate the remaining wait time remaining - wait_count = wait_count - (TACCR2 - TAR_init); + wait_count = wait_count - (TA0CCR2 - TAR_init); // do not count the initial timer values more that once, zero it out timer_event = 0; TAR_init = 0; // enable interupts and wait for timer (or CC1x GDO ISR) - TACCTL2 = CCIE; // interrupt enabled + TA0CCTL2 = CCIE; // interrupt enabled _BIS_SR(LPM0_bits + GIE); // Enter LPM0 // check to see if the timer woke us up or not @@ -253,16 +253,16 @@ unsigned int hal_timer_wait(unsigned int time) { // loop this is the only wait that gets executed /* define maximum timeout by using timer counter 2 */ - TACCR2 = wait_count; + TA0CCR2 = wait_count; /* enable interrupt */ - TACCTL2 = CCIE; + TA0CCTL2 = CCIE; /* enter low power mode and wait for event (timer or radio) */ _BIS_SR(LPM0_bits + GIE); /* disable interupts on CCR2 */ - TACCTL2 = 0; + TA0CCTL2 = 0; /* return the time spend in sleep */ return (time - (wait_count-TA0R)); @@ -283,7 +283,7 @@ unsigned int hal_timer_wait(unsigned int time) { * @return void * */ - void __attribute__((interrupt(TIMERA1_VECTOR))) TIMERA_ISR(void){ +HAL_ISR_FUNC_DECLARATION(TIMER_A1,timer_a1_isr){ //#pragma vector=TIMERB1_VECTOR //__interrupt void TIMERB1_ISR(void) { @@ -292,7 +292,7 @@ unsigned int hal_timer_wait(unsigned int time) { switch( __even_in_range(TAIV,14) ) { case TA0IV_NONE: break; // No interrupt - case TA0IV_TBCCR1: // Used to wake up radio from sleep + case TA0IV_TACCR1: // Used to wake up radio from sleep timer_event = TA0IV_TACCR1; _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) break; @@ -300,7 +300,7 @@ unsigned int hal_timer_wait(unsigned int time) { timer_event = TA0IV_TACCR2; _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) break; - case TA0IV_TACCR3: // CCR3 not used +/* case TA0IV_TACCR3: // CCR3 not used break; case TA0IV_TACCR4: // CCR4 not used break; @@ -309,7 +309,7 @@ unsigned int hal_timer_wait(unsigned int time) { case TA0IV_TACCR6: // CCR6 not used break; case TA0IV_TAIFG: // IFG not used - break; + break;*/ default: break; } diff --git a/source/lib/hal_mcu/hal_mcu.c b/source/lib/hal_mcu/hal_mcu.c index 48eb9be..b52d5af 100644 --- a/source/lib/hal_mcu/hal_mcu.c +++ b/source/lib/hal_mcu/hal_mcu.c @@ -39,7 +39,7 @@ #include "msp430.h" // TODO Provide the define statements needed from this file. -#include "hal_spi_rf.h" +#include "../radio_drv/hal_spi_rf.h" #if defined (__MSP430F5438A__) /******************************************************************************* @@ -168,6 +168,55 @@ void msp_setup(void) { #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. @@ -191,16 +240,25 @@ void msp_setup(void) { // Removed XTAL configuration and DCO Fault detection as not on exp430_fr5994 - // 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_LFXTCLK | SELS__DCOCLK | SELM__DCOCLK ; + // 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 = WDTPWD + WDTSEL_0 + WDTTMSEL + WDTIS_2; + WDTCTL= WDTPW0 + WDTSSEL_0 + WDTTMSEL + WDTIS_2; SFRIE1 |= WDTIE; // Enable WDT interrupt + + // Unlock the system. + PM5CTL0 &= ~LOCKLPM5; } #endif -- GitLab