Merge "mpu: actually enable the mpu (for real this time)"
diff --git a/firmware/os/drivers/leds/leds_lp3943.c b/firmware/os/drivers/leds/leds_lp3943.c
index 9bce104..d05571f 100644
--- a/firmware/os/drivers/leds/leds_lp3943.c
+++ b/firmware/os/drivers/leds/leds_lp3943.c
@@ -60,7 +60,7 @@
 #define LP3943_MAX_LED_SECTION          4
 
 #ifndef LP3943_DBG_ENABLE
-#define LP3943_DBG_ENABLE               1
+#define LP3943_DBG_ENABLE               0
 #endif
 #define LP3943_DBG_VALUE                0x55
 
diff --git a/firmware/os/drivers/st_mag40/st_mag40.c b/firmware/os/drivers/st_mag40/st_mag40.c
index cfdf642..ee8e8fa 100644
--- a/firmware/os/drivers/st_mag40/st_mag40.c
+++ b/firmware/os/drivers/st_mag40/st_mag40.c
@@ -45,6 +45,7 @@
 #define ST_MAG40_WAI_REG_VAL       0x40
 
 #define ST_MAG40_CFG_A_REG_ADDR    0x60
+#define ST_MAG40_TEMP_COMP_EN      0x80
 #define ST_MAG40_SOFT_RESET_BIT    0x20
 #define ST_MAG40_ODR_10_HZ         0x00
 #define ST_MAG40_ODR_20_HZ         0x04
@@ -64,6 +65,9 @@
 
 #define ST_MAG40_OUTXL_REG_ADDR    0x68
 
+/* Enable auto-increment of the I2C subaddress (to allow I2C multiple ops) */
+#define ST_MAG40_I2C_AUTO_INCR     0x80
+
 enum st_mag40_SensorEvents
 {
     EVT_COMM_DONE = EVT_APP_START + 1,
@@ -371,7 +375,7 @@
     if (xfer != NULL) {
         xfer->delay = delay;
         xfer->last = last;
-        xfer->txrxBuf[0] = 0x80 | addr;
+        xfer->txrxBuf[0] = ST_MAG40_I2C_AUTO_INCR | addr;
         i2cMasterTxRx(ST_MAG40_I2C_BUS_ID, ST_MAG40_I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, len, i2cCallback, xfer);
     }
 }
@@ -598,8 +602,7 @@
                 sendTestResult(SENSOR_APP_EVT_STATUS_ERROR, SENS_TYPE_MAG);
 
         mTask.mag_test_state = MAG_SELFTEST_DONE;
-        mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR, ST_MAG40_POWER_IDLE, 0, false);
-        mTask.comm_tx(ST_MAG40_CFG_B_REG_ADDR, ST_MAG40_OFF_CANC, 0, false);
+        mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR, ST_MAG40_TEMP_COMP_EN | ST_MAG40_POWER_IDLE, 0, false);
         mTask.comm_tx(ST_MAG40_CFG_C_REG_ADDR, ST_MAG40_BDU_ON | ST_MAG40_INT_MAG, 0, true);
         break;
 
@@ -766,7 +769,7 @@
     case CONFIG_POWER_UP:
         mTask.subState = CONFIG_POWER_UP_2;
         mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR,
-                      ST_MAG40_POWER_ON | mTask.currentODR, 0, true);
+                      ST_MAG40_TEMP_COMP_EN | ST_MAG40_POWER_ON | mTask.currentODR, 0, true);
         break;
 
     case CONFIG_POWER_UP_2:
@@ -779,7 +782,7 @@
     case CONFIG_POWER_DOWN:
         mTask.subState = CONFIG_POWER_DOWN_2;
         mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR,
-                      ST_MAG40_POWER_IDLE | mTask.currentODR, 0, true);
+                      ST_MAG40_TEMP_COMP_EN | ST_MAG40_POWER_IDLE | mTask.currentODR, 0, true);
         break;
 
     case CONFIG_POWER_DOWN_2:
@@ -793,7 +796,7 @@
         mTask.subState = CONFIG_SET_RATE_2;
         tmp = mTask.magOn ? ST_MAG40_POWER_ON : ST_MAG40_POWER_IDLE;
         tmp |= mTask.currentODR;
