mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/sleep.c@186:707f6e361f3e, 2018-06-22 (annotated)
- Committer:
- Anna Bridge
- Date:
- Fri Jun 22 16:45:37 2018 +0100
- Revision:
- 186:707f6e361f3e
mbed-dev library. Release version 162
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
186:707f6e361f3e | 1 | /* mbed Microcontroller Library |
Anna Bridge |
186:707f6e361f3e | 2 | * Copyright (c) 2006-2013 ARM Limited |
Anna Bridge |
186:707f6e361f3e | 3 | * |
Anna Bridge |
186:707f6e361f3e | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Anna Bridge |
186:707f6e361f3e | 5 | * you may not use this file except in compliance with the License. |
Anna Bridge |
186:707f6e361f3e | 6 | * You may obtain a copy of the License at |
Anna Bridge |
186:707f6e361f3e | 7 | * |
Anna Bridge |
186:707f6e361f3e | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
Anna Bridge |
186:707f6e361f3e | 9 | * |
Anna Bridge |
186:707f6e361f3e | 10 | * Unless required by applicable law or agreed to in writing, software |
Anna Bridge |
186:707f6e361f3e | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
Anna Bridge |
186:707f6e361f3e | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Anna Bridge |
186:707f6e361f3e | 13 | * See the License for the specific language governing permissions and |
Anna Bridge |
186:707f6e361f3e | 14 | * limitations under the License. |
Anna Bridge |
186:707f6e361f3e | 15 | */ |
Anna Bridge |
186:707f6e361f3e | 16 | #include "sleep_api.h" |
Anna Bridge |
186:707f6e361f3e | 17 | #include "cmsis.h" |
Anna Bridge |
186:707f6e361f3e | 18 | #include "mbed_interface.h" |
Anna Bridge |
186:707f6e361f3e | 19 | #include "softdevice_handler.h" |
Anna Bridge |
186:707f6e361f3e | 20 | #include "nrf_soc.h" |
Anna Bridge |
186:707f6e361f3e | 21 | #include "nrf_timer.h" |
Anna Bridge |
186:707f6e361f3e | 22 | #include "us_ticker.h" |
Anna Bridge |
186:707f6e361f3e | 23 | |
Anna Bridge |
186:707f6e361f3e | 24 | // Mask of reserved bits of the register ICSR in the System Control Block peripheral |
Anna Bridge |
186:707f6e361f3e | 25 | // In this case, bits which are equal to 0 are the bits reserved in this register |
Anna Bridge |
186:707f6e361f3e | 26 | #define SCB_ICSR_RESERVED_BITS_MASK 0x9E43F03F |
Anna Bridge |
186:707f6e361f3e | 27 | |
Anna Bridge |
186:707f6e361f3e | 28 | #define FPU_EXCEPTION_MASK 0x0000009F |
Anna Bridge |
186:707f6e361f3e | 29 | |
Anna Bridge |
186:707f6e361f3e | 30 | extern bool us_ticker_initialized; |
Anna Bridge |
186:707f6e361f3e | 31 | |
Anna Bridge |
186:707f6e361f3e | 32 | void hal_sleep(void) |
Anna Bridge |
186:707f6e361f3e | 33 | { |
Anna Bridge |
186:707f6e361f3e | 34 | // ensure debug is disconnected if semihost is enabled.... |
Anna Bridge |
186:707f6e361f3e | 35 | |
Anna Bridge |
186:707f6e361f3e | 36 | // Trigger an event when an interrupt is pending. This allows to wake up |
Anna Bridge |
186:707f6e361f3e | 37 | // the processor from disabled interrupts. |
Anna Bridge |
186:707f6e361f3e | 38 | SCB->SCR |= SCB_SCR_SEVONPEND_Msk; |
Anna Bridge |
186:707f6e361f3e | 39 | |
Anna Bridge |
186:707f6e361f3e | 40 | #if defined(NRF52) || defined(NRF52840_XXAA) |
Anna Bridge |
186:707f6e361f3e | 41 | /* Clear exceptions and PendingIRQ from the FPU unit */ |
Anna Bridge |
186:707f6e361f3e | 42 | __set_FPSCR(__get_FPSCR() & ~(FPU_EXCEPTION_MASK)); |
Anna Bridge |
186:707f6e361f3e | 43 | (void) __get_FPSCR(); |
Anna Bridge |
186:707f6e361f3e | 44 | NVIC_ClearPendingIRQ(FPU_IRQn); |
Anna Bridge |
186:707f6e361f3e | 45 | #endif |
Anna Bridge |
186:707f6e361f3e | 46 | |
Anna Bridge |
186:707f6e361f3e | 47 | // If the SoftDevice is enabled, its API must be used to go to sleep. |
Anna Bridge |
186:707f6e361f3e | 48 | if (softdevice_handler_is_enabled()) { |
Anna Bridge |
186:707f6e361f3e | 49 | sd_power_mode_set(NRF_POWER_MODE_LOWPWR); |
Anna Bridge |
186:707f6e361f3e | 50 | sd_app_evt_wait(); |
Anna Bridge |
186:707f6e361f3e | 51 | } else { |
Anna Bridge |
186:707f6e361f3e | 52 | NRF_POWER->TASKS_LOWPWR = 1; |
Anna Bridge |
186:707f6e361f3e | 53 | |
Anna Bridge |
186:707f6e361f3e | 54 | // Note: it is not sufficient to just use WFE here, since the internal |
Anna Bridge |
186:707f6e361f3e | 55 | // event register may be already set from an event that occurred in the |
Anna Bridge |
186:707f6e361f3e | 56 | // past (like an SVC call to the SoftDevice) and in such case WFE will |
Anna Bridge |
186:707f6e361f3e | 57 | // just clear the register and continue execution. |
Anna Bridge |
186:707f6e361f3e | 58 | // Therefore, the strategy here is to first clear the event register |
Anna Bridge |
186:707f6e361f3e | 59 | // by using SEV/WFE pair, and then execute WFE again, unless there is |
Anna Bridge |
186:707f6e361f3e | 60 | // a pending interrupt. |
Anna Bridge |
186:707f6e361f3e | 61 | |
Anna Bridge |
186:707f6e361f3e | 62 | // Set an event and wake up whatsoever, this will clear the event |
Anna Bridge |
186:707f6e361f3e | 63 | // register from all previous events set (SVC call included) |
Anna Bridge |
186:707f6e361f3e | 64 | __SEV(); |
Anna Bridge |
186:707f6e361f3e | 65 | __WFE(); |
Anna Bridge |
186:707f6e361f3e | 66 | |
Anna Bridge |
186:707f6e361f3e | 67 | // Test if there is an interrupt pending (mask reserved regions) |
Anna Bridge |
186:707f6e361f3e | 68 | if (SCB->ICSR & (SCB_ICSR_RESERVED_BITS_MASK)) { |
Anna Bridge |
186:707f6e361f3e | 69 | // Ok, there is an interrut pending, no need to go to sleep |
Anna Bridge |
186:707f6e361f3e | 70 | return; |
Anna Bridge |
186:707f6e361f3e | 71 | } else { |
Anna Bridge |
186:707f6e361f3e | 72 | // next event will wakeup the CPU |
Anna Bridge |
186:707f6e361f3e | 73 | // If an interrupt occured between the test of SCB->ICSR and this |
Anna Bridge |
186:707f6e361f3e | 74 | // instruction, WFE will just not put the CPU to sleep |
Anna Bridge |
186:707f6e361f3e | 75 | __WFE(); |
Anna Bridge |
186:707f6e361f3e | 76 | } |
Anna Bridge |
186:707f6e361f3e | 77 | } |
Anna Bridge |
186:707f6e361f3e | 78 | } |
Anna Bridge |
186:707f6e361f3e | 79 | |
Anna Bridge |
186:707f6e361f3e | 80 | void hal_deepsleep(void) |
Anna Bridge |
186:707f6e361f3e | 81 | { |
Anna Bridge |
186:707f6e361f3e | 82 | if (us_ticker_initialized) { |
Anna Bridge |
186:707f6e361f3e | 83 | nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_STOP); |
Anna Bridge |
186:707f6e361f3e | 84 | } |
Anna Bridge |
186:707f6e361f3e | 85 | |
Anna Bridge |
186:707f6e361f3e | 86 | hal_sleep(); |
Anna Bridge |
186:707f6e361f3e | 87 | |
Anna Bridge |
186:707f6e361f3e | 88 | if (us_ticker_initialized) { |
Anna Bridge |
186:707f6e361f3e | 89 | nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_START); |
Anna Bridge |
186:707f6e361f3e | 90 | } |
Anna Bridge |
186:707f6e361f3e | 91 | |
Anna Bridge |
186:707f6e361f3e | 92 | // NRF_POWER->SYSTEMOFF=1; |
Anna Bridge |
186:707f6e361f3e | 93 | } |