Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 05b8a54

Browse files
author
fpr
committedApr 26, 2018
Add low power driver
Signed-off-by: fpr <[email protected]>
1 parent eb61637 commit 05b8a54

File tree

3 files changed

+407
-0
lines changed

3 files changed

+407
-0
lines changed
 

‎cores/arduino/board.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C"{
1414
#include "digital_io.h"
1515
#include "hal_uart_emul.h"
1616
#include "hw_config.h"
17+
#include "LowPower.h"
1718
#include "spi_com.h"
1819
#include "stm32_eeprom.h"
1920
#include "timer.h"

‎cores/arduino/stm32/LowPower.c

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
/**
2+
******************************************************************************
3+
* @file LowPower.c
4+
* @author WI6LABS
5+
* @version V1.0.0
6+
* @date 17 - November -2017
7+
* @brief Provides a Low Power interface
8+
*
9+
******************************************************************************
10+
* @attention
11+
*
12+
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
13+
*
14+
* Redistribution and use in source and binary forms, with or without modification,
15+
* are permitted provided that the following conditions are met:
16+
* 1. Redistributions of source code must retain the above copyright notice,
17+
* this list of conditions and the following disclaimer.
18+
* 2. Redistributions in binary form must reproduce the above copyright notice,
19+
* this list of conditions and the following disclaimer in the documentation
20+
* and/or other materials provided with the distribution.
21+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
22+
* may be used to endorse or promote products derived from this software
23+
* without specific prior written permission.
24+
*
25+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*
36+
******************************************************************************
37+
*/
38+
39+
#include "Arduino.h"
40+
#include "LowPower.h"
41+
42+
#ifdef HAL_PWR_MODULE_ENABLED
43+
44+
#ifdef __cplusplus
45+
extern "C" {
46+
#endif
47+
48+
// NOTE: is these pins are common to a MCU family?
49+
/* Wakeup pins list. Allow to know which pins can be used as wake up pin in
50+
standby or shutdown mode */
51+
#if defined(STM32L053xx)
52+
const PinMap PinMap_WKUP[] = {
53+
{PA_0, NP, 1}, //WKUP1
54+
{PC_13, NP, 2}, //WKUP2
55+
{NC, NP, 0}
56+
};
57+
#elif defined(STM32L476xx)
58+
const PinMap PinMap_WKUP[] = {
59+
{PA_0, NP, 1}, //WKUP1
60+
{PC_13, NP, 2}, //WKUP2
61+
{PE_6, NP, 3}, //WKUP3
62+
{PA_2, NP, 4}, //WKUP4
63+
{PC_5, NP, 5}, //WKUP5
64+
{NC, NP, 0}
65+
};
66+
#else
67+
const PinMap PinMap_WKUP[] = {
68+
{NC, NP, 0}
69+
};
70+
#endif
71+
72+
// Save UART handler for callback
73+
static UART_HandleTypeDef* WakeUpUart = NULL;
74+
// Save callback pointer
75+
static void (*WakeUpUartCb)( void ) = NULL;
76+
77+
/**
78+
* @brief Initialize low power mode
79+
* @param None
80+
* @retval None
81+
*/
82+
void LowPower_init(){
83+
/* Enable Power Clock */
84+
__HAL_RCC_PWR_CLK_ENABLE();
85+
86+
/* Ensure that HSI is wake-up system clock */
87+
#if defined(STM32L0xx) || defined(STM32L4xx)
88+
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
89+
#endif // STM32L0xx || STM32L4xx
90+
91+
/* Check if the system was resumed from StandBy mode */
92+
if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
93+
{
94+
/* Clear Standby flag */
95+
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
96+
}
97+
98+
/* Clear all related wakeup flags */
99+
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
100+
}
101+
102+
/**
103+
* @brief Configure a pin as wakeup source if compatible.
104+
* @param pin: pin to configure
105+
* @param mode: pin mode (edge or state). The configuration have to be compatible.
106+
* @retval None
107+
*/
108+
void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode) {
109+
#ifndef STM32L4xx
110+
UNUSED(mode);
111+
#endif
112+
PinName p = digitalPinToPinName(pin);
113+
uint32_t wupPin = pinmap_find_function(p, PinMap_WKUP);
114+
switch (wupPin) {
115+
#ifdef PWR_WAKEUP_PIN1
116+
case 1 :
117+
#ifdef STM32L4xx
118+
if (mode == RISING) {
119+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_HIGH);
120+
}
121+
else {
122+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_LOW);
123+
}
124+
#else
125+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
126+
#endif
127+
break;
128+
#endif //PWR_WAKEUP_PIN1
129+
#ifdef PWR_WAKEUP_PIN2
130+
case 2 :
131+
#ifdef STM32L4xx
132+
if (mode == RISING) {
133+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_HIGH);
134+
}
135+
else {
136+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);
137+
}
138+
#else
139+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2);
140+
#endif
141+
break;
142+
#endif //PWR_WAKEUP_PIN2
143+
#ifdef PWR_WAKEUP_PIN3
144+
case 3 :
145+
#ifdef STM32L4xx
146+
if (mode == RISING) {
147+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN3_HIGH);
148+
}
149+
else {
150+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN3_LOW);
151+
}
152+
#else
153+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN3);
154+
#endif
155+
break;
156+
#endif //PWR_WAKEUP_PIN3
157+
#ifdef PWR_WAKEUP_PIN4
158+
case 4 :
159+
#ifdef STM32L4xx
160+
if (mode == RISING) {
161+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4_HIGH);
162+
}
163+
else {
164+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4_LOW);
165+
}
166+
#else
167+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4);
168+
#endif
169+
break;
170+
#endif //PWR_WAKEUP_PIN4
171+
#ifdef PWR_WAKEUP_PIN5
172+
case 5 :
173+
#ifdef STM32L4xx
174+
if (mode == RISING) {
175+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN5_HIGH);
176+
}
177+
else {
178+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN5_LOW);
179+
}
180+
#else
181+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN5);
182+
#endif
183+
break;
184+
#endif //PWR_WAKEUP_PIN5
185+
default :
186+
break;
187+
}
188+
}
189+
190+
/**
191+
* @brief Enable the sleep mode.
192+
* @param None
193+
* @retval None
194+
*/
195+
void LowPower_sleep(uint32_t regulator){
196+
__disable_irq();
197+
/*Suspend Tick increment to prevent wakeup by Systick interrupt.
198+
Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
199+
HAL_SuspendTick();
200+
201+
/* Enter Sleep Mode , wake up is done once User push-button is pressed */
202+
HAL_PWR_EnterSLEEPMode(regulator, PWR_SLEEPENTRY_WFI);
203+
204+
/* Resume Tick interrupt if disabled prior to SLEEP mode entry */
205+
HAL_ResumeTick();
206+
__enable_irq();
207+
208+
if (WakeUpUartCb != NULL) {
209+
WakeUpUartCb();
210+
}
211+
}
212+
213+
/**
214+
* @brief Enable the stop mode.
215+
* @param None
216+
* @retval None
217+
*/
218+
void LowPower_stop(){
219+
__disable_irq();
220+
221+
#if STM32L4xx
222+
if (WakeUpUart != NULL) {
223+
HAL_UARTEx_EnableStopMode(WakeUpUart);
224+
}
225+
#endif
226+
227+
#ifdef STM32L0xx
228+
/* Enable Ultra low power mode */
229+
HAL_PWREx_EnableUltraLowPower();
230+
231+
/* Enable the fast wake up from Ultra low power mode */
232+
HAL_PWREx_EnableFastWakeUp();
233+
234+
/* Select HSI as system clock source after Wake Up from Stop mode */
235+
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
236+
#endif
237+
238+
// Enter Stop mode
239+
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
240+
241+
// Exit Stop mode reset clocks
242+
SystemClock_Config();
243+
__enable_irq();
244+
245+
#if STM32L4xx
246+
if (WakeUpUart != NULL) {
247+
HAL_UARTEx_DisableStopMode(WakeUpUart);
248+
249+
if (WakeUpUartCb != NULL) {
250+
WakeUpUartCb();
251+
}
252+
}
253+
#endif
254+
}
255+
256+
/**
257+
* @brief Enable the standby mode. The board reset when leaves this mode.
258+
* @param None
259+
* @retval None
260+
*/
261+
void LowPower_standby(){
262+
__disable_irq();
263+
264+
#ifdef STM32L0xx
265+
/* Enable Ultra low power mode */
266+
HAL_PWREx_EnableUltraLowPower();
267+
268+
/* Enable the fast wake up from Ultra low power mode */
269+
HAL_PWREx_EnableFastWakeUp();
270+
#endif
271+
272+
HAL_PWR_EnterSTANDBYMode();
273+
}
274+
275+
/**
276+
* @brief Enable the shutdown mode.The board reset when leaves this mode.
277+
* If shutdown mode not available, use standby mode instead.
278+
* @param None
279+
* @retval None
280+
*/
281+
void LowPower_shutdown(){
282+
__disable_irq();
283+
#ifdef STM32L4xx
284+
// LSE must be on to use shutdown mode
285+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == SET) {
286+
HAL_PWREx_EnterSHUTDOWNMode();
287+
} else {
288+
LowPower_standby();
289+
}
290+
#else
291+
LowPower_standby();
292+
#endif
293+
}
294+
295+
/**
296+
* @brief Configure the UART as a wakeup source. A callback can be called when
297+
* the chip leaves the low power mode. See board datasheet to check
298+
* with which low power mode the UART is compatible.
299+
* @param serial: pointer to serial
300+
* @param FuncPtr: pointer to callback
301+
* @retval None
302+
*/
303+
void LowPower_EnableWakeUpUart(serial_t* serial, void (*FuncPtr)( void ) ) {
304+
#if defined(STM32L0xx) || defined(STM32L4xx)
305+
UART_WakeUpTypeDef WakeUpSelection;
306+
307+
// Save Uart handler
308+
WakeUpUart = &(serial->handle);
309+
310+
// Save callback
311+
WakeUpUartCb = FuncPtr;
312+
313+
/* make sure that no UART transfer is on-going */
314+
while(__HAL_UART_GET_FLAG(WakeUpUart, USART_ISR_BUSY) == SET);
315+
/* make sure that UART is ready to receive
316+
* (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */
317+
while(__HAL_UART_GET_FLAG(WakeUpUart, USART_ISR_REACK) == RESET);
318+
319+
/* set the wake-up event:
320+
* specify wake-up on RXNE flag */
321+
WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;
322+
HAL_UARTEx_StopModeWakeUpSourceConfig(WakeUpUart, WakeUpSelection);
323+
324+
/* Enable the UART Wake UP from STOP1 mode Interrupt */
325+
__HAL_UART_ENABLE_IT(WakeUpUart, UART_IT_WUF);
326+
#endif // STM32L0xx || STM32L4xx
327+
}
328+
329+
#ifdef __cplusplus
330+
}
331+
#endif
332+
333+
#endif // HAL_PWR_MODULE_ENABLED
334+
335+
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

