Skip to content

Commit

Permalink
Improvements on STM32 low power
Browse files Browse the repository at this point in the history
- Fix some registers set/reset.
- Remove void from nanoHAL_Uninitialize_C calls.
- Add missing configurations to wake from pin (STM32F7 series only).
- Remove setting code from CPU_SetPowerMode to pin and rtc blocks.
- Add code to SetPowerMode to freeze IWDG on STDBY (STM32F7 only).

Signed-off-by: José Simões <jose.simoes@eclo.solutions>
  • Loading branch information
josesimoes committed Jan 5, 2019
1 parent 7504274 commit 280f4c6
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,39 +97,85 @@ HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power::Ena
switch((WakeupPin)stack.Arg0().NumericByRef().u4)
{
#if defined(PWR_CSR_EWUP)

case WakeupPin_Pin1:
wakeUpPin = PWR_CSR_EWUP;

// need to config the respective EXTI line (PA0)
EXTI->IMR |= EXTI_IMR_IM0;
EXTI->RTSR |= EXTI_RTSR_TR0;

break;

#elif defined(PWR_CSR_EWUP1)

case WakeupPin_Pin1:
wakeUpPin = PWR_CSR_EWUP1;
// need to config the respective EXTI line (PA0)
EXTI->IMR |= EXTI_IMR_IM0;
EXTI->RTSR |= EXTI_RTSR_TR0;
break;

#elif defined(PWR_CSR2_EWUP1)

case WakeupPin_Pin1:
wakeUpPin = PWR_CSR2_EWUP1;

// need to config the respective EXTI line (PA0)
EXTI->IMR |= EXTI_IMR_IM0;
EXTI->RTSR |= EXTI_RTSR_TR0;

break;

#else
#error "missing include for STM32 target PAL"
#endif

#if defined(PWR_CSR_EWUP2)

case WakeupPin_Pin2:
wakeUpPin = PWR_CSR_EWUP2;

// need to config the respective EXTI line (PA2)
EXTI->IMR |= EXTI_IMR_IM2;
EXTI->RTSR |= EXTI_RTSR_TR2;
break;

#elif defined(PWR_CSR2_EWUP2)

case WakeupPin_Pin2:
wakeUpPin = PWR_CSR2_EWUP2;

// need to config the respective EXTI line (PA2)
EXTI->IMR |= EXTI_IMR_IM2;
EXTI->RTSR |= EXTI_RTSR_TR2;

break;

#endif

#if defined(PWR_CSR_EWUP3)

case WakeupPin_Pin3:
wakeUpPin = PWR_CSR_EWUP3;

// need to config the respective EXTI line (PC1)
EXTI->IMR |= EXTI_IMR_IM1;
EXTI->RTSR |= EXTI_RTSR_TR1;

break;

#elif defined(PWR_CSR2_EWUP3)

case WakeupPin_Pin3:
wakeUpPin = PWR_CSR2_EWUP3;

// need to config the respective EXTI line (PC1)
EXTI->IMR |= EXTI_IMR_IM1;
EXTI->RTSR |= EXTI_RTSR_TR1;

break;

#endif

default:
Expand All @@ -141,6 +187,8 @@ HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power::Ena

#if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F2XX) || \
defined(STM32F3XX) ||defined(STM32F4XX) || defined(STM32L0XX) || defined(STM32L1XX)
// clear PWR wake up Flag
PWR->CR |= PWR_CSR_WUF;

// disable the wake up pin
CLEAR_BIT(PWR->CSR, wakeUpPin);
Expand All @@ -151,15 +199,16 @@ HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power::Ena
#endif

#if defined(STM32F7XX) || defined(STM32H7XX) || defined(STM32L4XX)
// clear PWR wake up Flag
PWR->CR1 |= PWR_CR1_CSBF;

// disable the wake up pin
CLEAR_BIT(PWR->CSR1, wakeUpPin);
CLEAR_BIT(PWR->CSR2, wakeUpPin);

// enable the wake up pin
SET_BIT(PWR->CSR1, wakeUpPin);

#endif
SET_BIT(PWR->CSR2, wakeUpPin);

#endif

NANOCLR_NOCLEANUP();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,24 @@ HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC::Nativ

alarmTime.alrmr = alarmRegister;

#else
#error "Setting an alarm for this series in not supported. Care to look into it and submit a PR?"
#endif
#else
#error "Setting an alarm for this series in not supported. Care to look into it and submit a PR?"
#endif

#if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F2XX) || \
defined(STM32F3XX) ||defined(STM32F4XX) || defined(STM32L0XX) || defined(STM32L1XX)
// clear PWR wake up Flag
PWR->CR |= PWR_CSR_WUF;
#endif

#if defined(STM32F7XX) || defined(STM32H7XX) || defined(STM32L4XX)
// clear PWR wake up Flag
PWR->CR1 |= PWR_CR1_CSBF;

EXTI->EMR |= EXTI_IMR_IM17;
EXTI->RTSR |= EXTI_RTSR_TR17;

#endif

rtcSetAlarm(&RTCD1, ALARM_ID, &alarmTime);

Expand Down
2 changes: 1 addition & 1 deletion targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern "C" {

void nanoHAL_Uninitialize_C()
{
void nanoHAL_Uninitialize();
nanoHAL_Uninitialize();
}
}

Expand Down
66 changes: 61 additions & 5 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Power.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents) { (void)level

void CPU_SetPowerMode(PowerLevel_type powerLevel)
{
// default to false
bool success = false;

switch(powerLevel)
{
case PowerLevel__Off:
Expand All @@ -30,18 +33,71 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel)

chSysDisable();

// set power controll register to power down deep sleep
/////////////////////////////////////////////////////////////////////////
// stop the idependent watchdog, for series where the option is available
#if defined(STM32L4XX)

(void)success;
// TODO FIXME this code needs to follow the same workflow as the STM32F7
CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_IWDG_STDBY);

#elif defined(STM32F7XX)

// only need to change this option bit if not already done
if(!(FLASH->OPTCR & ~FLASH_OPTCR_IWDG_STDBY))
{
// developer notes:
// follow workflow recommended @ 3.4.2 Option bytes programming (from programming manual)
// Authorizes the Option Byte register programming
FLASH->OPTKEYR = FLASH_OPT_KEY1;
FLASH->OPTKEYR = FLASH_OPT_KEY2;

// wait 500ms for any flash operation to be completed
success = FLASH_WaitForLastOperation(500);

if(success)
{
// write option value (clear the FLASH_OPTCR_IWDG_STDBY)
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_IWDG_STDBY);

// set the option start bit
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;

// Data synchronous Barrier, forcing the CPU to respect the sequence of instruction without optimization
__DSB();

// wait 100ms for the flash operation to be completed
success = FLASH_WaitForLastOperation(100);
}

// Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
}

