void nrf_pwr_mgmt_run(void) { #if NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED /* * Clear FPU exceptions. * Without this step, the FPU interrupt is marked as pending, * preventing system from sleeping. */ uint32_t fpscr = __get_FPSCR(); __set_FPSCR(fpscr & ~0x9Fu); __DMB(); NVIC_ClearPendingIRQ(FPU_IRQn); // Assert if a critical FPU exception is signaled. ASSERT((fpscr & 0x03) == 0); #endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED SLEEP_LOCK(); #if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED uint32_t sleep_start; uint32_t sleep_end; uint32_t sleep_duration; sleep_start = app_timer_cnt_get(); #endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED DEBUG_PIN_SET(); // Wait for an event. #ifdef SOFTDEVICE_PRESENT ret_code_t ret_code = sd_app_evt_wait(); if (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) { __WFE(); __SEV(); __WFE(); } else { APP_ERROR_CHECK(ret_code); } #else __WFE(); __SEV(); __WFE(); #endif // SOFTDEVICE_PRESENT DEBUG_PIN_CLEAR(); #if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED sleep_end = app_timer_cnt_get(); UNUSED_VARIABLE(app_timer_cnt_diff_compute(sleep_end, sleep_start, &sleep_duration)); m_ticks_sleeping += sleep_duration; #endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED SLEEP_RELEASE(); }
/** * @brief Enter Stop 0 mode. * @note In Stop 0 mode, main and low voltage regulators are ON. * @note In Stop 0 mode, all I/O pins keep the same state as in Run mode. * @note All clocks in the VCORE domain are stopped; the PLL, the MSI, * the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability * (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI * after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated * only to the peripheral requesting it. * SRAM1, SRAM2 and register contents are preserved. * The BOR is available. * @note When exiting Stop 0 mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register * is set; the MSI oscillator is selected if STOPWUCK is cleared. * @note By keeping the internal regulator ON during Stop 0 mode, the consumption * is higher although the startup time is reduced. * @param STOPEntry specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg @ref PWR_STOPENTRY_WFI Enter Stop mode with WFI instruction * @arg @ref PWR_STOPENTRY_WFE Enter Stop mode with WFE instruction * @retval None */ void HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Stop 0 mode with Main Regulator */ MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP0); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
/** * @brief Enters Sleep mode. * * @note In Sleep mode, all I/O pins keep the same state as in Run mode. * * @note In Sleep mode, the systick is stopped to avoid exit from this mode with * systick interrupt when used as time base for Timeout * * @param Regulator Specifies the regulator state in SLEEP mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: SLEEP mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: SLEEP mode with low power regulator ON * @note This parameter is not used for the STM32F7 family and is kept as parameter * just to maintain compatibility with the lower power families. * @param SLEEPEntry Specifies if SLEEP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction * @retval None */ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); /* Clear SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Ensure that all instructions done before entering SLEEP mode */ __DSB(); __ISB(); /* Select SLEEP mode entry -------------------------------------------------*/ if(SLEEPEntry == PWR_SLEEPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } }
void bleSChedule(void) { if (bicProcessDispatch) return; bicProcessDispatch = 1; __SEV(); }
/** * @UART uart wfe deepsleep wakeup demo * @param none * @return none */ void UartWFEDeepSleepWuDemo(void) { UINT8 i, recbuf[3]; Memset(recbuf,0x0,3); IomUARTRXWuEn(); IomUARTRXWuLevHi(); printf("Uart WFE deep sleep enter!!!\r\n"); ScuWakeCoreEvent(); __SEV(); SCB->SCR |= 0x04; __WFE(); __WFE(); UartReceive(recbuf, 1); printf("\r\n"); if(SCU->WKSR0 &0x40) { ScuWkSrcUartClr(); printf("Uart WFE Deep sleep Wakeup!\r\n"); } for(i = 0; i < 1; i++) { printf("recbuf[%d]=0x%x\r\n",i,recbuf[i]); } }
/** * @brief Function for main application entry. */ int main(void) { LEDS_CONFIGURE(BSP_LED_0_MASK); LEDS_OFF(BSP_LED_0_MASK); adc_config(); UNUSED_RETURN_VALUE(NRF_LOG_INIT()); NRF_LOG_PRINTF("ADC example\r\n"); while (true) { APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer,ADC_BUFFER_SIZE)); uint32_t i; for (i = 0; i < ADC_BUFFER_SIZE; i++) { // manually trigger ADC conversion nrf_drv_adc_sample(); // enter into sleep mode __SEV(); __WFE(); __WFE(); nrf_delay_ms(100); LEDS_INVERT(BSP_LED_0_MASK); } } }
/** * @brief Enters Sleep mode. * @note In Sleep mode, all I/O pins keep the same state as in Run mode. * @param Regulator: Specifies the regulator state in SLEEP mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: SLEEP mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: SLEEP mode with low power regulator ON * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction. * When WFI entry is used, tick interrupt have to be disabled if not desired as * the interrupt wake up source. * This parameter can be one of the following values: * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction * @retval None */ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); /* Select the regulator state in Sleep mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= (uint32_t)~(PWR_CR_PDDS | PWR_CR_LPSDSR); /* Set LPSDSR bit according to PWR_Regulator value */ tmpreg |= Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Clear SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); /* Select SLEEP mode entry -------------------------------------------------*/ if(SLEEPEntry == PWR_SLEEPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } }
/** * @brief Enters Stop mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by using an interrupt or a wakeup event, * MSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Select the regulator state in Stop mode: Set PDDS and LPSDSR bit according to PWR_Regulator value */ MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPSDSR), Regulator); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
void xPortSysTickHandler( void ) { nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_TICK); #if configUSE_TICKLESS_IDLE == 1 nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0); #endif uint32_t isrstate = portSET_INTERRUPT_MASK_FROM_ISR(); do{ #if configUSE_TICKLESS_IDLE == 1 TickType_t diff; TickType_t actualTicks = xTaskGetTickCountFromISR(); TickType_t hwTicks = nrf_rtc_counter_get(portNRF_RTC_REG); diff = (hwTicks - actualTicks) & portNRF_RTC_MAXTICKS; if(diff <= 0) { break; } if(diff > 2) // Correct internat ticks { vTaskStepTick(diff - 1); } #endif /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. */ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; __SEV(); } }while(0); portCLEAR_INTERRUPT_MASK_FROM_ISR( isrstate ); }
void SysTick_Handler(void) { static uint32_t prsk = SCAN_PERIOD; uint8_t i, led; uint8_t *command = (uint8_t *)CMD_BASE_ADDR; if (--prsk == 0) { prsk = SCAN_PERIOD; led = 0; for (i = 0; i < 4; i++) { if ((GPIO_ReadValue(buttons[i].port) & buttons[i].mask) == 0) { led |= (1 << i); } } // Send command command[0] = CMD_SET_LED; command[1] = led; __DSB(); // ensure completion of memory access __SEV(); // send event } }
/** * @brief Enter Deep-sleep mode. * @note When exiting Deep-sleep mode, the HSI is selected as the system clock. * @note An additional wakeup delay will be incurred if the LDO operates in * low power mode. * @param PWR_LDO: the LDO state in Deep-sleep mode. * This parameter can be one of the following values: * @arg PWR_LDO_ON: Deep-sleep mode with LDO ON * @arg PWR_LDO_LOWPOWER: Deep-sleep mode with LDO in low power mode * @param PWR_DEEPSLEEPENTRY: WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_DEEPSLEEPENTRY_WFI: enter Deep-sleep mode with WFI instruction * @arg PWR_DEEPSLEEPENTRY_WFE: enter Deep-sleep mode with WFE instruction * @retval None */ void PWR_DEEPSLEEPMode_Entry(uint32_t PWR_LDO, uint8_t PWR_DEEPSLEEPENTRY) { uint32_t temp = 0; /* Select the LDO state in Deep-sleep mode */ temp = PWR->CTLR; /* Clear SDBM and LDOLP bits, and select Deep-sleep mode */ temp &= ~((uint32_t)(PWR_CTLR_SDBM | PWR_CTLR_LDOLP)); /* Set LDOLP bit according to PWR_LDO value, and select the LDO's state */ temp |= PWR_LDO; /* Store the new value */ PWR->CTLR = temp; /* Set SLEEPDEEP bit of Cortex-M3 System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Select WFI or WFE to enter Deep-sleep mode */ if(PWR_DEEPSLEEPENTRY == PWR_DEEPSLEEPENTRY_WFI) { __WFI(); } else { __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex-M3 System Control Register */ SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); }
/** * @brief Enters Stop mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by using an interrupt or a wakeup event, * HSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */ CLEAR_BIT(PWR->CR, PWR_CR_PDDS); /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */ MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); PWR_OverloadWfe(); /* WFE redefine locally */ PWR_OverloadWfe(); /* WFE redefine locally */ } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
/** * @brief Write random bytes; * * @param[in] rngp pointer to the @p RNGDriver object * @param[in] n size of buf in bytes * @param[in] buf @p buffer location * * @notapi */ msg_t rng_lld_write(RNGDriver *rngp, uint8_t *buf, size_t n, systime_t timeout) { size_t i; for (i = 0 ; i < n ; i++) { /* Wait for byte ready * It take about 677µs to generate a new byte, not sure if * forcing a context switch will be a benefit */ while (NRF_RNG->EVENTS_VALRDY == 0) { /* Sleep and wakeup on ARM event (interrupt) */ SCB->SCR |= SCB_SCR_SEVONPEND_Msk; __SEV(); __WFE(); __WFE(); } /* Read byte */ buf[i] = (char)NRF_RNG->VALUE; /* Mark as read */ NRF_RNG->EVENTS_VALRDY = 0; /* Clear interrupt so we can wake up again */ nvicClearPending(RNG_IRQn); } return MSG_OK; }
/**@brief Function for the Power Management. */ static void power_manage(void) { // Use directly __WFE and __SEV macros since the SoftDevice is not available. // Wait for event. __WFE(); // Clear Event Register. __SEV(); __WFE(); }
void PWR_Sleep(void) { switch (pwr_mode) { case MXC_E_PWR_MODE_LP0: __SEV(); __WFE(); /* hack to clear event latch per ARM support */ __WFE(); /* deep sleep */ break; /* reset here */ case MXC_E_PWR_MODE_LP1: __SEV(); __WFE(); __WFE(); wakeup(); break; case MXC_E_PWR_MODE_LP2: __WFI(); break; default: /* PWR_LP3 */ break; } }
/** * @brief Enter the system to STOP mode. * @note In System Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting System Stop mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as default system wakeup clock. * @note In System STOP mode, when the voltage regulator operates in low power mode, * an additional startup delay is incurred when the system is waking up. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Select the regulator state in Stop mode */ tmpreg = PWR->CR1; /* Clear PDDS and LPDS bits */ tmpreg &= (uint32_t)~(PWR_CR1_LPDS); /* Set LPDS bit according to Regulator value */ tmpreg |= Regulator; /* Store the new value */ PWR->CR1 = tmpreg; /* Keep DSTOP mode when D1 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D1); /* Keep DSTOP mode when D2 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D2); /* Keep DSTOP mode when D3 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D3); /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Ensure that all instructions done before entering STOP mode */ __DSB(); __ISB(); /* Select Stop mode entry */ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); }
static int entropy_nrf5_get_entropy_isr(struct device *dev, u8_t *buf, u16_t len, u32_t flags) { u16_t cnt = len; /* Check if this API is called on correct driver instance. */ __ASSERT_NO_MSG(&entropy_nrf5_data == DEV_DATA(dev)); if (likely((flags & ENTROPY_BUSYWAIT) == 0)) { return rng_pool_get((struct rng_pool *)(entropy_nrf5_data.isr), buf, len); } if (len) { unsigned int key; int irq_enabled; key = irq_lock(); irq_enabled = irq_is_enabled(RNG_IRQn); irq_disable(RNG_IRQn); irq_unlock(key); nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); nrf_rng_task_trigger(NRF_RNG_TASK_START); do { int byte; while (!nrf_rng_event_get(NRF_RNG_EVENT_VALRDY)) { __WFE(); __SEV(); __WFE(); } byte = random_byte_get(); NVIC_ClearPendingIRQ(RNG_IRQn); if (byte < 0) { continue; } buf[--len] = byte; } while (len); if (irq_enabled) { irq_enable(RNG_IRQn); } } return cnt; }
void AnalyzerControl::SetConfiguration(const GeneratorParameters& params) { taskENTER_CRITICAL(); _configuration = params; _needconfiguration = true; // Interrupt M4 core if it's analyzing if (StateAnalysisRunning) { __DSB(); __SEV(); } taskEXIT_CRITICAL(); }
static inline u8_t entropy_nrf5_get_u8(void) { while (!nrf_rng_event_get(NRF_RNG_EVENT_VALRDY)) { __WFE(); __SEV(); __WFE(); } nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); /* Clear the Pending status of the RNG interrupt so that it could * wake up the core when the VALRDY event occurs again. */ NVIC_ClearPendingIRQ(RNG_IRQn); return nrf_rng_random_value_get(); }
/** * @brief Function for application main entry. */ int main(void) { leds_config(); lfclk_config(); rtc_config(); while (true) { __SEV(); __WFE(); __WFE(); } }
/** * @brief Function for application main entry. */ int main(void) { // setup gpio_config(); lfclk_config(); rtc_config(); // loop while (true) { // Enter System ON sleep mode __WFE(); // Make sure any pending events are cleared __SEV(); __WFE(); } }
void xPortSysTickHandler( void ) { nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_TICK); #if configUSE_TICKLESS_IDLE == 1 nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0); #endif uint32_t isrstate = portSET_INTERRUPT_MASK_FROM_ISR(); /* Increment the RTOS tick. */ if ( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. */ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; __SEV(); } portCLEAR_INTERRUPT_MASK_FROM_ISR( isrstate ); }
int main(void) { nrf_gpio_cfg_output(GPIO_TOGGLE_PIN); //Set LED pin as output start_timer(); //Configure and start timer while(true) { // Enter System ON sleep mode __WFE(); // Make sure any pending events are cleared __SEV(); __WFE(); // For more information on the WFE - SEV - WFE sequence, please refer to the following Devzone article: // https://devzone.nordicsemi.com/index.php/how-do-you-put-the-nrf51822-chip-to-sleep#reply-1589 } }
/** * @brief Function for application main entry. */ int main(void) { uart_init(); uart_printf("\n\rstart qdec\n\r"); // setup gpio_config(); // Configure GPIO pins. qdec_config(); // Configure QDEC // loop while (true) { // Enter System ON sleep mode __WFE(); // Make sure any pending events are cleared __SEV(); __WFE(); } }
void mbed_enter_sleep(sleep_t *obj) { (void)obj; // ensure debug is disconnected if semihost is enabled.... NRF_POWER->TASKS_LOWPWR = 1; SCB->SCR |= SCB_SCR_SEVONPEND_Msk; /* send an event when an interrupt is pending. * This helps with the wakeup from the following app_evt_wait(). */ uint8_t sd_enabled; // look if exceptions are enabled or not, if they are, it is possible to make an SVC call // and check if the soft device is running if ((__get_PRIMASK() == 0) && (sd_softdevice_is_enabled(&sd_enabled) == NRF_SUCCESS) && (sd_enabled == 1)) { // soft device is enabled, use the primitives from the soft device to go to sleep sd_app_evt_wait(); } else { // Note: it is not possible to just use WFE at this stage because WFE // will read the event register (not accessible) and if an event occured, // in the past, it will just clear the event register and continue execution. // SVC call like sd_softdevice_is_enabled set the event register to 1. // This means that a making an SVC call followed by WFE will never put the // CPU to sleep. // Our startegy here is to clear the event register then, if there is any // interrupt, return from here. If no interrupts are pending, just call // WFE. // Set an event and wake up whatsoever, this will clear the event // register from all previous events set (SVC call included) __SEV(); __WFE(); // Test if there is an interrupt pending (mask reserved regions) if (SCB->ICSR & (SCB_ICSR_RESERVED_BITS_MASK)) { // Ok, there is an interrut pending, no need to go to sleep return; } else { // next event will wakeup the CPU // If an interrupt occured between the test of SCB->ICSR and this // instruction, WFE will just not put the CPU to sleep __WFE(); } } }
/** * @brief Enter Sleep or Low-power Sleep mode. * @note In Sleep/Low-power Sleep mode, all I/O pins keep the same state as in Run mode. * @param Regulator: Specifies the regulator state in Sleep/Low-power Sleep mode. * This parameter can be one of the following values: * @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode) * @arg @ref PWR_LOWPOWERREGULATOR_ON Low-power Sleep mode (regulator in low-power mode) * @note Low-power Sleep mode is entered from Low-power Run mode. Therefore, if not yet * in Low-power Run mode before calling HAL_PWR_EnterSLEEPMode() with Regulator set * to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the * Flash in power-down monde in setting the SLEEP_PD bit in FLASH_ACR register. * Additionally, the clock frequency must be reduced below 2 MHz. * Setting SLEEP_PD in FLASH_ACR then appropriately reducing the clock frequency must * be done before calling HAL_PWR_EnterSLEEPMode() API. * @note When exiting Low-power Sleep mode, the MCU is in Low-power Run mode. To move in * Run mode, the user must resort to HAL_PWREx_DisableLowPowerRunMode() API. * @param SLEEPEntry: Specifies if Sleep mode is entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep mode with WFI instruction * @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep mode with WFE instruction * @note When WFI entry is used, tick interrupt have to be disabled if not desired as * the interrupt wake up source. * @retval None */ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); /* Set Regulator parameter */ if (Regulator == PWR_MAINREGULATOR_ON) { /* If in low-power run mode at this point, exit it */ if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF)) { HAL_PWREx_DisableLowPowerRunMode(); } /* Regulator now in main mode. */ } else { /* If in run mode, first move to low-power run mode. The system clock frequency must be below 2 MHz at this point. */ if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF) == RESET) { HAL_PWREx_EnableLowPowerRunMode(); } } /* Clear SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select SLEEP mode entry -------------------------------------------------*/ if(SLEEPEntry == PWR_SLEEPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } }
void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt executes all interrupts must be unmasked. There is therefore no need to save and then restore the interrupt mask value as its value is already known. */ ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE ) { /* A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. */ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; __SEV(); } } portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); }
/** * @brief Function for main application entry. */ int main(void) { adc_config(); uart_config(); printf("\n\rADC HAL simple example\r\n"); printf("Current sample value:\r\n"); nrf_adc_start(); while (true) { // enter into sleep mode __SEV(); __WFE(); __WFE(); } }
/** * @brief Enters Sleep mode. * * @note In Sleep mode, all I/O pins keep the same state as in Run mode. * * @note In Sleep mode, the systick is stopped to avoid exit from this mode with * systick interrupt when used as time base for Timeout * * @param Regulator: Specifies the regulator state in SLEEP mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: SLEEP mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: SLEEP mode with low power regulator ON * @note This parameter is not used for the STM32F4 family and is kept as parameter * just to maintain compatibility with the lower power families. * @param SLEEPEntry: Specifies if SLEEP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction * @retval None */ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); /* Select SLEEP mode entry -------------------------------------------------*/ if(SLEEPEntry == PWR_SLEEPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } }
/**@brief Function for waiting for events. * * @details This function will place the chip in low power mode while waiting for events from * the SoftDevice or other peripherals. When interrupted by an event, it will call the * @ref app_sched_execute function to process the received event. This function will return * when the final state of the firmware update is reached OR when a tear down is in * progress. */ static void wait_for_events(void) { for (;;) { __SEV(); __WFI(); __WFE(); // Event received. Process it from the scheduler. app_sched_execute(); if ((m_update_status == BOOTLOADER_COMPLETE) || (m_update_status == BOOTLOADER_TIMEOUT) || (m_update_status == BOOTLOADER_RESET)) { // When update has completed or a timeout/reset occured we will return. return; } } }