‎cores/arduino/stm32/LowPower.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
******************************************************************************
3+
* @file LowPower.h
4+
* @author WI6LABS
5+
* @version V1.0.0
6+
* @date 17 - November -2017
7+
* @brief Header for Low Power module
8+
******************************************************************************
9+
* @attention
10+
*
11+
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
12+
*
13+
* Redistribution and use in source and binary forms, with or without modification,
14+
* are permitted provided that the following conditions are met:
15+
* 1. Redistributions of source code must retain the above copyright notice,
16+
* this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and/or other materials provided with the distribution.
20+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
21+
* may be used to endorse or promote products derived from this software
22+
* without specific prior written permission.
23+
*
24+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34+
*
35+
******************************************************************************
36+
*/
37+
38+
/* Define to prevent recursive inclusion -------------------------------------*/
39+
#ifndef __LOW_POWER_H
40+
#define __LOW_POWER_H
41+
42+
/* Includes ------------------------------------------------------------------*/
43+
#include "stm32_def.h"
44+
#include "uart.h"
45+
46+
#ifdef HAL_PWR_MODULE_ENABLED
47+
48+
#ifdef __cplusplus
49+
extern "C" {
50+
#endif
51+
52+
/* Exported types ------------------------------------------------------------*/
53+
/* Exported constants --------------------------------------------------------*/
54+
/* Exported macro ------------------------------------------------------------*/
55+
/* Exported functions ------------------------------------------------------- */
56+
57+
void LowPower_init();
58+
void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode);
59+
void LowPower_EnableWakeUpUart(serial_t* serial, void (*FuncPtr)( void ) );
60+
void LowPower_sleep(uint32_t regulator);
61+
void LowPower_stop();
62+
void LowPower_standby();
63+
void LowPower_shutdown();
64+
65+
#ifdef __cplusplus
66+
}
67+
#endif
68+
69+
#endif // HAL_PWR_MODULE_ENABLED
70+
71+
#endif /* __LOW_POWER_H */

0 commit comments

Comments
 (0)
Please sign in to comment.