#elif defined(STM32H7XX)

(void)success;
// TODO FIXME this code needs to follow the same workflow as the STM32F7
CLEAR_BIT(FLASH->OPTSR, FLASH_OPTSR_FZ_IWDG_SDBY);

#else
(void)success;
#endif

///////////////////////////////////////////////////////
// set power control register to: power down deep sleep
#if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F2XX) || \
defined(STM32F3XX) ||defined(STM32F4XX) || defined(STM32L0XX) || defined(STM32L1XX)

SET_BIT(PWR->CR, PWR_CR_PDDS);

#endif

#if defined(STM32F7XX) || defined(STM32H7XX) || defined(STM32L4XX)

#if defined(STM32F7XX)
CLEAR_BIT(PWR->CSR1, PWR_CSR1_WUIF);
SET_BIT(PWR->CR1, PWR_CR1_PDDS);
#endif

#if defined(STM32H7XX)
SET_BIT(PWR->CR1, PWR_CR1_PDDS);
#endif

// set SLEEPDEEP bit of Cortex SCR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ typedef struct SMT32FlashDriver {
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET)
#define FLASH_KEY1 ((uint32_t)0x45670123U)
#define FLASH_KEY2 ((uint32_t)0xCDEF89ABU)
#define FLASH_OPT_KEY1 ((uint32_t)0x08192A3BU)
#define FLASH_OPT_KEY2 ((uint32_t)0x4C5D6E7FU)
#define SECTOR_MASK ((uint32_t)0xFFFFFF07)

// FLASH_Error_Code FLASH Error Code
Expand Down Expand Up @@ -426,7 +428,10 @@ SMT32FlashDriver STM32FLASH;
#ifdef __cplusplus
extern "C" {
#endif

bool HAL_FLASH_Unlock(void);
void HAL_FLASH_Lock(void);
bool FLASH_WaitForLastOperation(uint32_t timeout);

void flash_lld_init();
void flash_lld_readBytes(uint32_t startAddress, uint32_t length, uint8_t* buffer);
int flash_lld_write(uint32_t startAddress, uint32_t length, const uint8_t* buffer);
Expand Down
2 changes: 1 addition & 1 deletion targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern "C" {

void nanoHAL_Uninitialize_C()
{
void nanoHAL_Uninitialize();
nanoHAL_Uninitialize();
}
}

Expand Down

0 comments on commit 280f4c6

Please sign in to comment.