diff --git a/cc3200/bootmgr/main.c b/cc3200/bootmgr/main.c index c7c149d217..c1a64b84ad 100644 --- a/cc3200/bootmgr/main.c +++ b/cc3200/bootmgr/main.c @@ -148,7 +148,7 @@ static void bootmgr_board_init(void) { // Mandatory MCU Initialization PRCMCC3200MCUInit(); - mperror_check_reset_cause(); + mperror_bootloader_check_reset_cause(); // Enable the Data Hashing Engine HASH_Init(); @@ -156,9 +156,8 @@ static void bootmgr_board_init(void) { // Init the system led and the system switch mperror_init0(); - // clear the safe boot request, since we should not trust - // the register's state after reset - mperror_clear_safe_boot(); + // clear the safe boot flag, since we can't trust its content after reset + PRCMClearSafeBootRequest(); } //***************************************************************************** @@ -266,7 +265,7 @@ static void bootmgr_image_loader(sBootInfo_t *psBootInfo) { // turn the led off MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0); // request a safe boot to the application - mperror_request_safe_boot(); + PRCMRequestSafeBoot(); } // do we have a new update image that needs to be verified? else if ((psBootInfo->ActiveImg == IMG_ACT_UPDATE) && (psBootInfo->Status == IMG_STATUS_CHECK)) { diff --git a/cc3200/hal/prcm.c b/cc3200/hal/prcm.c index 78b8d8276f..a7cab502fa 100644 --- a/cc3200/hal/prcm.c +++ b/cc3200/hal/prcm.c @@ -98,11 +98,8 @@ #define RTC_SECS_IN_U64MSEC(u64Msec) ((unsigned long)(u64Msec >> 10)) #define RTC_MSEC_IN_U64MSEC(u64Msec) ((unsigned short)(u64Msec & 0x3FF)) +#define RTC_MSEC_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2) #define RTC_SECS_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3) -#define RTC_MSEC_U16_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2+2) - -#define RTC_U32SECS_REG (HWREG(RTC_SECS_U32_REG_ADDR)) -#define RTC_U16MSEC_REG (*(unsigned short*)RTC_MSEC_U16_REG_ADDR) //***************************************************************************** // Register Access and Updates @@ -110,14 +107,16 @@ // Tick of SCC has a resolution of 32768Hz. Therefore, scaling SCC value by 32 // yields ~1 msec resolution. All operations of SCC in RTC context use ms unit. //***************************************************************************** -#define SCC_U64MSEC_GET() (PRCMSlowClkCtrGet() >> 5) -#define SCC_U64MSEC_MATCH_SET(u64Msec) (PRCMSlowClkCtrMatchSet(u64Msec << 5)) -#define SCC_U64MSEC_MATCH_GET() (PRCMSlowClkCtrMatchGet() >> 5) +#define SCC_U64MSEC_GET() (MAP_PRCMSlowClkCtrGet() >> 5) +#define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5)) +#define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5) //***************************************************************************** // // Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used. -// Bits: 30 to 26 are reserved, available to software for use +// Bit: 30 is used to indicate that a safe boot should be performed +// bit: 29 is used to indicate that the last reset was caused by the WDT +// Bits: 28 to 26 are unused // Bits: 25 to 16 are used to save millisecond part of RTC reference. // Bits: 15 to 0 are being used for HW Changes / ECO // @@ -130,11 +129,21 @@ static void RTCUseSet(void) { unsigned short usRegValue; - usRegValue = RTC_U16MSEC_REG | (1 << 15); + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 31); - UtilsDelay((80*200)/3); + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); +} - RTC_U16MSEC_REG = usRegValue; +//***************************************************************************** +// Clear RTC USE Bit +//***************************************************************************** +static void RTCUseClear(void) +{ + unsigned short usRegValue; + + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 31)); + + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); } //***************************************************************************** @@ -142,13 +151,7 @@ static void RTCUseSet(void) //***************************************************************************** static tBoolean IsRTCUsed(void) { - unsigned short usRegValue; - - usRegValue = RTC_U16MSEC_REG; - - UtilsDelay((80*200)/3); - - return ((usRegValue & (1 << 15))? true : false); + return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 31)) ? true : false; } //***************************************************************************** @@ -156,13 +159,7 @@ static tBoolean IsRTCUsed(void) //***************************************************************************** static unsigned short RTCU16MSecRegRead(void) { - unsigned short usRegValue; - - usRegValue = RTC_U16MSEC_REG; - - UtilsDelay((80*200)/3); - - return (usRegValue & 0x3FF); + return ((MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) >> 16) & 0x03FF); } //***************************************************************************** @@ -172,11 +169,11 @@ static void RTCU16MSecRegWrite(unsigned short u16Msec) { unsigned short usRegValue; - usRegValue = RTC_U16MSEC_REG; + // read the whole register and clear the msec bits + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(0x03FF << 16)); - UtilsDelay((80*200)/3); - - RTC_U16MSEC_REG = ((usRegValue & ~0x3FF) |u16Msec); + // write the msec bits only + MAP_PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue | ((u16Msec & 0x03FF) << 16)); } //***************************************************************************** @@ -184,7 +181,7 @@ static void RTCU16MSecRegWrite(unsigned short u16Msec) //***************************************************************************** static unsigned long RTCU32SecRegRead(void) { - return (PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR)); + return (MAP_PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR)); } //***************************************************************************** @@ -192,7 +189,7 @@ static unsigned long RTCU32SecRegRead(void) //***************************************************************************** static void RTCU32SecRegWrite(unsigned long u32Msec) { - PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec); + MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec); } //***************************************************************************** @@ -200,6 +197,7 @@ static void RTCU32SecRegWrite(unsigned long u32Msec) //***************************************************************************** #define IS_RTC_USED() IsRTCUsed() #define RTC_USE_SET() RTCUseSet() +#define RTC_USE_CLR() RTCUseClear() #define RTC_U16MSEC_REG_RD() RTCU16MSecRegRead() #define RTC_U16MSEC_REG_WR(u16Msec) RTCU16MSecRegWrite(u16Msec) @@ -239,6 +237,98 @@ static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] = }; +//***************************************************************************** +// +//! Requests a safe boot +//! +//! \return None. +// +//***************************************************************************** +void PRCMRequestSafeBoot(void) +{ + unsigned short usRegValue; + + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 30); + + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); +} + +//***************************************************************************** +// +//! Clear the safe boot request +//! +//! \return None. +// +//***************************************************************************** +void PRCMClearSafeBootRequest(void) +{ + unsigned short usRegValue; + + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 30)); + + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); +} + +//***************************************************************************** +// +//! Read the safe boot request bit. This bit is cleared after reading. +//! +//! \return Value of the safe boot bit +// +//***************************************************************************** +tBoolean PRCMIsSafeBootRequested(void) +{ + tBoolean safeboot = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 30)) ? true : false; + + PRCMClearSafeBootRequest(); + + return safeboot; +} + +//***************************************************************************** +// +//! Signals that a WDT reset has occurred +//! +//! \return None. +// +//***************************************************************************** +void PRCMSignalWDTReset(void) +{ + unsigned short usRegValue; + + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 29); + + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); +} + +//***************************************************************************** +// +//! Clear the WDT reset signal +//! +//! \return None. +// +//***************************************************************************** +void PRCMClearWDTResetSignal(void) +{ + unsigned short usRegValue; + + usRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 29)); + + PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, usRegValue); +} + +//***************************************************************************** +// +//! Read the WDT reset signal bit +//! +//! \return Value of the WDT reset signal bit +// +//***************************************************************************** +tBoolean PRCMWasResetBecauseOfWDT(void) +{ + return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 29)) ? true : false; +} + //***************************************************************************** // //! Performs a software reset of a SOC @@ -304,7 +394,7 @@ void PRCMMCUReset(tBoolean bIncludeSubsystem) //! \return Returns one of the cause defined above. // //***************************************************************************** -unsigned long PRCMSysResetCauseGet() +unsigned long PRCMSysResetCauseGet(void) { unsigned long ulWakeupStatus; @@ -318,7 +408,7 @@ unsigned long PRCMSysResetCauseGet() // if(ulWakeupStatus == PRCM_POWER_ON) { - if(PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1) + if(MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1) { ulWakeupStatus = PRCM_HIB_EXIT; } @@ -349,8 +439,7 @@ unsigned long PRCMSysResetCauseGet() //! \return None. // //***************************************************************************** -void -PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags) +void PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags) { // // Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC @@ -386,8 +475,7 @@ PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags) //! \return None. // //***************************************************************************** -void -PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags) +void PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags) { // // Disable the specified peripheral clocks @@ -409,8 +497,7 @@ PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags) //! \return Returns input clock frequency for specified peripheral. // //***************************************************************************** -unsigned long -PRCMPeripheralClockGet(unsigned long ulPeripheral) +unsigned long PRCMPeripheralClockGet(unsigned long ulPeripheral) { unsigned long ulClockFreq; unsigned long ulHiPulseDiv; @@ -462,8 +549,7 @@ PRCMPeripheralClockGet(unsigned long ulPeripheral) //! \return None. // //***************************************************************************** -void -PRCMPeripheralReset(unsigned long ulPeripheral) +void PRCMPeripheralReset(unsigned long ulPeripheral) { volatile unsigned long ulDelay; @@ -503,8 +589,7 @@ PRCMPeripheralReset(unsigned long ulPeripheral) //! \return Returns \b true if the peripheral is ready, \b false otherwise. // //***************************************************************************** -tBoolean -PRCMPeripheralStatusGet(unsigned long ulPeripheral) +tBoolean PRCMPeripheralStatusGet(unsigned long ulPeripheral) { unsigned long ReadyBit; @@ -546,8 +631,7 @@ PRCMPeripheralStatusGet(unsigned long ulPeripheral) //! \return None. // //***************************************************************************** -void -PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq) +void PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq) { unsigned long long ullDiv; unsigned short usInteger; @@ -577,8 +661,7 @@ PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq) //! \return None. // //***************************************************************************** -void -PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr) +void PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr) { // // Set The SP Value @@ -602,8 +685,7 @@ PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr) //! \return None. // //***************************************************************************** -void -PRCMLPDSEnter() +void PRCMLPDSEnter(void) { // // Disable TestPD @@ -642,8 +724,7 @@ PRCMLPDSEnter() //! \return None. // //***************************************************************************** -void -PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc) +void PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc) { unsigned long ulRegVal; @@ -678,8 +759,7 @@ PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc) //! \return None. // //***************************************************************************** -void -PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc) +void PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc) { HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc; } @@ -695,8 +775,7 @@ PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc) //! PRCMLPDSWakeupSourceEnable(). // //***************************************************************************** -unsigned long -PRCMLPDSWakeupCauseGet() +unsigned long PRCMLPDSWakeupCauseGet(void) { return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC)); } @@ -714,8 +793,7 @@ PRCMLPDSWakeupCauseGet() //! \return Returns \b true on success, \b false otherwise. // //***************************************************************************** -void -PRCMLPDSIntervalSet(unsigned long ulTicks) +void PRCMLPDSIntervalSet(unsigned long ulTicks) { // // Check sleep is atleast for 21 cycles @@ -759,13 +837,12 @@ PRCMLPDSIntervalSet(unsigned long ulTicks) //! \return None. // //***************************************************************************** -void -PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType) +void PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType) { // // Set the wakeup GPIO // - PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin); + MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin); // // Set the trigger type. @@ -785,8 +862,7 @@ PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType) //! \return None. // //***************************************************************************** -void -PRCMSleepEnter() +void PRCMSleepEnter(void) { // // Request Sleep @@ -806,8 +882,7 @@ PRCMSleepEnter() //! \return None. // //***************************************************************************** -void -PRCMDeepSleepEnter() +void PRCMDeepSleepEnter(void) { // // Set bandgap duty cycle to 1 @@ -857,8 +932,7 @@ PRCMDeepSleepEnter() //! \return None. // //**************************************************************************** -void -PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags) +void PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags) { if(ulModeFlags & PRCM_SRAM_DSLP_RET) { @@ -902,8 +976,7 @@ PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags) //! \return None. // //**************************************************************************** -void -PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags) +void PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags) { if(ulFlags & PRCM_SRAM_DSLP_RET) { @@ -944,15 +1017,14 @@ PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags) //! \return None. // //***************************************************************************** -void -PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc) +void PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc) { unsigned long ulRegValue; // // Read the RTC register // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN); // // Enable the RTC as wakeup source if specified @@ -962,12 +1034,12 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc) // // Enable HIB wakeup sources // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); // // REad the GPIO wakeup configuration register // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN); // // Enable the specified GPIOs a wakeup sources @@ -977,7 +1049,7 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc) // // Write the new register configuration // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue); } //***************************************************************************** @@ -993,15 +1065,14 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc) //! \return None. // //***************************************************************************** -void -PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc) +void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc) { unsigned long ulRegValue; // // Read the RTC register // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN); // // Disable the RTC as wakeup source if specified @@ -1011,12 +1082,12 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc) // // Disable HIB wakeup sources // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); // // Read the GPIO wakeup configuration register // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN); // // Enable the specified GPIOs a wakeup sources @@ -1026,7 +1097,7 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc) // // Write the new register configuration // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue); } @@ -1040,10 +1111,9 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc) //! \b PRCM_HIB_WAKEUP_CAUSE_GPIO // //***************************************************************************** -unsigned long -PRCMHibernateWakeupCauseGet() +unsigned long PRCMHibernateWakeupCauseGet(void) { - return ((PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF); + return ((MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF); } //***************************************************************************** @@ -1057,22 +1127,21 @@ PRCMHibernateWakeupCauseGet() //! \return Returns \b true on success, \b false otherwise. // //***************************************************************************** -void -PRCMHibernateIntervalSet(unsigned long long ullTicks) +void PRCMHibernateIntervalSet(unsigned long long ullTicks) { unsigned long long ullRTCVal; // // Latch the RTC vlaue // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1); // // Read latched values as 2 32-bit vlaues // - ullRTCVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW); + ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW); ullRTCVal = ullRTCVal << 32; - ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW); + ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW); // // Add the interval @@ -1082,9 +1151,9 @@ PRCMHibernateIntervalSet(unsigned long long ullTicks) // // Set RTC match value // - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF, + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF, (unsigned long)(ullRTCVal)); - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF, + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF, (unsigned long)(ullRTCVal>>32)); } @@ -1119,8 +1188,7 @@ PRCMHibernateIntervalSet(unsigned long long ullTicks) //! \return None. // //***************************************************************************** -void -PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType) +void PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType) { unsigned char ucLoop; unsigned long ulRegValue; @@ -1137,9 +1205,9 @@ PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType) { if(ulGPIOBitMap & (1<>32)); } @@ -1233,16 +1299,16 @@ void PRCMSlowClkCtrMatchSet(unsigned long long ullValue) //! \return None. // //***************************************************************************** -unsigned long long PRCMSlowClkCtrMatchGet() +unsigned long long PRCMSlowClkCtrMatchGet(void) { unsigned long long ullValue; // // Get RTC match value // - ullValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF); + ullValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF); ullValue = ullValue<<32; - ullValue |= PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF); + ullValue |= MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF); // // Return the value @@ -1265,7 +1331,7 @@ unsigned long long PRCMSlowClkCtrMatchGet() //***************************************************************************** void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue) { - PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue); } //***************************************************************************** @@ -1285,7 +1351,7 @@ unsigned long PRCMOCRRegisterRead(unsigned char ucIndex) // // Return the read value. // - return PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2)); + return MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2)); } //***************************************************************************** @@ -1326,7 +1392,7 @@ void PRCMIntRegister(void (*pfnHandler)(void)) //! \return None. // //***************************************************************************** -void PRCMIntUnregister() +void PRCMIntUnregister(void) { // // Enable the UART interrupt. @@ -1368,9 +1434,9 @@ void PRCMIntEnable(unsigned long ulIntFlags) // // Enable RTC interrupt // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); ulRegValue |= 0x1; - PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue); } } @@ -1404,9 +1470,9 @@ void PRCMIntDisable(unsigned long ulIntFlags) // // Disable RTC interrupt // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); ulRegValue &= ~0x1; - PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue); + MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue); } } @@ -1420,7 +1486,7 @@ void PRCMIntDisable(unsigned long ulIntFlags) //! \return Returns the current interrupt status. // //***************************************************************************** -unsigned long PRCMIntStatus() +unsigned long PRCMIntStatus(void) { return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS); } @@ -1437,15 +1503,25 @@ unsigned long PRCMIntStatus() //! register is not available to user. Also, users must not excercise the Slow //! Clock Counter API(s), if RTC has been set for use. //! -//! The RTC feature, if set or marked, can be only reset either through reboot -//! or power cycle. +//! \return None. +// +//***************************************************************************** +void PRCMRTCInUseSet(void) +{ + RTC_USE_SET(); + return; +} + +//***************************************************************************** +// +//! Clear the function of RTC as being used //! //! \return None. // //***************************************************************************** -void PRCMRTCInUseSet() +void PRCMRTCInUseClear(void) { - RTC_USE_SET(); + RTC_USE_CLR(); return; } @@ -1466,7 +1542,7 @@ void PRCMRTCInUseSet() //! \return None. // //***************************************************************************** -tBoolean PRCMRTCInUseGet() +tBoolean PRCMRTCInUseGet(void) { return IS_RTC_USED()? true : false; } @@ -1616,7 +1692,7 @@ void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec) //! \return None // //***************************************************************************** -void PRCMCC3200MCUInit() +void PRCMCC3200MCUInit(void) { unsigned long ulRegValue; @@ -1627,11 +1703,11 @@ void PRCMCC3200MCUInit() // // Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled, - // any hibernate wakeup source will be kept maked until the device enters + // any hibernate wakeup source will be kept masked until the device enters // hibernate completely (analog + digital) // - ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0); - PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4)); + ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0); + MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4)); // // Handling the clock switching (for 1.32 only) diff --git a/cc3200/hal/prcm.h b/cc3200/hal/prcm.h index 0caa666ee6..16090980dd 100644 --- a/cc3200/hal/prcm.h +++ b/cc3200/hal/prcm.h @@ -197,6 +197,12 @@ unsigned char ulRstReg; // API Function prototypes // //***************************************************************************** +extern void PRCMRequestSafeBoot(void); +extern void PRCMClearSafeBootRequest(void); +extern tBoolean PRCMIsSafeBootRequested(void); +extern void PRCMSignalWDTReset(void); +extern void PRCMClearWDTResetSignal(void); +extern tBoolean PRCMWasResetBecauseOfWDT(void); extern void PRCMSOCReset(void); extern void PRCMMCUReset(tBoolean bIncludeSubsystem); extern unsigned long PRCMSysResetCauseGet(void); @@ -250,6 +256,7 @@ extern void PRCMIntEnable(unsigned long ulIntFlags); extern void PRCMIntDisable(unsigned long ulIntFlags); extern unsigned long PRCMIntStatus(void); extern void PRCMRTCInUseSet(void); +extern void PRCMRTCInUseClear(void); extern tBoolean PRCMRTCInUseGet(void); extern void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec); extern void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec); diff --git a/cc3200/hal/rom_patch.h b/cc3200/hal/rom_patch.h index 6ca366b0f6..9855e7c341 100644 --- a/cc3200/hal/rom_patch.h +++ b/cc3200/hal/rom_patch.h @@ -46,7 +46,6 @@ #undef ROM_IntEnable #undef ROM_IntDisable #undef ROM_IntPendSet -#undef ROM_PRCMHibernateWakeUpGPIOSelect #undef ROM_SDHostCardErrorMaskSet #undef ROM_SDHostCardErrorMaskGet #undef ROM_TimerConfigure diff --git a/cc3200/misc/mperror.c b/cc3200/misc/mperror.c index a1c35421e8..85ed0a6466 100644 --- a/cc3200/misc/mperror.c +++ b/cc3200/misc/mperror.c @@ -56,8 +56,6 @@ #define MPERROR_HEARTBEAT_ON_MS (80) #define MPERROR_HEARTBEAT_OFF_MS (4920) -#define MPERROR_SAFE_BOOT_REG_IDX (0) - /****************************************************************************** DECLARE PRIVATE DATA ******************************************************************************/ @@ -102,7 +100,7 @@ void mperror_init0 (void) { mperror_heart_beat.beating = false; } -void mperror_check_reset_cause (void) { +void mperror_bootloader_check_reset_cause (void) { // if we are recovering from a WDT reset, trigger // a hibernate cycle for a clean boot if (MAP_PRCMSysResetCauseGet() == PRCM_WDT_RESET) { @@ -115,6 +113,10 @@ void mperror_check_reset_cause (void) { UtilsDelay(800); HWREG(0x4402F024) &= 0xF7FFFFFF; + // since the reset cause will be changed, we must store the right reason + // so that the application knows we booting the next time + PRCMSignalWDTReset(); + MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); // set the sleep interval to 10ms MAP_PRCMHibernateIntervalSet(330); @@ -136,21 +138,6 @@ void mperror_signal_error (void) { } } -void mperror_request_safe_boot (void) { - MAP_PRCMOCRRegisterWrite(MPERROR_SAFE_BOOT_REG_IDX, 1); -} - -void mperror_clear_safe_boot (void) { - MAP_PRCMOCRRegisterWrite(MPERROR_SAFE_BOOT_REG_IDX, 0); -} - -// returns the last state of the safe boot request and clears the register -bool mperror_safe_boot_requested (void) { - bool ret = MAP_PRCMOCRRegisterRead(MPERROR_SAFE_BOOT_REG_IDX); - mperror_clear_safe_boot(); - return ret; -} - void mperror_enable_heartbeat (void) { mperror_heart_beat.enabled = true; } diff --git a/cc3200/misc/mperror.h b/cc3200/misc/mperror.h index 1cc043fe98..06dd549496 100644 --- a/cc3200/misc/mperror.h +++ b/cc3200/misc/mperror.h @@ -35,12 +35,9 @@ extern const mp_obj_base_t pyb_heartbeat_obj; extern void NORETURN __fatal_error(const char *msg); void mperror_init0 (void); -void mperror_check_reset_cause (void); +void mperror_bootloader_check_reset_cause (void); void mperror_deinit_sfe_pin (void); void mperror_signal_error (void); -void mperror_request_safe_boot (void); -void mperror_clear_safe_boot (void); -bool mperror_safe_boot_requested (void); void mperror_enable_heartbeat (void); void mperror_disable_heartbeat (void); void mperror_heartbeat_signal (void); diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c index 13c787cc4e..714019ceb9 100644 --- a/cc3200/mods/modpyb.c +++ b/cc3200/mods/modpyb.c @@ -278,7 +278,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { #endif #if MICROPY_HW_ENABLE_RTC - { MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type }, diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c index 253dca4783..010db9cf64 100644 --- a/cc3200/mods/modwlan.c +++ b/cc3200/mods/modwlan.c @@ -911,7 +911,7 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan); -/// \method callback(method, intmode, value, priority, pwrmode) +/// \method callback(handler, intmode, value, priority, pwrmode) /// Creates a callback object associated with WLAN /// min num of arguments is 1 (pwrmode) STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c index 5744662018..b71a06cbf6 100644 --- a/cc3200/mods/pybrtc.c +++ b/cc3200/mods/pybrtc.c @@ -38,6 +38,8 @@ #include "rom_map.h" #include "prcm.h" #include "pybrtc.h" +#include "pybsleep.h" +#include "mpcallback.h" /// \moduleref pyb /// \class RTC - real time clock @@ -51,6 +53,25 @@ /// rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0)) /// print(rtc.datetime()) +/****************************************************************************** + DECLARE TYPES + ******************************************************************************/ +typedef struct { + mp_obj_t callback; + uint32_t alarm_sec; + uint16_t alarm_msec; + uint8_t pwrmode; +} pybrtc_data_t; + +/****************************************************************************** + DECLARE PRIVATE DATA + ******************************************************************************/ +STATIC pybrtc_data_t pybrtc_data = {.callback = mp_const_none}; +STATIC const mp_cb_methods_t pybrtc_cb_methods; + +/****************************************************************************** + DECLARE PUBLIC FUNCTIONS + ******************************************************************************/ __attribute__ ((section (".boot"))) void pybrtc_init(void) { // if the RTC was previously set, leave it alone @@ -60,32 +81,28 @@ void pybrtc_init(void) { // set the time to 00:00:00 uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0); - MAP_PRCMRTCSet(seconds, 0); - - // Mark the RTC in use + // Mark the RTC in use first MAP_PRCMRTCInUseSet(); + + // Now set the RTC calendar seconds + MAP_PRCMRTCSet(seconds, 0); } } +/****************************************************************************** + DECLARE PRIVATE FUNCTIONS + ******************************************************************************/ +STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) { + +} + +STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) { + +} + /******************************************************************************/ // Micro Python bindings -typedef struct _pyb_rtc_obj_t { - mp_obj_base_t base; -} pyb_rtc_obj_t; - -STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}}; - -/// \classmethod \constructor() -/// Create an RTC object. -STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); - - // return constant object - return (mp_obj_t)&pyb_rtc_obj; -} - /// \method datetime([datetimetuple]) /// Get or set the date and time of the RTC. /// @@ -144,14 +161,64 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime); +/// \method callback(handler, intmode, value, priority, pwrmode) +/// Creates a callback object associated with the real time clock +/// min num of arguments is 1 (value). The value is the alarm time +/// in the future, in msec +STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_val_t args[mpcallback_INIT_NUM_ARGS]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args); + + // check if any parameters were passed + if (kw_args->used > 0 || pybrtc_data.callback == mp_const_none) { + uint32_t seconds; + uint16_t mseconds; + // get the seconds and the milliseconds from the RTC + MAP_PRCMRTCGet(&seconds, &mseconds); + mseconds = RTC_CYCLES_U16MS(mseconds); + + // configure the rtc alarm accordingly + seconds += args[3].u_int / 1000; + mseconds += args[3].u_int - ((args[3].u_int / 1000) * 1000); + if (mseconds > 1000) { + seconds++; + mseconds -= 1000; + } + + // check the wake from param + if (args[4].u_int & PYB_PWR_MODE_ACTIVE) { + MAP_PRCMRTCMatchSet(seconds, mseconds); + } + + // save the alarm config for later + pybrtc_data.alarm_sec = seconds; + pybrtc_data.alarm_msec = mseconds; + pybrtc_data.pwrmode = args[4].u_int; + + // create the callback + pybrtc_data.callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods); + } + + return pybrtc_data.callback; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_callback_obj, 1, pyb_rtc_callback); + STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj }, }; STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table); -const mp_obj_type_t pyb_rtc_type = { +STATIC const mp_obj_type_t pyb_rtc_type = { { &mp_type_type }, .name = MP_QSTR_RTC, - .make_new = pyb_rtc_make_new, .locals_dict = (mp_obj_t)&pyb_rtc_locals_dict, }; + +STATIC const mp_cb_methods_t pybrtc_cb_methods = { + .init = pyb_rtc_callback, + .enable = pyb_rtc_callback_enable, + .disable = pyb_rtc_callback_disable, +}; + +const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type}; diff --git a/cc3200/mods/pybrtc.h b/cc3200/mods/pybrtc.h index 5f1ff654d7..a41cff772e 100644 --- a/cc3200/mods/pybrtc.h +++ b/cc3200/mods/pybrtc.h @@ -31,7 +31,7 @@ #define RTC_U16MS_CYCLES(msec) ((msec * 1024) / 1000) #define RTC_CYCLES_U16MS(cycles) ((cycles * 1000) / 1024) -extern const mp_obj_type_t pyb_rtc_type; +extern const mp_obj_base_t pyb_rtc_obj; void pybrtc_init(void); diff --git a/cc3200/mods/pybsleep.c b/cc3200/mods/pybsleep.c index bbaeddefb5..e0df2c1ce4 100644 --- a/cc3200/mods/pybsleep.c +++ b/cc3200/mods/pybsleep.c @@ -61,6 +61,12 @@ #define SPIFLASH_INSTR_DEEP_POWER_DOWN (0xB9) #define SPIFLASH_STATUS_BUSY (0x01) +#define LPDS_UP_TIME (425) // 13 msec +#define LPDS_DOWN_TIME (98) // 3 msec +#define USER_OFFSET (131) // 4 smec +#define WAKEUP_TIME_LPDS (LPDS_UP_TIME + LPDS_DOWN_TIME + USER_OFFSET) // 20 msec +#define WAKEUP_TIME_HIB (32768) // 1 s + /****************************************************************************** DECLARE PRIVATE TYPES ******************************************************************************/ @@ -101,9 +107,9 @@ typedef struct { } pybsleep_obj_t; typedef struct { - mp_obj_t wlan_wake_cb; - mp_obj_t timer_wake_cb; - mp_obj_t gpio_wake_cb; + mp_obj_t wlan_lpds_wake_cb; + mp_obj_t timer_lpds_wake_cb; + mp_obj_t gpio_lpds_wake_cb; } pybsleep_wake_cb_t; /****************************************************************************** @@ -113,6 +119,7 @@ STATIC const mp_obj_type_t pybsleep_type; STATIC nvic_reg_store_t *nvic_reg_store; STATIC pybsleep_wake_cb_t pybsleep_wake_cb; volatile arm_cm4_core_regs_t vault_arm_registers; +STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET; /****************************************************************************** DECLARE PRIVATE FUNCTIONS @@ -128,17 +135,49 @@ STATIC void pybsleep_iopark (void); /****************************************************************************** DEFINE PUBLIC FUNCTIONS ******************************************************************************/ -void pyblsleep_init0 (void) { +__attribute__ ((section (".boot"))) +void pybsleep_pre_init (void) { + // allocate memory for nvic registers vault + ASSERT ((nvic_reg_store = mem_Malloc(sizeof(nvic_reg_store_t))) != NULL); +} + +void pybsleep_init0 (void) { // initialize the sleep objects list mp_obj_list_init(&MP_STATE_PORT(pybsleep_obj_list), 0); - // allocate memory for nvic registers vault - ASSERT ((nvic_reg_store = mem_Malloc(sizeof(nvic_reg_store_t))) != NULL); - - // enable and register the PRCM interrupt + // register and enable the PRCM interrupt osi_InterruptRegister(INT_PRCM, (P_OSI_INTR_ENTRY)PRCMInterruptHandler, INT_PRIORITY_LVL_1); - MAP_IntPendClear(INT_PRCM); - MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR); + + // store the reset casue (if it's soft reset, leave it as it is) + if (pybsleep_reset_cause != PYB_SLP_SOFT_RESET) { + switch (MAP_PRCMSysResetCauseGet()) { + case PRCM_POWER_ON: + pybsleep_reset_cause = PYB_SLP_PWRON_RESET; + break; + case PRCM_CORE_RESET: + case PRCM_MCU_RESET: + case PRCM_SOC_RESET: + pybsleep_reset_cause = PYB_SLP_HARD_RESET; + break; + case PRCM_WDT_RESET: + pybsleep_reset_cause = PYB_SLP_WDT_RESET; + break; + case PRCM_HIB_EXIT: + if (PRCMWasResetBecauseOfWDT()) { + pybsleep_reset_cause = PYB_SLP_WDT_RESET; + } + else { + pybsleep_reset_cause = PYB_SLP_HIB_RESET; + } + break; + default: + break; + } + } +} + +void pybsleep_signal_soft_reset (void) { + pybsleep_reset_cause = PYB_SLP_SOFT_RESET; } void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup) { @@ -160,15 +199,15 @@ void pybsleep_remove (const mp_obj_t obj) { } void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj) { - pybsleep_wake_cb.wlan_wake_cb = cb_obj; + pybsleep_wake_cb.wlan_lpds_wake_cb = cb_obj; } void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj) { - pybsleep_wake_cb.gpio_wake_cb = cb_obj; + pybsleep_wake_cb.gpio_lpds_wake_cb = cb_obj; } void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj) { - pybsleep_wake_cb.timer_wake_cb = cb_obj; + pybsleep_wake_cb.timer_lpds_wake_cb = cb_obj; } /****************************************************************************** @@ -341,31 +380,27 @@ void pybsleep_suspend_exit (void) { STATIC void PRCMInterruptHandler (void) { // reading the interrupt status automatically clears the interrupt if (PRCM_INT_SLOW_CLK_CTR == MAP_PRCMIntStatus()) { - if (pybsleep_wake_cb.timer_wake_cb) { - mpcallback_handler(pybsleep_wake_cb.timer_wake_cb); + // this interrupt is triggered during active mode + if (pybsleep_wake_cb.timer_lpds_wake_cb) { + mpcallback_handler(pybsleep_wake_cb.timer_lpds_wake_cb); } } else { + // interrupt has been triggered while waking up from LPDS switch (MAP_PRCMLPDSWakeupCauseGet()) { case PRCM_LPDS_HOST_IRQ: - if (pybsleep_wake_cb.wlan_wake_cb) { - mpcallback_handler(pybsleep_wake_cb.wlan_wake_cb); + if (pybsleep_wake_cb.wlan_lpds_wake_cb) { + mpcallback_handler(pybsleep_wake_cb.wlan_lpds_wake_cb); } break; case PRCM_LPDS_GPIO: - if (pybsleep_wake_cb.gpio_wake_cb) { - mpcallback_handler(pybsleep_wake_cb.gpio_wake_cb); + if (pybsleep_wake_cb.gpio_lpds_wake_cb) { + mpcallback_handler(pybsleep_wake_cb.gpio_lpds_wake_cb); } - // clear all pending GPIO interrupts in order to - // avoid duplicated calls to the handler - MAP_IntPendClear(INT_GPIOA0); - MAP_IntPendClear(INT_GPIOA1); - MAP_IntPendClear(INT_GPIOA2); - MAP_IntPendClear(INT_GPIOA3); break; case PRCM_LPDS_TIMER: - if (pybsleep_wake_cb.timer_wake_cb) { - mpcallback_handler(pybsleep_wake_cb.timer_wake_cb); + if (pybsleep_wake_cb.timer_lpds_wake_cb) { + mpcallback_handler(pybsleep_wake_cb.timer_lpds_wake_cb); } break; default: @@ -443,7 +478,7 @@ STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) { nlr_buf_t nlr; // check if we need to enable network wake-up - if (pybsleep_wake_cb.wlan_wake_cb) { + if (pybsleep_wake_cb.wlan_lpds_wake_cb) { MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ); } else { @@ -466,7 +501,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_suspend_obj, pyb_sleep_suspend); /// \function hibernate() /// Enters hibernate mode. Wake up sources should have been enable prior to -// calling this method. +/// calling this method. STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) { wlan_stop(); pybsleep_flash_powerdown(); @@ -475,16 +510,40 @@ STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_hibernate_obj, pyb_sleep_hibernate); +/// \function reset_cause() +/// Returns the last reset casue +STATIC mp_obj_t pyb_sleep_reset_cause (mp_obj_t self_in) { + return MP_OBJ_NEW_SMALL_INT(pybsleep_reset_cause); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_reset_cause_obj, pyb_sleep_reset_cause); + +/// \function wake_reason() +/// Returns the wake up reson from ldps or hibernate +STATIC mp_obj_t pyb_sleep_wake_reason (mp_obj_t self_in) { + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_wake_reason_obj, pyb_sleep_wake_reason); + STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = { // instance methods { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_sleep_idle_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_suspend), (mp_obj_t)&pyb_sleep_suspend_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&pyb_sleep_reset_cause_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&pyb_sleep_wake_reason_obj }, // class constants { MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) }, { MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PWR_ON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HIB_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_PIN) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) }, }; STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table); diff --git a/cc3200/mods/pybsleep.h b/cc3200/mods/pybsleep.h index 5abb49be80..17833669b1 100644 --- a/cc3200/mods/pybsleep.h +++ b/cc3200/mods/pybsleep.h @@ -37,6 +37,22 @@ /****************************************************************************** DEFINE TYPES ******************************************************************************/ +typedef enum { + PYB_SLP_PWRON_RESET = 0, + PYB_SLP_HARD_RESET, + PYB_SLP_WDT_RESET, + PYB_SLP_HIB_RESET, + PYB_SLP_SOFT_RESET, + +} pybsleep_reset_cause_t; + +typedef enum { + PYB_SLP_WAKED_BY_WLAN, + PYB_SLP_WAKED_BY_PIN, + PYB_SLP_WAKED_BY_RTC + +} pybsleep_wake_reason_t; + typedef void (*WakeUpCB_t)(const mp_obj_t self); /****************************************************************************** @@ -47,7 +63,9 @@ extern const mp_obj_base_t pyb_sleep_obj; /****************************************************************************** DECLARE FUNCTIONS ******************************************************************************/ -void pyblsleep_init0 (void); +void pybsleep_pre_init (void); +void pybsleep_init0 (void); +void pybsleep_signal_soft_reset (void); void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup); void pybsleep_remove (const mp_obj_t obj); void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj); diff --git a/cc3200/mptask.c b/cc3200/mptask.c index 90576b8e74..bd86da2aa4 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -121,7 +121,7 @@ soft_reset: mperror_init0(); mpexception_init0(); mpcallback_init0(); - pyblsleep_init0(); + pybsleep_init0(); uart_init0(); pin_init0(); readline_init0(); @@ -149,7 +149,7 @@ soft_reset: mptask_enter_ap_mode(); // don't check for safeboot when comming out of hibernate #ifndef DEBUG - safeboot = mperror_safe_boot_requested(); + safeboot = PRCMIsSafeBootRequested(); #endif } else { @@ -233,6 +233,7 @@ soft_reset: soft_reset_exit: // soft reset + pybsleep_signal_soft_reset(); sflash_disk_flush(); @@ -269,6 +270,9 @@ STATIC void mptask_pre_init (void) { // Allocate memory for the flash file system ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL); + // this one allocates memory for the nvic vault + pybsleep_pre_init(); + #if MICROPY_HW_HAS_SDCARD pybsd_init0(); #endif diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index 65ac04680b..386a916b62 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -251,6 +251,17 @@ Q(Sleep) Q(idle) Q(suspend) Q(hibernate) +Q(reset_cause) +Q(wake_reason) Q(ACTIVE) Q(SUSPENDED) Q(HIBERNATING) +Q(PWR_ON_RESET) +Q(HARD_RESET) +Q(WDT_RESET) +Q(HIB_RESET) +Q(SOFT_RESET) +Q(WLAN_WAKE) +Q(PIN_WAKE) +Q(RTC_WAKE) +