Skip to content

Commit abf9850

Browse files
authored
Merge pull request #1796 from BartSX/lptickerF0
[STM32F0xx] LowPowerTicker implementation
2 parents a07a118 + 4b5a317 commit abf9850

File tree

4 files changed

+274
-4
lines changed

4 files changed

+274
-4
lines changed

hal/targets.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@
569569
"inherits": ["Target"],
570570
"progen": {"target": "nucleo-f030r8"},
571571
"detect_code": ["0725"],
572-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
572+
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
573573
"default_build": "small"
574574
},
575575
"NUCLEO_F031K6": {
@@ -605,7 +605,7 @@
605605
"inherits": ["Target"],
606606
"progen": {"target": "nucleo-f070rb"},
607607
"detect_code": ["0755"],
608-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
608+
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
609609
"default_build": "small"
610610
},
611611
"NUCLEO_F072RB": {
@@ -617,7 +617,7 @@
617617
"inherits": ["Target"],
618618
"progen": {"target": "nucleo-f072rb"},
619619
"detect_code": ["0730"],
620-
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
620+
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
621621
"default_build": "small"
622622
},
623623
"NUCLEO_F091RC": {
@@ -629,7 +629,7 @@
629629
"inherits": ["Target"],
630630
"progen": {"target": "nucleo-f091rc"},
631631
"detect_code": ["0750"],
632-
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
632+
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
633633
"default_build": "small"
634634
},
635635
"NUCLEO_F103RB": {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* mbed Microcontroller Library
2+
*******************************************************************************
3+
* Copyright (c) 2016, STMicroelectronics
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice,
10+
* this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
15+
* may be used to endorse or promote products derived from this software
16+
* without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*******************************************************************************
29+
*/
30+
#include "device.h"
31+
32+
#if DEVICE_LOWPOWERTIMER
33+
34+
#include "ticker_api.h"
35+
#include "lp_ticker_api.h"
36+
#include "rtc_api.h"
37+
#include "rtc_api_hal.h"
38+
39+
static uint8_t lp_ticker_inited = 0;
40+
static uint8_t lp_ticker_reconf_presc = 0;
41+
42+
void lp_ticker_init() {
43+
if (lp_ticker_inited) return;
44+
lp_ticker_inited = 1;
45+
46+
rtc_init();
47+
rtc_set_irq_handler((uint32_t) lp_ticker_irq_handler);
48+
}
49+
50+
uint32_t lp_ticker_read() {
51+
uint32_t sub_secs, milis;
52+
time_t time;
53+
54+
lp_ticker_init();
55+
56+
time = rtc_read();
57+
sub_secs = rtc_read_subseconds();
58+
milis = 1000 - (sub_secs * 1000 / rtc_ticker_get_synch_presc());
59+
60+
return (time * 1000000) + (milis * 1000);
61+
}
62+
63+
void lp_ticker_set_interrupt(timestamp_t timestamp) {
64+
uint32_t sub_secs, delta, milis;
65+
time_t secs;
66+
struct tm *timeinfo;
67+
68+
// Reconfigure RTC prescalers whenever the timestamp is below 30ms
69+
if (!lp_ticker_reconf_presc && timestamp < 30000) {
70+
rtc_reconfigure_prescalers();
71+
lp_ticker_reconf_presc = 1;
72+
}
73+
74+
milis = (timestamp % 1000000) / 1000;
75+
76+
secs = rtc_read();
77+
delta = ((timestamp / 1000000) - secs);
78+
79+
secs += delta;
80+
sub_secs = (rtc_ticker_get_synch_presc() * (1000 - milis)) / 1000;
81+
timeinfo = localtime(&secs);
82+
83+
rtc_set_alarm(timeinfo, sub_secs);
84+
}
85+
86+
void lp_ticker_disable_interrupt() {
87+
lp_ticker_reconf_presc = 0;
88+
rtc_ticker_disable_irq();
89+
}
90+
91+
void lp_ticker_clear_interrupt() {
92+
}
93+
94+
#endif

hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
*******************************************************************************
2929
*/
3030
#include "rtc_api.h"
31+
#include "rtc_api_hal.h"
32+
#include "stm32f0xx.h"
33+
#include "stm32f0xx_hal_rtc_ex.h"
3134

3235
#if DEVICE_RTC
3336

@@ -39,6 +42,57 @@ static int rtc_inited = 0;
3942

4043
static RTC_HandleTypeDef RtcHandle;
4144

45+
#if DEVICE_LOWPOWERTIMER
46+
static uint32_t m_synch_prediv = RTC_SYNCH_PREDIV;
47+
static uint32_t m_asynch_prediv = RTC_ASYNCH_PREDIV;
48+
49+
static void (*irq_handler)(void);
50+
51+
static void rtc_configure_time_and_date()
52+
{
53+
RTC_TimeTypeDef mTime;
54+
RTC_DateTypeDef mDate;
55+
56+
mDate.WeekDay = 1;
57+
mDate.Month = 1;
58+
mDate.Date = 1;
59+
mDate.Year = 1970;
60+
if (HAL_RTC_SetDate(&RtcHandle, &mDate, RTC_FORMAT_BIN) != HAL_OK) {
61+
error("Date set failed\n");
62+
}
63+
64+
mTime.Hours = 0;
65+
mTime.Minutes = 0;
66+
mTime.Seconds = 0;
67+
mTime.TimeFormat = RTC_HOURFORMAT12_AM;
68+
mTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
69+
mTime.StoreOperation = RTC_STOREOPERATION_RESET;
70+
if (HAL_RTC_SetTime(&RtcHandle, &mTime, RTC_FORMAT_BIN) != HAL_OK) {
71+
error("Time set failed\n");
72+
}
73+
}
74+
75+
void RTC_IRQHandler()
76+
{
77+
HAL_RTC_AlarmIRQHandler(&RtcHandle);
78+
}
79+
80+
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
81+
{
82+
if (irq_handler)
83+
{
84+
// Fire the user callback
85+
irq_handler();
86+
}
87+
}
88+
89+
void rtc_set_irq_handler(uint32_t handler)
90+
{
91+
irq_handler = (void (*)(void)) handler;
92+
}
93+
94+
#endif
95+
4296
void rtc_init(void) {
4397
RCC_OscInitTypeDef RCC_OscInitStruct;
4498
uint32_t rtc_freq = 0;
@@ -92,15 +146,27 @@ void rtc_init(void) {
92146
__HAL_RCC_RTC_ENABLE();
93147

94148
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
149+
#if !DEVICE_LOWPOWERTIMER
95150
RtcHandle.Init.AsynchPrediv = 127;
96151
RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1;
152+
#else
153+
RtcHandle.Init.AsynchPrediv = m_asynch_prediv;
154+
RtcHandle.Init.SynchPrediv = m_synch_prediv;
155+
#endif
156+
97157
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
98158
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
99159
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
100160

101161
if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
102162
error("RTC error: RTC initialization failed.");
103163
}
164+
165+
#if DEVICE_LOWPOWERTIMER
166+
rtc_configure_time_and_date();
167+
NVIC_SetVector(RTC_IRQn, (uint32_t)&RTC_IRQHandler);
168+
HAL_NVIC_EnableIRQ(RTC_IRQn);
169+
#endif
104170
}
105171

106172
void rtc_free(void) {
@@ -177,7 +243,12 @@ time_t rtc_read(void) {
177243
timeinfo.tm_wday = dateStruct.WeekDay;
178244
timeinfo.tm_mon = dateStruct.Month - 1;
179245
timeinfo.tm_mday = dateStruct.Date;
246+
#if DEVICE_LOWPOWERTIMER
247+
//We need to add 52 to get the 1970 year
248+
timeinfo.tm_year = dateStruct.Year + 52;
249+
#else
180250
timeinfo.tm_year = dateStruct.Year + 100;
251+
#endif
181252
timeinfo.tm_hour = timeStruct.Hours;
182253
timeinfo.tm_min = timeStruct.Minutes;
183254
timeinfo.tm_sec = timeStruct.Seconds;
@@ -215,4 +286,48 @@ void rtc_write(time_t t) {
215286
HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
216287
}
217288

289+
#if DEVICE_LOWPOWERTIMER
290+
void rtc_set_alarm(struct tm *ti, uint32_t subsecs)
291+
{
292+
RTC_AlarmTypeDef mAlarm;
293+
294+
mAlarm.AlarmTime.Hours = ti->tm_hour;
295+
mAlarm.AlarmTime.Minutes = ti->tm_min;
296+
mAlarm.AlarmTime.Seconds = ti->tm_sec;
297+
mAlarm.AlarmTime.SubSeconds = subsecs;
298+
mAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
299+
mAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
300+
mAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
301+
mAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
302+
mAlarm.AlarmDateWeekDay = 1;
303+
mAlarm.Alarm = RTC_ALARM_A;
304+
305+
if (HAL_RTC_SetAlarm_IT(&RtcHandle, &mAlarm, RTC_FORMAT_BIN) != HAL_OK) {
306+
error("Set Alarm failed\n");
307+
}
308+
}
309+
310+
void rtc_reconfigure_prescalers()
311+
{
312+
m_synch_prediv = 0x3FF;
313+
m_asynch_prediv = 0x1F;
314+
rtc_init();
315+
}
316+
317+
uint32_t rtc_ticker_get_synch_presc()
318+
{
319+
return m_synch_prediv;
320+
}
321+
322+
uint32_t rtc_read_subseconds()
323+
{
324+
return RTC->SSR;
325+
}
326+
327+
void rtc_ticker_disable_irq()
328+
{
329+
HAL_RTC_DeactivateAlarm(&RtcHandle, RTC_ALARM_A);
330+
}
331+
#endif // DEVICE_LOWPOWERTIMER
332+
218333
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* mbed Microcontroller Library
2+
*******************************************************************************
3+
* Copyright (c) 2016, STMicroelectronics
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice,
10+
* this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
15+
* may be used to endorse or promote products derived from this software
16+
* without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*******************************************************************************
29+
*/
30+
31+
#ifndef MBED_RTC_API_HAL_H
32+
#define MBED_RTC_API_HAL_H
33+
34+
#include <stdint.h>
35+
#include "rtc_api.h"
36+
37+
#ifdef __cplusplus
38+
extern "C" {
39+
#endif
40+
/*
41+
* Extend rtc_api.h
42+
*/
43+
44+
// Prescaler values for LSE clock
45+
#define RTC_ASYNCH_PREDIV 0x7F
46+
#define RTC_SYNCH_PREDIV 0x00FF
47+
48+
void rtc_set_irq_handler(uint32_t handler);
49+
50+
void rtc_ticker_disable_irq();
51+
uint32_t rtc_ticker_get_synch_presc();
52+
53+
void rtc_set_alarm(struct tm *ti, uint32_t subsecs);
54+
uint32_t rtc_read_subseconds();
55+
void rtc_reconfigure_prescalers();
56+
57+
#ifdef __cplusplus
58+
}
59+
#endif
60+
61+
#endif

0 commit comments

Comments
 (0)