-        mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR, tmp, 0, true);
+        mTask.comm_tx(ST_MAG40_CFG_A_REG_ADDR, ST_MAG40_TEMP_COMP_EN | tmp, 0, true);
         break;
 
     case CONFIG_SET_RATE_2:
@@ -822,7 +825,6 @@
 
     case INIT_ENABLE_DRDY:
         mTask.subState = INIT_DONE;
-        mTask.comm_tx(ST_MAG40_CFG_B_REG_ADDR, ST_MAG40_OFF_CANC, 0, false);
         mTask.comm_tx(ST_MAG40_CFG_C_REG_ADDR,
                     ST_MAG40_BDU_ON | ST_MAG40_INT_MAG, 0, true);
         break;
diff --git a/firmware/os/inc/seos_priv.h b/firmware/os/inc/seos_priv.h
index fab733a..e2dd764 100644
--- a/firmware/os/inc/seos_priv.h
+++ b/firmware/os/inc/seos_priv.h
@@ -119,7 +119,7 @@
 
 static inline bool osTaskIsChre(const struct Task *task)
 {
-    return (task->app->hdr.fwFlags & FL_APP_HDR_CHRE) != 0;
+    return task->app && (task->app->hdr.fwFlags & FL_APP_HDR_CHRE) != 0;
 }
 
 static inline void osTaskMakeNewTid(struct Task *task)
diff --git a/firmware/os/platform/stm32/inc/plat/pwr.h b/firmware/os/platform/stm32/inc/plat/pwr.h
index e142c51..d17b4ec 100644
--- a/firmware/os/platform/stm32/inc/plat/pwr.h
+++ b/firmware/os/platform/stm32/inc/plat/pwr.h
@@ -163,7 +163,7 @@
 #define FLASH_BASE                    0x40023C00UL
 #define DMA1_BASE                     0x40026000UL
 #define DMA2_BASE                     0x40026400UL
