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