mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5581 from SiliconLabs/feature/remove-custom-sleepmodes
Remove custom Silicon Labs sleep managementpull/5693/head
commit
6c59e13e76
|
@ -23,8 +23,7 @@
|
||||||
#include "em_usbtypes.h"
|
#include "em_usbtypes.h"
|
||||||
#include "em_usbhal.h"
|
#include "em_usbhal.h"
|
||||||
#include "em_usbd.h"
|
#include "em_usbd.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
enum USBISRCommand {
|
enum USBISRCommand {
|
||||||
CMD_HANDLED = 0,
|
CMD_HANDLED = 0,
|
||||||
|
@ -134,11 +133,6 @@ USBHAL::USBHAL(void)
|
||||||
// be dynamically removed/reinstated to allow deeper sleep.
|
// be dynamically removed/reinstated to allow deeper sleep.
|
||||||
usbhal_allow_em2(false);
|
usbhal_allow_em2(false);
|
||||||
|
|
||||||
// When in suspend / Vbus off we can go to EM2, but never below
|
|
||||||
// that as long as USB is being used. Despite the name the call here
|
|
||||||
// blocks entering modes _below_ EM2, but allows EM2.
|
|
||||||
blockSleepMode(EM2);
|
|
||||||
|
|
||||||
epCallback[EP0OUT] = NULL;
|
epCallback[EP0OUT] = NULL;
|
||||||
epCallback[EP0IN ] = NULL;
|
epCallback[EP0IN ] = NULL;
|
||||||
epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
|
epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
|
||||||
|
@ -193,17 +187,17 @@ USBHAL::~USBHAL(void)
|
||||||
usbhal_free_buffers();
|
usbhal_free_buffers();
|
||||||
|
|
||||||
usbhal_allow_em2(true);
|
usbhal_allow_em2(true);
|
||||||
unblockSleepMode(EM2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void usbhal_allow_em2(bool allow_em2)
|
extern "C" void usbhal_allow_em2(bool allow_em2)
|
||||||
{
|
{
|
||||||
if (allow_em2) {
|
static bool blocked = false;
|
||||||
// unblockSleepMode is safe to call even if we would unblock
|
if (allow_em2 && blocked) {
|
||||||
// an already unblocked mode, so no checks here.
|
sleep_manager_unlock_deep_sleep();
|
||||||
unblockSleepMode(EM1);
|
blocked = false;
|
||||||
} else {
|
} else if (!blocked) {
|
||||||
blockSleepMode(EM1);
|
sleep_manager_lock_deep_sleep();
|
||||||
|
blocked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
|
|
||||||
void gpio_write(gpio_t *obj, int value)
|
void gpio_write(gpio_t *obj, int value)
|
||||||
|
|
|
@ -31,10 +31,8 @@
|
||||||
#include "em_gpio.h"
|
#include "em_gpio.h"
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#define NUM_GPIO_CHANNELS (16)
|
#define NUM_GPIO_CHANNELS (16)
|
||||||
#define GPIO_LEAST_ACTIVE_SLEEPMODE EM3
|
|
||||||
|
|
||||||
/* Macro return index of the LSB flag which is set. */
|
/* Macro return index of the LSB flag which is set. */
|
||||||
#if ((__CORTEX_M == 3) || (__CORTEX_M == 4))
|
#if ((__CORTEX_M == 3) || (__CORTEX_M == 4))
|
||||||
|
@ -142,21 +140,16 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||||
if(GPIO->IEN == 0) was_disabled = true;
|
if(GPIO->IEN == 0) was_disabled = true;
|
||||||
|
|
||||||
GPIO_IntConfig((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin &0xF, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge);
|
GPIO_IntConfig((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin &0xF, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge);
|
||||||
if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) {
|
|
||||||
blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gpio_irq_enable(gpio_irq_t *obj)
|
inline void gpio_irq_enable(gpio_irq_t *obj)
|
||||||
{
|
{
|
||||||
if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
GPIO_IntEnable(1 << (obj->pin & 0xF)); // pin mask for pins to enable
|
GPIO_IntEnable(1 << (obj->pin & 0xF)); // pin mask for pins to enable
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gpio_irq_disable(gpio_irq_t *obj)
|
inline void gpio_irq_disable(gpio_irq_t *obj)
|
||||||
{
|
{
|
||||||
GPIO_IntDisable(1 << (obj->pin & 0xF)); // pin mask for pins to disable
|
GPIO_IntDisable(1 << (obj->pin & 0xF)); // pin mask for pins to disable
|
||||||
if(GPIO->IEN == 0) unblockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
#if DEVICE_I2C
|
#if DEVICE_I2C
|
||||||
|
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "i2c_api.h"
|
#include "i2c_api.h"
|
||||||
#include "PeripheralPins.h"
|
#include "PeripheralPins.h"
|
||||||
#include "pinmap_function.h"
|
#include "pinmap_function.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#include "em_i2c.h"
|
#include "em_i2c.h"
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
|
@ -508,7 +508,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
|
||||||
retval = I2C_TransferInit(obj->i2c.i2c, &(obj->i2c.xfer));
|
retval = I2C_TransferInit(obj->i2c.i2c, &(obj->i2c.xfer));
|
||||||
|
|
||||||
if(retval == i2cTransferInProgress) {
|
if(retval == i2cTransferInProgress) {
|
||||||
blockSleepMode(EM1);
|
sleep_manager_lock_deep_sleep();
|
||||||
} else {
|
} else {
|
||||||
// something happened, and the transfer did not go through
|
// something happened, and the transfer did not go through
|
||||||
// So, we need to clean up
|
// So, we need to clean up
|
||||||
|
@ -541,7 +541,7 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
|
||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
i2c_enable_interrupt(obj, 0, false);
|
i2c_enable_interrupt(obj, 0, false);
|
||||||
|
|
||||||
unblockSleepMode(EM1);
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
|
||||||
return I2C_EVENT_TRANSFER_COMPLETE & obj->i2c.events;
|
return I2C_EVENT_TRANSFER_COMPLETE & obj->i2c.events;
|
||||||
case i2cTransferNack:
|
case i2cTransferNack:
|
||||||
|
@ -549,7 +549,7 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
|
||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
i2c_enable_interrupt(obj, 0, false);
|
i2c_enable_interrupt(obj, 0, false);
|
||||||
|
|
||||||
unblockSleepMode(EM1);
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
|
||||||
return I2C_EVENT_ERROR_NO_SLAVE & obj->i2c.events;
|
return I2C_EVENT_ERROR_NO_SLAVE & obj->i2c.events;
|
||||||
default:
|
default:
|
||||||
|
@ -557,7 +557,7 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
|
||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
i2c_enable_interrupt(obj, 0, false);
|
i2c_enable_interrupt(obj, 0, false);
|
||||||
|
|
||||||
unblockSleepMode(EM1);
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
|
||||||
// return error
|
// return error
|
||||||
return I2C_EVENT_ERROR & obj->i2c.events;
|
return I2C_EVENT_ERROR & obj->i2c.events;
|
||||||
|
@ -578,19 +578,19 @@ uint8_t i2c_active(i2c_t *obj)
|
||||||
*/
|
*/
|
||||||
void i2c_abort_asynch(i2c_t *obj)
|
void i2c_abort_asynch(i2c_t *obj)
|
||||||
{
|
{
|
||||||
// Do not deactivate I2C twice
|
|
||||||
if (!i2c_active(obj)) return;
|
|
||||||
|
|
||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
i2c_enable_interrupt(obj, 0, false);
|
i2c_enable_interrupt(obj, 0, false);
|
||||||
|
|
||||||
|
// Do not deactivate I2C twice
|
||||||
|
if (!i2c_active(obj)) return;
|
||||||
|
|
||||||
// Abort
|
// Abort
|
||||||
obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
|
obj->i2c.i2c->CMD = I2C_CMD_STOP | I2C_CMD_ABORT;
|
||||||
|
|
||||||
// Block until free
|
// Block until free
|
||||||
while(i2c_active(obj));
|
while(i2c_active(obj));
|
||||||
|
|
||||||
unblockSleepMode(EM1);
|
sleep_manager_unlock_deep_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //DEVICE_I2C ASYNCH
|
#endif //DEVICE_I2C ASYNCH
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#if DEVICE_PWMOUT
|
#if DEVICE_PWMOUT
|
||||||
|
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "pwmout_api.h"
|
#include "pwmout_api.h"
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
#include "PeripheralPins.h"
|
#include "PeripheralPins.h"
|
||||||
#include "device_peripherals.h"
|
#include "device_peripherals.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "em_gpio.h"
|
#include "em_gpio.h"
|
||||||
|
@ -180,7 +180,7 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
pwmout_set_channel_route(pwmout_get_channel_route(obj->channel));
|
pwmout_set_channel_route(pwmout_get_channel_route(obj->channel));
|
||||||
blockSleepMode(EM1);
|
sleep_manager_lock_deep_sleep();
|
||||||
pwmout_enable(obj, true);
|
pwmout_enable(obj, true);
|
||||||
pwmout_enable_pins(obj, true);
|
pwmout_enable_pins(obj, true);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ void pwmout_free(pwmout_t *obj)
|
||||||
{
|
{
|
||||||
if(pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) {
|
if(pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) {
|
||||||
//Channel was previously enabled, so do housekeeping
|
//Channel was previously enabled, so do housekeeping
|
||||||
unblockSleepMode(EM1);
|
sleep_manager_unlock_deep_sleep();
|
||||||
} else {
|
} else {
|
||||||
//This channel was disabled already
|
//This channel was disabled already
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include "rtc_api_HAL.h"
|
#include "rtc_api_HAL.h"
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#if (defined RTC_COUNT) && (RTC_COUNT > 0)
|
#if (defined RTC_COUNT) && (RTC_COUNT > 0)
|
||||||
#include "em_rtc.h"
|
#include "em_rtc.h"
|
||||||
|
@ -48,8 +47,6 @@ static void (*comp0_handler)(void) = NULL;
|
||||||
#ifndef RTCC_COUNT
|
#ifndef RTCC_COUNT
|
||||||
|
|
||||||
/* Using RTC API */
|
/* Using RTC API */
|
||||||
|
|
||||||
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
|
|
||||||
#define RTC_NUM_BITS (24)
|
#define RTC_NUM_BITS (24)
|
||||||
|
|
||||||
void RTC_IRQHandler(void)
|
void RTC_IRQHandler(void)
|
||||||
|
@ -111,7 +108,6 @@ void rtc_init_real(uint32_t flags)
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
RTC_Init(&init);
|
RTC_Init(&init);
|
||||||
|
|
||||||
blockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
rtc_inited = true;
|
rtc_inited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +127,6 @@ void rtc_free_real(uint32_t flags)
|
||||||
NVIC_DisableIRQ(RTC_IRQn);
|
NVIC_DisableIRQ(RTC_IRQn);
|
||||||
RTC_Reset();
|
RTC_Reset();
|
||||||
CMU_ClockEnable(cmuClock_RTC, false);
|
CMU_ClockEnable(cmuClock_RTC, false);
|
||||||
unblockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
rtc_inited = false;
|
rtc_inited = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,8 +134,6 @@ void rtc_free_real(uint32_t flags)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Using RTCC API */
|
/* Using RTCC API */
|
||||||
|
|
||||||
#define RTCC_LEAST_ACTIVE_SLEEPMODE EM2
|
|
||||||
#define RTCC_NUM_BITS (32)
|
#define RTCC_NUM_BITS (32)
|
||||||
|
|
||||||
void RTCC_IRQHandler(void)
|
void RTCC_IRQHandler(void)
|
||||||
|
@ -204,8 +197,6 @@ void rtc_init_real(uint32_t flags)
|
||||||
|
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
RTCC_Init(&init);
|
RTCC_Init(&init);
|
||||||
|
|
||||||
blockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
rtc_inited = true;
|
rtc_inited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +216,6 @@ void rtc_free_real(uint32_t flags)
|
||||||
NVIC_DisableIRQ(RTCC_IRQn);
|
NVIC_DisableIRQ(RTCC_IRQn);
|
||||||
RTCC_Reset();
|
RTCC_Reset();
|
||||||
CMU_ClockEnable(cmuClock_RTCC, false);
|
CMU_ClockEnable(cmuClock_RTCC, false);
|
||||||
unblockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
rtc_inited = false;
|
rtc_inited = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#if DEVICE_SERIAL
|
#if DEVICE_SERIAL
|
||||||
|
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "serial_api.h"
|
#include "serial_api.h"
|
||||||
#include "serial_api_HAL.h"
|
#include "serial_api_HAL.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -44,10 +45,6 @@
|
||||||
#include "dma_api.h"
|
#include "dma_api.h"
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#define SERIAL_LEAST_ACTIVE_SLEEPMODE EM1
|
|
||||||
#define SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART EM2
|
|
||||||
|
|
||||||
/** Validation of LEUART register block pointer reference
|
/** Validation of LEUART register block pointer reference
|
||||||
* for assert statements. */
|
* for assert statements. */
|
||||||
|
@ -2239,13 +2236,11 @@ static void serial_unblock_sleep(serial_t *obj)
|
||||||
{
|
{
|
||||||
if( obj->serial.sleep_blocked > 0 ) {
|
if( obj->serial.sleep_blocked > 0 ) {
|
||||||
#ifdef LEUART_USING_LFXO
|
#ifdef LEUART_USING_LFXO
|
||||||
if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
|
if(!LEUART_REF_VALID(obj->serial.periph.leuart) || (LEUART_BaudrateGet(obj->serial.periph.leuart) > (LEUART_LF_REF_FREQ/2))){
|
||||||
unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
|
sleep_manager_unlock_deep_sleep();
|
||||||
}else{
|
|
||||||
unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
unblockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
#endif
|
#endif
|
||||||
obj->serial.sleep_blocked--;
|
obj->serial.sleep_blocked--;
|
||||||
}
|
}
|
||||||
|
@ -2255,13 +2250,13 @@ static void serial_block_sleep(serial_t *obj)
|
||||||
{
|
{
|
||||||
obj->serial.sleep_blocked++;
|
obj->serial.sleep_blocked++;
|
||||||
#ifdef LEUART_USING_LFXO
|
#ifdef LEUART_USING_LFXO
|
||||||
if(LEUART_REF_VALID(obj->serial.periph.leuart) && (LEUART_BaudrateGet(obj->serial.periph.leuart) <= (LEUART_LF_REF_FREQ/2))){
|
if(!LEUART_REF_VALID(obj->serial.periph.leuart) || (LEUART_BaudrateGet(obj->serial.periph.leuart) > (LEUART_LF_REF_FREQ/2))){
|
||||||
blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE_LEUART);
|
/* LEUART configured to a baudrate triggering the use of HFCLK, so prevent HFCLK from getting turned off */
|
||||||
}else{
|
sleep_manager_lock_deep_sleep();
|
||||||
blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
blockSleepMode(SERIAL_LEAST_ACTIVE_SLEEPMODE);
|
/* HFCLK unavailable in deepsleep */
|
||||||
|
sleep_manager_lock_deep_sleep();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,32 +25,15 @@
|
||||||
#if DEVICE_SLEEP
|
#if DEVICE_SLEEP
|
||||||
|
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
#include "em_emu.h"
|
#include "em_emu.h"
|
||||||
#include "mbed_critical.h"
|
|
||||||
|
|
||||||
uint32_t sleep_block_counter[NUM_SLEEP_MODES] = {0};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sleep mode.
|
* Sleep mode.
|
||||||
* Enter the lowest possible sleep mode that is not blocked by ongoing activity.
|
* Stop the core clock using a WFI.
|
||||||
*/
|
*/
|
||||||
void hal_sleep(void)
|
void hal_sleep(void)
|
||||||
{
|
{
|
||||||
if (sleep_block_counter[0] > 0) {
|
EMU_EnterEM1();
|
||||||
/* Blocked everything below EM0, so just return */
|
|
||||||
return;
|
|
||||||
} else if (sleep_block_counter[1] > 0) {
|
|
||||||
/* Blocked everything below EM1, enter EM1 */
|
|
||||||
EMU_EnterEM1();
|
|
||||||
} else if (sleep_block_counter[2] > 0) {
|
|
||||||
/* Blocked everything below EM2, enter EM2 */
|
|
||||||
EMU_EnterEM2(true);
|
|
||||||
} else {
|
|
||||||
/* Blocked everything below EM3, enter EM3 */
|
|
||||||
EMU_EnterEM3(true);
|
|
||||||
} /* Never enter EM4, as mbed has no way of configuring EM4 wakeup */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,35 +52,4 @@ void hal_deepsleep(void)
|
||||||
EMU_EnterEM2(true);
|
EMU_EnterEM2(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Block the microcontroller from sleeping below a certain mode
|
|
||||||
*
|
|
||||||
* This will block sleep() from entering an energy mode below the one given.
|
|
||||||
* -- To be called by peripheral HAL's --
|
|
||||||
*
|
|
||||||
* After the peripheral is finished with the operation, it should call unblock with the same state
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void blockSleepMode(sleepstate_enum minimumMode)
|
|
||||||
{
|
|
||||||
core_util_critical_section_enter();
|
|
||||||
sleep_block_counter[minimumMode]++;
|
|
||||||
core_util_critical_section_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Unblock the microcontroller from sleeping below a certain mode
|
|
||||||
*
|
|
||||||
* This will unblock sleep() from entering an energy mode below the one given.
|
|
||||||
* -- To be called by peripheral HAL's --
|
|
||||||
*
|
|
||||||
* This should be called after all transactions on a peripheral are done.
|
|
||||||
*/
|
|
||||||
void unblockSleepMode(sleepstate_enum minimumMode)
|
|
||||||
{
|
|
||||||
core_util_critical_section_enter();
|
|
||||||
if(sleep_block_counter[minimumMode] > 0) {
|
|
||||||
sleep_block_counter[minimumMode]--;
|
|
||||||
}
|
|
||||||
core_util_critical_section_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/***************************************************************************//**
|
|
||||||
* @file sleepmodes.h
|
|
||||||
*******************************************************************************
|
|
||||||
* @section License
|
|
||||||
* <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
|
|
||||||
*******************************************************************************
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MBED_SLEEPMODES_H
|
|
||||||
#define MBED_SLEEPMODES_H
|
|
||||||
|
|
||||||
#include "em_gpio.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Blocks all sleepmodes below the one passed as argument
|
|
||||||
*
|
|
||||||
* @param minimumMode The lowest-power sleep mode which must remain active
|
|
||||||
*/
|
|
||||||
void blockSleepMode(sleepstate_enum minimumMode);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unblocks a previously-blocked sleep mode
|
|
||||||
*
|
|
||||||
*@param minimumMode The same sleepmode that was previously passed to blockSleepMode
|
|
||||||
*/
|
|
||||||
void unblockSleepMode(sleepstate_enum minimumMode);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -26,6 +26,7 @@
|
||||||
#if DEVICE_SPI
|
#if DEVICE_SPI
|
||||||
|
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "PeripheralPins.h"
|
#include "PeripheralPins.h"
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
#include "pinmap_function.h"
|
#include "pinmap_function.h"
|
||||||
|
@ -39,12 +40,9 @@
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "em_dma.h"
|
#include "em_dma.h"
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
static uint16_t fill_word = SPI_FILL_WORD;
|
static uint16_t fill_word = SPI_FILL_WORD;
|
||||||
|
|
||||||
#define SPI_LEAST_ACTIVE_SLEEPMODE EM1
|
|
||||||
|
|
||||||
static inline CMU_Clock_TypeDef spi_get_clock_tree(spi_t *obj)
|
static inline CMU_Clock_TypeDef spi_get_clock_tree(spi_t *obj)
|
||||||
{
|
{
|
||||||
switch ((int)obj->spi.spi) {
|
switch ((int)obj->spi.spi) {
|
||||||
|
@ -1188,7 +1186,7 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
|
||||||
spi_enable_event(obj, event, true);
|
spi_enable_event(obj, event, true);
|
||||||
|
|
||||||
// Set the sleep mode
|
// Set the sleep mode
|
||||||
blockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_lock_deep_sleep();
|
||||||
|
|
||||||
/* And kick off the transfer */
|
/* And kick off the transfer */
|
||||||
spi_master_transfer_dma(obj, tx, rx, tx_length, rx_length, (void*)handler, hint);
|
spi_master_transfer_dma(obj, tx, rx, tx_length, rx_length, (void*)handler, hint);
|
||||||
|
@ -1244,7 +1242,7 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
|
||||||
|
|
||||||
/* Wait transmit to complete, before user code is indicated*/
|
/* Wait transmit to complete, before user code is indicated*/
|
||||||
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
||||||
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
/* return to CPP land to say we're finished */
|
/* return to CPP land to say we're finished */
|
||||||
return SPI_EVENT_COMPLETE;
|
return SPI_EVENT_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1262,7 +1260,7 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
|
||||||
/* disable interrupts */
|
/* disable interrupts */
|
||||||
spi_enable_interrupt(obj, (uint32_t)NULL, false);
|
spi_enable_interrupt(obj, (uint32_t)NULL, false);
|
||||||
|
|
||||||
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
/* Return the event back to userland */
|
/* Return the event back to userland */
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
@ -1370,7 +1368,7 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
|
||||||
|
|
||||||
/* Wait for transmit to complete, before user code is indicated */
|
/* Wait for transmit to complete, before user code is indicated */
|
||||||
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
||||||
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
|
||||||
/* return to CPP land to say we're finished */
|
/* return to CPP land to say we're finished */
|
||||||
return SPI_EVENT_COMPLETE;
|
return SPI_EVENT_COMPLETE;
|
||||||
|
@ -1391,7 +1389,7 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
|
||||||
|
|
||||||
/* Wait for transmit to complete, before user code is indicated */
|
/* Wait for transmit to complete, before user code is indicated */
|
||||||
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
while(!(obj->spi.spi->STATUS & USART_STATUS_TXC));
|
||||||
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
|
|
||||||
/* Return the event back to userland */
|
/* Return the event back to userland */
|
||||||
return event;
|
return event;
|
||||||
|
@ -1433,7 +1431,7 @@ void spi_abort_asynch(spi_t *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release sleep mode block
|
// Release sleep mode block
|
||||||
unblockSleepMode(SPI_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,13 +25,12 @@
|
||||||
#include "us_ticker_api.h"
|
#include "us_ticker_api.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_sleep.h"
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "em_timer.h"
|
#include "em_timer.h"
|
||||||
#include "clocking.h"
|
#include "clocking.h"
|
||||||
#include "sleep_api.h"
|
#include "sleep_api.h"
|
||||||
#include "sleepmodes.h"
|
|
||||||
|
|
||||||
#define TIMER_LEAST_ACTIVE_SLEEPMODE EM1
|
|
||||||
/**
|
/**
|
||||||
* Timer functions for microsecond ticker.
|
* Timer functions for microsecond ticker.
|
||||||
* mbed expects a 32-bit timer. Since the EFM32 only has 16-bit timers,
|
* mbed expects a 32-bit timer. Since the EFM32 only has 16-bit timers,
|
||||||
|
@ -161,7 +160,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
|
||||||
|
|
||||||
if((US_TICKER_TIMER->IEN & TIMER_IEN_CC0) == 0) {
|
if((US_TICKER_TIMER->IEN & TIMER_IEN_CC0) == 0) {
|
||||||
//Timer was disabled, but is going to be enabled. Set sleep mode.
|
//Timer was disabled, but is going to be enabled. Set sleep mode.
|
||||||
blockSleepMode(TIMER_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_lock_deep_sleep();
|
||||||
}
|
}
|
||||||
TIMER_IntDisable(US_TICKER_TIMER, TIMER_IEN_CC0);
|
TIMER_IntDisable(US_TICKER_TIMER, TIMER_IEN_CC0);
|
||||||
|
|
||||||
|
@ -218,7 +217,7 @@ void us_ticker_disable_interrupt(void)
|
||||||
{
|
{
|
||||||
if((US_TICKER_TIMER->IEN & TIMER_IEN_CC0) != 0) {
|
if((US_TICKER_TIMER->IEN & TIMER_IEN_CC0) != 0) {
|
||||||
//Timer was enabled, but is going to get disabled. Clear sleepmode.
|
//Timer was enabled, but is going to get disabled. Clear sleepmode.
|
||||||
unblockSleepMode(TIMER_LEAST_ACTIVE_SLEEPMODE);
|
sleep_manager_unlock_deep_sleep();
|
||||||
}
|
}
|
||||||
/* Disable compare channel interrupts */
|
/* Disable compare channel interrupts */
|
||||||
TIMER_IntDisable(US_TICKER_TIMER, TIMER_IEN_CC0);
|
TIMER_IntDisable(US_TICKER_TIMER, TIMER_IEN_CC0);
|
||||||
|
|
Loading…
Reference in New Issue