-#define DBG_BASE                      0xE0042000UL
+#define DBGMCU_BASE                   0xE0042000UL
 
 
 enum Stm32F4xxSleepType {       //current       power          wkup way       wkup speed   (typ/max)
diff --git a/firmware/os/platform/stm32/platform.c b/firmware/os/platform/stm32/platform.c
index d6f99e1..5c8082c 100644
--- a/firmware/os/platform/stm32/platform.c
+++ b/firmware/os/platform/stm32/platform.c
@@ -45,7 +45,7 @@
 #include <variant/variant.h>
 
 
-struct StmDbg {
+struct StmDbgmcu {
     volatile uint32_t IDCODE;
     volatile uint32_t CR;
     volatile uint32_t APB1FZ;
@@ -92,8 +92,16 @@
     uint8_t unused14[2];
 };
 
+#define TIM2        ((struct StmTim*)TIM2_BASE)
+#define DBGMCU      ((struct StmDbgmcu*)DBGMCU_BASE)
+
 /* RTC bit defintions */
-#define TIM_EGR_UG          0x0001
+#define TIM_EGR_UG  0x0001
+
+/* DBGMCU bit definition */
+#define DBG_SLEEP   0x00000001
+#define DBG_STOP    0x00000002
+#define DBG_STANDBY 0x00000004
 
 
 #ifdef DEBUG_UART_UNITNO
@@ -190,6 +198,8 @@
     gpioBitbangedUartOut(ch);
 #endif
 #if defined(DEBUG_UART_UNITNO)
+    if (ch == '\n')
+        usartPutchar(&mDbgUart, '\r');
     usartPutchar(&mDbgUart, ch);
 #endif
 #if defined(DEBUG_LOG_EVT)
@@ -218,9 +228,7 @@
 
 void platInitialize(void)
 {
-    const uint32_t debugStateInSleepMode = 0x00000007; /* debug in all modes */
-    struct StmTim *tim = (struct StmTim*)TIM2_BASE;
-    struct StmDbg *dbg = (struct StmDbg*)DBG_BASE;
+    const uint32_t debugStateInSleepMode = DBG_SLEEP | DBG_STOP | DBG_STANDBY;
     uint32_t i;
 
     pwrSystemInit();
@@ -263,9 +271,9 @@
 
     /* set up debugging */
 #if defined(DEBUG) && defined(DEBUG_SWD)
-    dbg->CR |= debugStateInSleepMode;
+    DBGMCU->CR |= debugStateInSleepMode;
 #else
-    dbg->CR &=~ debugStateInSleepMode;
+    DBGMCU->CR &=~ debugStateInSleepMode;
 #endif
 
     /* enable MPU */
@@ -273,11 +281,11 @@
 
     /* set up timer used for alarms */
     pwrUnitClock(PERIPH_BUS_APB1, PERIPH_APB1_TIM2, true);
-    tim->CR1 = (tim->CR1 &~ 0x03E1) | 0x0010; //count down mode with no clock division, disabled
-    tim->PSC = 15; // prescale by 16, so that at 16MHz CPU clock, we get 1MHz timer
-    tim->DIER |= 1; // interrupt when updated (underflowed)
-    tim->ARR = 0xffffffff;
-    tim->EGR = TIM_EGR_UG; // force a reload of the prescaler
+    TIM2->CR1 = (TIM2->CR1 &~ 0x03E1) | 0x0010; //count down mode with no clock division, disabled
+    TIM2->PSC = 15; // prescale by 16, so that at 16MHz CPU clock, we get 1MHz timer
+    TIM2->DIER |= 1; // interrupt when updated (underflowed)
+    TIM2->ARR = 0xffffffff;
+    TIM2->EGR = TIM_EGR_UG; // force a reload of the prescaler
     NVIC_EnableIRQ(TIM2_IRQn);
 
     rtcInit();
diff --git a/firmware/os/platform/stm32/wdt.c b/firmware/os/platform/stm32/wdt.c
index b3c785f..0bf7ed9 100644
--- a/firmware/os/platform/stm32/wdt.c
+++ b/firmware/os/platform/stm32/wdt.c
@@ -18,6 +18,13 @@
 #include <plat/wdt.h>
 #include <plat/cmsis.h>
 
+struct StmDbgmcu {
+    volatile uint32_t IDCODE;
+    volatile uint32_t CR;
+    volatile uint32_t APB1FZ;
+    volatile uint32_t APB2FZ;
+};
+
 struct StmWwdg {
     volatile uint16_t CR;
     uint8_t unused0[2];
@@ -27,21 +34,25 @@
     uint8_t unused2[2];
 };
 
-#define WWDG ((struct StmWwdg*)WWDG_BASE)
+#define DBGMCU              ((struct StmDbgmcu*)DBGMCU_BASE)
+#define WWDG                ((struct StmWwdg*)WWDG_BASE)
+
+/* DBGMCU bit definitions */
+#define DBG_WWDG_STOP       0x00000800U
 
 /* WWDG bit definitions */
-#define WWDG_CR_ENABLE 0x80
+#define WWDG_CR_ENABLE      0x80
 
-#define WWDG_TCNT_HIGH 0x40
-#define WWDG_TCNT_MASK 0x3F
+#define WWDG_TCNT_HIGH      0x40
+#define WWDG_TCNT_MASK      0x3F
 
-#define WWDG_CFR_DIV2 0x0080
-#define WWDG_CFR_DIV4 0x0100
-#define WWDG_CFR_DIV8 0x0180
-#define WWDG_CFR_EWI  0x0200
+#define WWDG_CFR_DIV2       0x0080
+#define WWDG_CFR_DIV4       0x0100
+#define WWDG_CFR_DIV8       0x0180
+#define WWDG_CFR_EWI        0x0200
 
 /* WWDG parameters */
-#define WWDG_WINDOW_SIZE 0x3F // 0 < x <= 0x3F
+#define WWDG_WINDOW_SIZE    0x3F // 0 < x <= 0x3F
 
 void WWDG_IRQHandler(void);
 void __attribute__((naked)) WWDG_IRQHandler(void)
@@ -74,6 +85,11 @@
 
 void wdtInit()
 {
+#if defined(DEBUG) && defined(DEBUG_SWD)
+    // Disable WWDG if core is halted
+    DBGMCU->APB1FZ |= DBG_WWDG_STOP;
+#endif
+
     wdtEnableClk();
     WWDG->CFR = WWDG_CFR_EWI | WWDG_CFR_DIV8 | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK);
     WWDG->CR  = WWDG_CR_ENABLE | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK);