//**************************************************************************** // //! \brief Setting various wake sources for the device //! //! \param target is the lowest power mode that the deveice will exercise //! //! \return 0 if success, -1 in case of error // //**************************************************************************** int set_wkup_srcs(enum soc_pm target) { int iRetVal = -1; switch(target) { case e_pm_S0: case e_pm_S1: case e_pm_S2: /* These handle the cases of run, sleep, deepsleep. Wake source is configured outside this scope in individual peripherals */ break; case e_pm_S3: if(lpds_wk_info.wk_type & WK_RTC) { /* Setup the LPDS wake time */ MAP_PRCMLPDSIntervalSet(lpds_wk_info.timer_interval * 32768); /* Enable the wake source to be timer */ MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_TIMER); iRetVal = 0; } if(lpds_wk_info.wk_type & WK_GPIO) { MAP_PRCMLPDSWakeUpGPIOSelect(lpds_wk_info.wk_gpio_pin,lpds_wk_info.trigger_type); MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO); iRetVal = 0; } if(lpds_wk_info.wk_type & WK_HOST_IRQ) { /* Set LPDS Wakeup source as NWP request */ MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_HOST_IRQ); iRetVal = 0; } if(lpds_wk_info.is_periodic == false) { lpds_wk_info.wk_type &= (~WK_RTC); } break; case e_pm_S4: if(hib_wk_info.wk_type & WK_RTC) { /* Setup the LPDS wake time */ MAP_PRCMHibernateIntervalSet(hib_wk_info.timer_interval * 32768); /* Enable the wake source to be timer */ MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); iRetVal = 0; } if(hib_wk_info.wk_type & WK_GPIO) { MAP_PRCMHibernateWakeUpGPIOSelect(hib_wk_info.wk_gpio_pin,hib_wk_info.trigger_type); MAP_PRCMHibernateWakeupSourceEnable(hib_wk_info.wk_gpio_pin); iRetVal = 0; } break; default: return -1; } return iRetVal; }
STATIC void pin_irq_enable (mp_obj_t self_in) { const pin_obj_t *self = self_in; uint hib_pin, idx; pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx); if (idx < PYBPIN_NUM_WAKE_PINS) { if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) { // enable GPIO as a wake source during LPDS MAP_PRCMLPDSWakeUpGPIOSelect(idx, pybpin_wake_pin[idx].lpds); MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO); } if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) { // enable GPIO as a wake source during hibernate MAP_PRCMHibernateWakeUpGPIOSelect(hib_pin, pybpin_wake_pin[idx].hib); MAP_PRCMHibernateWakeupSourceEnable(hib_pin); } else { MAP_PRCMHibernateWakeupSourceDisable(hib_pin); } } // if idx is invalid, the pin supports active interrupts for sure if (idx >= PYBPIN_NUM_WAKE_PINS || pybpin_wake_pin[idx].active) { MAP_GPIOIntClear(self->port, self->bit); MAP_GPIOIntEnable(self->port, self->bit); } // in case it was enabled before else if (idx < PYBPIN_NUM_WAKE_PINS && !pybpin_wake_pin[idx].active) { MAP_GPIOIntDisable(self->port, self->bit); } }
STATIC bool setup_timer_hibernate_wake (void) { uint64_t t_match, t_curr; int64_t t_remaining; // get the time remaining for the RTC timer to expire t_match = MAP_PRCMSlowClkCtrMatchGet(); t_curr = MAP_PRCMSlowClkCtrGet(); // get the time remaining in terms of slow clocks t_remaining = (t_match - t_curr); if (t_remaining > WAKEUP_TIME_HIB) { // subtract the time it takes for wakeup from hibernate t_remaining -= WAKEUP_TIME_HIB; // setup the LPDS wake time MAP_PRCMHibernateIntervalSet((uint32_t)t_remaining); // enable the wake source MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); return true; } // disable the timer as wake source MAP_PRCMLPDSWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR); uint32_t f_seconds; uint16_t f_mseconds; // setup a timer interrupt immediately pyb_rtc_calc_future_time (FORCED_TIMER_INTERRUPT_MS, &f_seconds, &f_mseconds); MAP_PRCMRTCMatchSet(f_seconds, f_mseconds); // LPDS wake by timer was not possible, force an interrupt in active mode instead MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR); return false; }
//**************************************************************************** // //! Enter the HIBernate mode configuring the wakeup timer //! //! \param none //! //! This function //! 1. Sets up the wakeup RTC timer //! 2. Enables the RTC //! 3. Enters into HIBernate //! //! \return None. // //**************************************************************************** void EnterHIBernate() { #define SLOW_CLK_FREQ (32*1024) // // Configure the HIB module RTC wake time // MAP_PRCMHibernateIntervalSet(5 * SLOW_CLK_FREQ); // // Enable the HIB RTC // MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); DBG_PRINT("HIB: Entering HIBernate...\n\r"); MAP_UtilsDelay(80000); // // powering down SPI Flash to save power // Utils_SpiFlashDeepPowerDown(); // // Enter HIBernate mode // MAP_PRCMHibernateEnter(); }
/* Setup the HIBernate wakr source as apecified GPIO */ static void setup_hib_gpio_wake(u32 gpio_num, u32 gpio_wake_type) { MAP_PRCMHibernateWakeUpGPIOSelect(gpio_num, gpio_wake_type); MAP_PRCMHibernateWakeupSourceEnable(gpio_num); return; }
void HibernateWatchdog() { MAP_PRCMHibernateIntervalSet(SLOW_CLK_FREQ); MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); DBG_PRINT("WDT: Entering HIBernate...\n\r"); MAP_UtilsDelay(80000); MAP_PRCMHibernateEnter(); }
void sj_system_restart() { /* Turns out to be not that easy. In particular, using *Reset functions is * not a good idea. * https://e2e.ti.com/support/wireless_connectivity/f/968/p/424736/1516404 * Instead, the recommended way is to enter hibernation with immediate wakeup. */ sl_Stop(50 /* ms */); MAP_PRCMHibernateIntervalSet(328 /* 32KHz ticks, 100 ms */); MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); MAP_PRCMHibernateEnter(); }
void CC3200Helpers_HibernateNowFor(unsigned long dwSeconds, char flStopSL) { unsigned long long qwTicks = dwSeconds; qwTicks *= SLOW_CLK_FREQ; MAP_PRCMHibernateIntervalSet(qwTicks); MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); MAP_UtilsDelay(80000); if ( flStopSL ) { sl_WlanDisconnect(); sl_Stop(0); } MAP_SPICSDisable(SSPI_BASE); MAP_SPICSEnable(SSPI_BASE); MAP_SPIDataPut(SSPI_BASE, 0xB9); // deep power down MAP_SPICSDisable(SSPI_BASE); MAP_PRCMHibernateEnter(); }
/* Timer based wakeup from S4 (HIB) */ static i32 check_n_setup_S4_wakeup_from_timer() { u64 scc_match, scc_curr, scc_remaining; /* Check if there is an alarm set */ if(cc_rtc_has_alarm()) { /* Get the time remaining for the RTC timer to expire */ scc_match = MAP_PRCMSlowClkCtrMatchGet(); scc_curr = MAP_PRCMSlowClkCtrGet(); if(scc_match > scc_curr) { /* Get the time remaining in terms of slow clocks */ scc_remaining = (scc_match - scc_curr); if(scc_remaining > WAKEUP_TIME_HIB) { /* Subtract the time it takes for wakeup from S4 (HIB) */ scc_remaining -= WAKEUP_TIME_HIB; /* Setup the HIB wake time */ MAP_PRCMHibernateIntervalSet(scc_remaining); /* Enable the wake source to be RTC */ MAP_PRCMHibernateWakeupSourceEnable( PRCM_HIB_SLOW_CLK_CTR); } else { /* Cannot enter HIB */ return ERR_TIMER_TO_WAKE; } } else { return -1; } } else { /* Disable Timer as wake source */ MAP_PRCMHibernateWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR); return -1; } return 0; }
//**************************************************************************** // MAIN FUNCTION //**************************************************************************** void main() { long retVal = -1; unsigned long ulResetCause; unsigned long ulDestinationIP; // // Board Initialization // BoardInit(); // // Configure the pinmux settings for the peripherals exercised // PinMuxConfig(); // // Configuring UART // InitTerm(); // // Initialize WDT // WDT_IF_Init(NULL,80000000 * 10); // // Get the reset cause // ulResetCause = PRCMSysResetCauseGet(); // // If watchdog triggered reset request hibernate // to clean boot the system // if( ulResetCause == PRCM_WDT_RESET ) { HIBEntrePreamble(); MAP_PRCMOCRRegisterWrite(0,1); MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); MAP_PRCMHibernateIntervalSet(330); MAP_PRCMHibernateEnter(); } // // uDMA Initialization // UDMAInit(); // // Display banner // DisplayBanner(APPLICATION_NAME); if( ulResetCause == PRCM_HIB_EXIT && (MAP_PRCMOCRRegisterRead(0) & 1) == 1 ) { UART_PRINT("Reset Cause : Watchdog Reset\n\r"); } else { UART_PRINT("Reset Cause : Power On\n\r"); // // Initialize the variables. // InitializeAppVariables(); // // Following function configure the device to default state by cleaning // the persistent settings stored in NVMEM (viz. connection profiles & // policies, power policy etc) // // Applications may choose to skip this step if the developer is sure // that the device is in its desired state at start of applicaton // // Note that all profiles and persistent settings that were done on the // device will be lost // retVal = ConfigureSimpleLinkToDefaultState(); if(retVal < 0) { if (DEVICE_NOT_IN_STATION_MODE == retVal) UART_PRINT("Failed to configure the device in its default" " state \n\r"); LOOP_FOREVER(); } } // // Set destination IP // ulDestinationIP = IP_ADDR; // // Asumption is that the device is configured in station mode already // and it is in its default state // retVal = sl_Start(0, 0, 0); // // Acknowledge the watchdog so that it doesn't resets // WatchdogAck(); if (retVal < 0 || retVal != ROLE_STA) { UART_PRINT("Failed to start the device \n\r"); LOOP_FOREVER(); } // //Connecting to WLAN AP // retVal = WlanConnect(); // // Acknowledge the watchdog so that it doesn't resets // WatchdogAck(); if(retVal < 0) { UART_PRINT("Failed to establish connection w/ an AP \n\r"); LOOP_FOREVER(); } UART_PRINT("Connected to AP : %s \n\r",SSID_NAME); UART_PRINT("Device IP : %d.%d.%d.%d\n\r\n\r", SL_IPV4_BYTE(g_ulIpAddr,3), SL_IPV4_BYTE(g_ulIpAddr,2), SL_IPV4_BYTE(g_ulIpAddr,1), SL_IPV4_BYTE(g_ulIpAddr,0)); UART_PRINT("\nStarting UDP Client\n\n\r"); UART_PRINT("Source IP : %d.%d.%d.%d\n\r" "Destination IP : %d.%d.%d.%d\n\r" "PORT : %d\n\r", SL_IPV4_BYTE(g_ulIpAddr,3), SL_IPV4_BYTE(g_ulIpAddr,2), SL_IPV4_BYTE(g_ulIpAddr,1), SL_IPV4_BYTE(g_ulIpAddr,0), SL_IPV4_BYTE(ulDestinationIP,3), SL_IPV4_BYTE(ulDestinationIP,2), SL_IPV4_BYTE(ulDestinationIP,1), SL_IPV4_BYTE(ulDestinationIP,0), g_uiPortNum); // // Acknowledge the watchdog so that it doesn't resets // WatchdogAck(); // // Send packets // BsdUdpClient(PORT_NUM,ulDestinationIP); // // power off the network processor // sl_Stop(SL_STOP_TIMEOUT); while (1) { _SlNonOsMainLoopTask(); } }