]> git.karo-electronics.de Git - oswald.git/blobdiff - metawatch/mw_main.c
Add modified LPM3_EXIT_ISR to work around FLL IRQ wake-up problem
[oswald.git] / metawatch / mw_main.c
index 4ba6c542845b7dd1f177e62a2f09579f458d4aa5..07f8ba581a3c1c4493d02caf420ca31ca6eb87e4 100644 (file)
 #include "oswald_main.h"
 #include "oswald_hal.h"
 
+#include "bluetooth_init_cc256x.h"
 
 uint16_t _event_src = 0;
 
 #define HARDWARE_REVISION_ADDRESS (0x1a07)
 
-unsigned char GetMsp430HardwareRevision(void)
+uint8_t GetMsp430HardwareRevision(void)
 {
-       unsigned char *pDeviceType = (unsigned char *)(unsigned char *)HARDWARE_REVISION_ADDRESS;
+       uint8_t *pDeviceType = (uint8_t *)(uint8_t *)HARDWARE_REVISION_ADDRESS;
   
        return pDeviceType[0]+'1';                         
 }
 
 uint8_t DetermineErrata(void)
 {
-       unsigned char Revision = GetMsp430HardwareRevision();
+       uint8_t Revision = GetMsp430HardwareRevision();
   
        switch (Revision) {
                case 'F':
+               case 'G':
                case 'H':
                        return 0;
                        break;
@@ -67,6 +69,31 @@ static void set16mhz(void)
        }
 }
 
+static unsigned char PMM15Check(void)
+{
+  // First check if SVSL/SVML is configured for fast wake-up
+  if ((!(SVSMLCTL & SVSLE)) || ((SVSMLCTL & SVSLE) && (SVSMLCTL & SVSLFP)) ||
+      (!(SVSMLCTL & SVMLE)) || ((SVSMLCTL & SVMLE) && (SVSMLCTL & SVMLFP)))
+  { 
+    // Next Check SVSH/SVMH settings to see if settings are affected by PMM15
+    if ((SVSMHCTL & SVSHE) && (!(SVSMHCTL & SVSHFP)))
+    {
+      if ( (!(SVSMHCTL & SVSHMD)) ||
+           ((SVSMHCTL & SVSHMD) && (SVSMHCTL & SVSMHACE)) )
+        return 1; // SVSH affected configurations
+    }
+
+    if ((SVSMHCTL & SVMHE) && (!(SVSMHCTL & SVMHFP)) && (SVSMHCTL & SVSMHACE))
+      return 1; // SVMH affected configurations
+  }
+
+  return 0; // SVS/M settings not affected by PMM15
+}
+
+#define configCPU_CLOCK_HZ ((unsigned long) 16777216) /* 512*32768 */
+#define configTICK_RATE_HZ ((unsigned int)1024)
+#define ACLK_MULTIPLIER    ((unsigned int)512)
+
 static void setup_clocks(void)
 {
        unsigned long i;
@@ -75,6 +102,8 @@ static void setup_clocks(void)
 
        /* use external oscillator */
        P7SEL |= BIT0 + BIT1;
+
+#if 1
        if ((UCSCTL6 & XT1DRIVE_3) != XT1DRIVE_3) {
                UCSCTL6_L |= XT1DRIVE1_L + XT1DRIVE0_L;
        }
@@ -88,7 +117,21 @@ static void setup_clocks(void)
        set16mhz();
 
        UCSCTL8 |= SMCLKREQEN;
+#else
+       // Startup LFXT1 32 kHz crystal
+       while (LFXT_Start_Timeout(XT1DRIVE_0, 50000) == UCS_STATUS_ERROR)
+               nop();
+
+       // 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);
+#endif
        // setup for quick wake up from interrupt and
        // minimal power consumption in sleep mode
        DISABLE_SVSL();                         // SVS Low side is turned off
@@ -105,12 +148,15 @@ static void setup_clocks(void)
 
        SVSH_ENABLED_IN_LPM_FULL_PERF();        // SVS high side Full perf mode,
                                                // stays on in LPM3,enhanced protect
+       SVSL_ENABLED_IN_LPM_FAST_WAKE();
 
        // Wait until high side, low side settled
        while ((PMMIFG & SVSMLDLYIFG) == 0 && (PMMIFG & SVSMHDLYIFG) == 0)
                nop();
        CLEAR_PMM_IFGS();
 
+       while (PMM15Check());
+
        // Errata PMM17
        if (DetermineErrata()) {
                *(unsigned int*)(0x0110) = 0x9602;
@@ -176,9 +222,12 @@ static void setup_pins(void)
        APPLE_POWER_DISABLE();
 
        CONFIG_BT_PINS();
-       BT_CLK_REQ_CONFIG_AS_OUTPUT_LOW();
-       BT_IO1_CONFIG_AS_OUTPUT_LOW();
-       BT_IO2_CONFIG_AS_OUTPUT_LOW();
+//     BT_CLK_REQ_CONFIG_AS_OUTPUT_LOW();
+//     BT_IO1_CONFIG_AS_OUTPUT_LOW();
+//     BT_IO2_CONFIG_AS_OUTPUT_LOW();
+       BT_CLK_REQ_CONFIG_AS_INPUT();
+       BT_IO1_CONFIG_AS_INPUT();
+       BT_IO2_CONFIG_AS_INPUT();
        mw_disable_bt();
 
        LIGHT_SENSE_INIT();
@@ -198,6 +247,20 @@ static void setup_pins(void)
 #ifndef MW_DEVBOARD_V2 // but only on real watch
        SFRRPCR &= ~SYSRSTRE;
        SFRRPCR |= SYSNMI;
+#endif
+       /* allow debug UART */
+/*
+       P10SEL &= ~(BIT6 | BIT7);
+       P10DIR |= BIT6 | BIT7;
+       P10OUT &= ~(BIT6 | BIT7);
+*/
+#ifndef MW_DEVBOARD_V2
+       ENABLE_MUX_OUTPUT_CONTROL();
+#ifdef MW_DEBUG_UART
+       MUX_OUTPUT_SELECTS_SERIAL();
+#else
+       MUX_OUTPUT_OFF();
+#endif
 #endif
 }
 
@@ -250,8 +313,8 @@ __interrupt void RTC_ISR (void)
                case RTCIV_RT1PSIFG:
                        RTCPS1CTL &= ~RT1PSIFG;
                        _event_src |= RTC_1HZ_EVENT;
-                       LPM3_EXIT;
-                       nop();
+                       // LPM3_EXIT;
+                       LPM3_EXIT_ISR();
 #if defined MW_DEVBOARD_V2
                        LED7_TOGGLE();
 #endif
@@ -301,7 +364,7 @@ void setup_rtc(void)
        nop();
 }
 
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
 static void dbg_out_rtc(void)
 {
        char clk_str[16];
@@ -377,7 +440,7 @@ static void handle_bt_uart_rx_event(void)
        *rp = (*rp + len) % BT_RX_MAX_SIZE;
 }
 
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
 static void handle_uart_rx_event(void)
 {
        char c;
@@ -462,6 +525,20 @@ static void handle_uart_rx_event(void)
                        debug_uart_tx("HCI reset\n");
                        bt_hci_cmd(HCI_HC_BB_OGF, HCI_RESET_OCF, 0, NULL);
                        bt_hci_cmd(HCI_HC_BB_OGF, HCI_W_COD_OCF, 3, dclass);
+               } else if (c == 'i') {
+                       debug_uart_tx("Information:\n");
+                       debug_uart_tx("Oswald ");
+                       debug_uart_tx(MW_MAIN_VERSION);
+                       debug_uart_tx("\n");
+                       debug_uart_tx("Build #");
+                       debug_uart_tx(BUILDNO);
+                       debug_uart_tx("\n");
+                       debug_uart_tx("BT V ");
+                       debug_uart_tx(cc256x_version);
+                       debug_uart_tx("\n");
+                       debug_uart_tx("MCU Rev ");
+                       debug_uart_tx_char(GetMsp430HardwareRevision());
+                       debug_uart_tx("\n");
                } else if (c == 'S') {
                        debug_uart_tx("Scan enable\n");
                        tstr[0] = HCI_BB_SCAN_INQUIRY | HCI_BB_SCAN_PAGE;
@@ -516,12 +593,13 @@ __interrupt void TIMER0_A0_ISR (void)
        LED6_TOGGLE();
 #endif
        _event_src |= TIMER_500MS_EVENT | TIMER_100MS_EVENT;
-       LPM3_EXIT;
+       // LPM3_EXIT;
+       LPM3_EXIT_ISR();
 }
 
 uint8_t handle_event(void)
 {
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
        char tstr[64];
 #endif
        if (_event_src == 0)
@@ -535,7 +613,7 @@ uint8_t handle_event(void)
                        _event_src &= ~RTC_1HZ_EVENT;
                        check_pwr_state();
                        oswald_one_second_tick();
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
                        dbg_out_rtc();
 #endif
                } else if (_event_src & BT_UART_RCV_EVENT) {
@@ -546,7 +624,7 @@ uint8_t handle_event(void)
                        bt_hci_ehcill_wake();
                } else if (_event_src & DBG_UART_RCV_EVENT) {
                        _event_src &= ~DBG_UART_RCV_EVENT;
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
                        handle_uart_rx_event();
 #endif
                } else if (_event_src & BUTTON_EVENT) {
@@ -562,7 +640,7 @@ uint8_t handle_event(void)
                        _event_src &= ~ACCEL_EVENT;
                        mw_acc_handle_irq();
                } else {
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
                        snprintf(tstr, 64, "unhandled event in 0x%04x\n", _event_src);
                        debug_uart_tx(tstr);
 #endif
@@ -574,7 +652,8 @@ uint8_t handle_event(void)
 #pragma vector=BUTTON_PORT_VECTOR
 __interrupt void BUTTON_ISR (void)
 {
-       LPM3_EXIT;
+       // LPM3_EXIT;
+       LPM3_EXIT_ISR();
        BUTTON_PORT_IFG &= ~ALL_BUTTONS;
        // BUTTON_PORT_IE  &= ~INT_EDGE_SEL_BUTTONS;
        _event_src |= BUTTON_EVENT;
@@ -585,14 +664,16 @@ __interrupt void BUTTON_ISR (void)
 __interrupt void PORT1_GPIO_ISR (void)
 {
        if (P1IFG & BT_IO_CTS) {
-               LPM3_EXIT;
+               //LPM3_EXIT;
+               LPM3_EXIT_ISR();
                P1IE &= ~BT_IO_CTS;
                P1IFG &= ~BT_IO_CTS;
                debug_uart_tx("BT CTS irq\n");
                _event_src |= BT_UART_WAKEUP_EVENT;
                // bt_hci_ehcill_wake();
        } else if (P1IFG & ACCELEROMETER_INT_PIN) {
-               LPM3_EXIT;
+               //LPM3_EXIT;
+               LPM3_EXIT_ISR();
                P1IFG &= ~ACCELEROMETER_INT_PIN;
                // debug_uart_tx("ACC irq\n");
                _event_src |= ACCEL_EVENT;
@@ -619,7 +700,7 @@ int main(void)
        /* enable interrupts, we will need them! */
        __enable_interrupt();
 
-#if defined MW_DEVBOARD_V2
+#if defined MW_DEVBOARD_V2 || MW_DEBUG_UART
        init_debug_uart();
        debug_uart_tx("\nOswald on MetaWatch\n");
 #endif