Skip to content

Commit 6410a69

Browse files
committed
Fix HSE source clock issue
Signed-off-by: Frederic.Pillon <[email protected]>
1 parent 03ed45a commit 6410a69

File tree

2 files changed

+56
-162
lines changed

2 files changed

+56
-162
lines changed

cores/arduino/stm32/rtc.c

+52-161
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ static RTC_HandleTypeDef RtcHandle = {0};
5151
static voidCallbackPtr RTCUserCallback = NULL;
5252
static void *callbackUserData = NULL;
5353

54+
static sourceClock_t clkSrc = LSI_CLOCK;
55+
static uint8_t HSEDiv = 0;
5456
static int8_t AsynchPrediv = -1; // 1 to 127
5557
static int16_t SynchPrediv = -1; // 0 to 32767
5658

@@ -96,6 +98,7 @@ static void RTC_setClock(sourceClock_t source)
9698
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
9799
Error_Handler();
98100
}
101+
clkSrc = LSE_CLOCK;
99102
} else if(source == HSE_CLOCK) {
100103
// Enable the clock if not already set by user.
101104
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) {
@@ -106,19 +109,54 @@ static void RTC_setClock(sourceClock_t source)
106109
Error_Handler();
107110
}
108111
}
109-
112+
/* HSE division factor for RTC clock must be set to ensure that
113+
* the clock supplied to the RTC is less than or equal to 1 MHz
114+
*/
110115
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
111116
#if defined(STM32F1xx)
117+
/* HSE max is 16 MHZ divided by 128 --> 125 KHz */
112118
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
113-
#elif defined(STM32L4xx) || defined(STM32F0xx) || defined(STM32F3xx)
119+
HSEDiv = 128;
120+
#elif defined(STM32F0xx) || defined(STM32F3xx) || defined(STM32L4xx)
114121
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32;
122+
HSEDiv = 32;
123+
#elif defined(STM32L0xx) || defined(STM32L1xx)
124+
if((HSE_VALUE/2) <= HSE_RTC_MAX) {
125+
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV2;
126+
HSEDiv = 2;
127+
} else if((HSE_VALUE/4) <= HSE_RTC_MAX) {
128+
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV4;
129+
HSEDiv = 4;
130+
} else if((HSE_VALUE/8) <= HSE_RTC_MAX) {
131+
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV8;
132+
HSEDiv = 8;
133+
} else if((HSE_VALUE/16) <= HSE_RTC_MAX) {
134+
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV16;
135+
HSEDiv = 16;
136+
}
137+
#elif defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32F7xx)
138+
/* Not defined for STM32Fxx */
139+
#ifndef RCC_RTCCLKSOURCE_HSE_DIVX
140+
#define RCC_RTCCLKSOURCE_HSE_DIVX 0x00000300U
141+
#endif
142+
for(HSEDiv = 2; HSEDiv<32; HSEDiv++) {
143+
if((HSE_VALUE/HSEDiv) <= HSE_RTC_MAX) {
144+
PeriphClkInit.RTCClockSelection = (HSEDiv<<16) | RCC_RTCCLKSOURCE_HSE_DIVX;
145+
break;
146+
}
147+
}
115148
#else
116-
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV8;
149+
#error "Unknown Family - could not define RTCClockSelection"
117150
#endif
151+
if((HSE_VALUE/HSEDiv) > HSE_RTC_MAX) {
152+
Error_Handler();
153+
}
154+
118155
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
119156
Error_Handler();
120157
}
121-
} else {
158+
clkSrc = HSE_CLOCK;
159+
} else if(source == LSI_CLOCK) {
122160
// Enable the clock if not already set by user.
123161
if(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
124162
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
@@ -134,6 +172,9 @@ static void RTC_setClock(sourceClock_t source)
134172
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
135173
Error_Handler();
136174
}
175+
clkSrc = LSI_CLOCK;
176+
} else {
177+
Error_Handler();
137178
}
138179

139180
__HAL_RCC_RTC_ENABLE();
@@ -179,167 +220,17 @@ static void RTC_getPrediv(uint32_t *asynch, uint32_t *synch)
179220
}
180221

181222
// Get clock frequency
182-
if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_LSE) {
223+
if(clkSrc == LSE_CLOCK) {
183224
clk = LSE_VALUE;
184225
}
185-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV2
186-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV2) {
187-
clk = HSE_VALUE / 2;
188-
}
189-
#endif
190-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV3
191-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV3) {
192-
clk = HSE_VALUE / 3;
193-
}
194-
#endif
195-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV4
196-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV4) {
197-
clk = HSE_VALUE / 4;
198-
}
199-
#endif
200-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV5
201-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV5) {
202-
clk = HSE_VALUE / 5;
203-
}
204-
#endif
205-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV6
206-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV6) {
207-
clk = HSE_VALUE / 6;
208-
}
209-
#endif
210-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV7
211-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV7) {
212-
clk = HSE_VALUE / 7;
213-
}
214-
#endif
215-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV8
216-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV8) {
217-
clk = HSE_VALUE / 8;
218-
}
219-
#endif
220-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV9
221-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV9) {
222-
clk = HSE_VALUE / 9;
223-
}
224-
#endif
225-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV10
226-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV10) {
227-
clk = HSE_VALUE / 10;
228-
}
229-
#endif
230-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV11
231-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV11) {
232-
clk = HSE_VALUE / 11;
233-
}
234-
#endif
235-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV12
236-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV12) {
237-
clk = HSE_VALUE / 12;
238-
}
239-
#endif
240-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV13
241-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV13) {
242-
clk = HSE_VALUE / 13;
243-
}
244-
#endif
245-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV14
246-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV14) {
247-
clk = HSE_VALUE / 14;
248-
}
249-
#endif
250-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV15
251-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV15) {
252-
clk = HSE_VALUE / 15;
253-
}
254-
#endif
255-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV16
256-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV16) {
257-
clk = HSE_VALUE / 16;
258-
}
259-
#endif
260-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV17
261-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV17) {
262-
clk = HSE_VALUE / 17;
263-
}
264-
#endif
265-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV18
266-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV18) {
267-
clk = HSE_VALUE / 18;
268-
}
269-
#endif
270-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV19
271-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV19) {
272-
clk = HSE_VALUE / 19;
273-
}
274-
#endif
275-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV20
276-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV20) {
277-
clk = HSE_VALUE / 20;
278-
}
279-
#endif
280-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV21
281-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV21) {
282-
clk = HSE_VALUE / 21;
283-
}
284-
#endif
285-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV22
286-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV22) {
287-
clk = HSE_VALUE / 22;
288-
}
289-
#endif
290-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV23
291-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV23) {
292-
clk = HSE_VALUE / 23;
293-
}
294-
#endif
295-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV24
296-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV24) {
297-
clk = HSE_VALUE / 24;
298-
}
299-
#endif
300-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV25
301-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV25) {
302-
clk = HSE_VALUE / 25;
303-
}
304-
#endif
305-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV26
306-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV26) {
307-
clk = HSE_VALUE / 26;
308-
}
309-
#endif
310-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV27
311-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV27) {
312-
clk = HSE_VALUE / 27;
313-
}
314-
#endif
315-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV28
316-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV28) {
317-
clk = HSE_VALUE / 28;
318-
}
319-
#endif
320-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV29
321-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV29) {
322-
clk = HSE_VALUE / 29;
323-
}
324-
#endif
325-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV30
326-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV30) {
327-
clk = HSE_VALUE / 30;
328-
}
329-
#endif
330-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV31
331-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV31) {
332-
clk = HSE_VALUE / 31;
333-
}
334-
#endif
335-
#ifdef RCC_RTCCLKSOURCE_HSE_DIV32
336-
else if(__HAL_RCC_GET_RTC_SOURCE() == RCC_RTCCLKSOURCE_HSE_DIV32) {
337-
clk = HSE_VALUE / 32;
338-
}
339-
#endif
340-
else {
226+
else if(clkSrc == LSI_CLOCK) {
341227
clk = LSI_VALUE;
342228
}
229+
else if(clkSrc == HSE_CLOCK) {
230+
clk = HSE_VALUE/HSEDiv;
231+
} else {
232+
Error_Handler();
233+
}
343234

344235
// Get prescalers
345236
if(clk > 0) {

cores/arduino/stm32/rtc.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ typedef enum {
8282
typedef void(*voidCallbackPtr)(void *);
8383

8484
/* Exported constants --------------------------------------------------------*/
85+
86+
#define HSE_RTC_MAX 1000000U
87+
8588
/* Ultra Low Power High (ULPH) density */
8689
#if defined(STM32L100xBA) || defined (STM32L151xBA) || defined (STM32L152xBA) ||\
8790
defined(STM32L100xC) || defined (STM32L151xC) || defined (STM32L152xC) ||\
@@ -112,7 +115,7 @@ typedef void(*voidCallbackPtr)(void *);
112115
#define IS_RTC_HOUR12(HOUR) IS_RTC_HOUR24(HOUR)
113116
#endif // defined(STM32F1xx) && !defined(IS_RTC_WEEKDAY)
114117

115-
// __HAL_RCC_GET_RTC_SOURCE is not defined for F2, F4 and F7
118+
// __HAL_RCC_GET_RTC_SOURCE is not defined for F2 and F4
116119
#ifndef __HAL_RCC_GET_RTC_SOURCE
117120
static uint32_t RTC_getSource(void) {
118121
RCC_PeriphCLKInitTypeDef *PeriphClkInit;

0 commit comments

Comments
 (0)