Skip to content

Commit 87a1b9d

Browse files
committed
fix[gd32][rtc]: Fix the initialization logic of the RTC clock and the issue of default triggering of the alarm interrupt.
1 parent 6f10e55 commit 87a1b9d

File tree

1 file changed

+46
-111
lines changed

1 file changed

+46
-111
lines changed

bsp/gd32/arm/libraries/gd32_drivers/drv_rtc.c

Lines changed: 46 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <board.h>
1414
#include <rtdevice.h>
1515
#include <rthw.h>
16+
#include <sys/time.h>
1617

1718
#define DBG_TAG "drv.rtc"
1819
#define DBG_LVL DBG_INFO
@@ -29,9 +30,11 @@
2930
#elif defined(BSP_USING_ALARM0)
3031
#define BSP_ALARM_FLAG RTC_FLAG_ALARM0
3132
#define BSP_RTC_ALARM RTC_ALARM0
33+
#define BSP_RTC_INT_ALARM RTC_INT_ALARM0
3234
#elif defined(BSP_USING_ALARM1)
3335
#define BSP_ALARM_FLAG RTC_FLAG_ALARM1
3436
#define BSP_RTC_ALARM RTC_ALARM1
37+
#define BSP_RTC_INT_ALARM RTC_INT_ALARM1
3538
#endif
3639
#endif
3740

@@ -87,64 +90,32 @@ void RTC_Alarm_IRQHandler(void)
8790
{
8891
/* Clear alarm flag */
8992
rtc_flag_clear(RTC_FLAG_ALARM0);
90-
91-
/* Clear EXTI line 17 flag */
9293
exti_flag_clear(EXTI_17);
9394

9495
/* Notify RTC framework about alarm event */
9596
if (g_rtc_device != RT_NULL)
9697
{
9798
rt_alarm_update(g_rtc_device, 1);
9899
}
99-
100100
LOG_D("RTC Alarm0 triggered");
101101
}
102102

103-
/* Check if alarm1 interrupt occurred */
104103
if (rtc_flag_get(RTC_FLAG_ALARM1) != RESET)
105104
{
106105
/* Clear alarm flag */
107106
rtc_flag_clear(RTC_FLAG_ALARM1);
108-
109-
/* Clear EXTI line 17 flag */
110107
exti_flag_clear(EXTI_17);
111108

112109
/* Notify RTC framework about alarm event */
113110
if (g_rtc_device != RT_NULL)
114111
{
115112
rt_alarm_update(g_rtc_device, 1);
116113
}
117-
118114
LOG_D("RTC Alarm1 triggered");
119115
}
120116

121-
122117
rt_interrupt_leave();
123118
}
124-
125-
/**
126-
* @brief Initialize RTC alarm interrupt
127-
*/
128-
static void rtc_alarm_interrupt_init(void)
129-
{
130-
/* Clear any pending alarm flag first */
131-
rtc_flag_clear(RTC_FLAG_ALARM0);
132-
rtc_flag_clear(RTC_FLAG_ALARM1);
133-
134-
/* Clear EXTI line 17 flag */
135-
exti_flag_clear(EXTI_17);
136-
137-
/* Configure EXTI line 17 for RTC alarm interrupt */
138-
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
139-
140-
/* Enable RTC alarm interrupt */
141-
rtc_interrupt_enable(RTC_INT_ALARM0);
142-
143-
/* Enable RTC Alarm global interrupt in NVIC */
144-
nvic_irq_enable(RTC_Alarm_IRQn, 0, 0);
145-
146-
LOG_D("RTC alarm interrupt initialized with EXTI configuration");
147-
}
148119
#endif /* RT_USING_ALARM */
149120

150121
static rt_err_t gd_rtc_init(void)
@@ -181,48 +152,18 @@ static rt_err_t gd_rtc_init(void)
181152
#endif
182153
}
183154

184-
#if defined (RTC_CLOCK_SOURCE_LXTAL)
185155
/* Use LSE (32.768kHz) as RTC clock source */
156+
#define PRESCALER_S 0xFF
157+
#define PRESCALER_A 0x7F
158+
159+
rcu_osci_on(RCU_LXTAL);
186160
if (rcu_osci_stab_wait(RCU_LXTAL) != SUCCESS)
187161
{
188-
rcu_osci_on(RCU_LXTAL);
189-
if (rcu_osci_stab_wait(RCU_LXTAL) != SUCCESS)
190-
{
191-
LOG_E("LSE oscillator failed to stabilize");
192-
return -RT_ERROR;
193-
}
162+
LOG_E("LSE oscillator failed to stabilize");
163+
return -RT_ERROR;
194164
}
195165
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
196166
LOG_D("RTC clock source: LSE (32.768kHz)");
197-
#elif defined(RTC_CLOCK_SOURCE_IRC32K)
198-
/* Use LSI (40kHz) as RTC clock source */
199-
if (rcu_osci_stab_wait(RCU_IRC32K) != SUCCESS)
200-
{
201-
rcu_osci_on(RCU_IRC32K);
202-
if (rcu_osci_stab_wait(RCU_IRC32K) != SUCCESS)
203-
{
204-
LOG_E("LSI oscillator failed to stabilize");
205-
return -RT_ERROR;
206-
}
207-
}
208-
rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
209-
LOG_D("RTC clock source: LSI (32kHz)");
210-
#elif defined(RTC_CLOCK_SOURCE_IRC40K)
211-
/* Use LSI (40kHz) as RTC clock source */
212-
if (rcu_osci_stab_wait(RCU_IRC40K) != SUCCESS)
213-
{
214-
rcu_osci_on(RCU_IRC40K);
215-
if (rcu_osci_stab_wait(RCU_IRC40K) != SUCCESS)
216-
{
217-
LOG_E("LSI oscillator failed to stabilize");
218-
return -RT_ERROR;
219-
}
220-
}
221-
rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
222-
LOG_D("RTC clock source: LSI (40kHz)");
223-
#else
224-
#error "Please defined RTC clock source (RTC_CLOCK_SOURCE_LXTAL | RTC_CLOCK_SOURCE_IRC32K | RCU_RTCSRC_IRC40K)"
225-
#endif
226167

227168
/* Wait for RTC registers synchronization */
228169
if (rtc_register_sync_wait() != SUCCESS)
@@ -243,11 +184,6 @@ static rt_err_t gd_rtc_init(void)
243184
LOG_D("RTC set to default time: 2024-01-01 00:00:00");
244185
}
245186

246-
#ifdef RT_USING_ALARM
247-
/* Initialize alarm interrupt */
248-
rtc_alarm_interrupt_init();
249-
#endif
250-
251187
LOG_D("RTC initialization successful");
252188
return RT_EOK;
253189
}
@@ -279,10 +215,11 @@ static time_t get_rtc_timestamp(void)
279215
tm_new.tm_wday = (rtc_wday == 7) ? 0 : rtc_wday; /* Sunday conversion */
280216

281217
/* Calculate day of year */
282-
tm_new.tm_yday = 0; /* Will be calculated by mktime */
218+
tm_new.tm_yday = 0; /* Will be calculated by timegm */
283219
tm_new.tm_isdst = 0; /* No daylight saving */
284220

285-
return mktime(&tm_new);
221+
/* Use timegm instead of mktime to avoid timezone issues */
222+
return timegm(&tm_new);
286223
}
287224

288225
static rt_err_t gd_get_secs(time_t *sec)
@@ -300,43 +237,35 @@ static rt_err_t gd_get_secs(time_t *sec)
300237

301238
static rt_err_t set_rtc_timestamp(time_t time_stamp)
302239
{
303-
struct tm *p_tm;
240+
struct tm now;
304241
rtc_parameter_struct rtc_init_struct;
305242
ErrStatus status;
306243

307-
p_tm = gmtime(&time_stamp);
308-
if (p_tm == RT_NULL)
309-
{
310-
LOG_E("Invalid timestamp");
311-
return -RT_ERROR;
312-
}
244+
/* Use gmtime_r for thread safety */
245+
gmtime_r(&time_stamp, &now);
313246

314-
/* GD32 RTC uses year starting from 2000; tm_year is years since 1900 */
315-
if (p_tm->tm_year < 100)
247+
if (now.tm_year < 100)
316248
{
317249
LOG_E("Year must be >= 2000");
318250
return -RT_ERROR;
319251
}
320252

321-
/* Initialize RTC parameter structure */
322-
rtc_init(&rtc_init_struct);
323-
324253
/* Convert to BCD format */
325-
rtc_init_struct.rtc_year = bin_to_bcd(p_tm->tm_year - 100); /* RTC year: 0-99 (2000-2099) */
326-
rtc_init_struct.rtc_month = bin_to_bcd(p_tm->tm_mon + 1); /* RTC month: 1-12 */
327-
rtc_init_struct.rtc_date = bin_to_bcd(p_tm->tm_mday);
254+
rtc_init_struct.rtc_year = bin_to_bcd(now.tm_year - 100); /* RTC year: 0-99 (2000-2099) */
255+
rtc_init_struct.rtc_month = bin_to_bcd(now.tm_mon + 1); /* RTC month: 1-12 */
256+
rtc_init_struct.rtc_date = bin_to_bcd(now.tm_mday);
328257

329258
/* Convert weekday: tm_wday 0-6 (Sun-Sat) to RTC 1-7 (Mon-Sun) */
330-
rtc_init_struct.rtc_day_of_week = bin_to_bcd(p_tm->tm_wday == 0 ? 7 : p_tm->tm_wday);
259+
rtc_init_struct.rtc_day_of_week = bin_to_bcd(now.tm_wday == 0 ? 7 : now.tm_wday);
331260

332-
rtc_init_struct.rtc_hour = bin_to_bcd(p_tm->tm_hour);
333-
rtc_init_struct.rtc_minute = bin_to_bcd(p_tm->tm_min);
334-
rtc_init_struct.rtc_second = bin_to_bcd(p_tm->tm_sec);
261+
rtc_init_struct.rtc_hour = bin_to_bcd(now.tm_hour);
262+
rtc_init_struct.rtc_minute = bin_to_bcd(now.tm_min);
263+
rtc_init_struct.rtc_second = bin_to_bcd(now.tm_sec);
335264
rtc_init_struct.rtc_display_format = RTC_24HOUR;
336265

337-
/* Use default prescaler values for 32.768kHz or 40kHz clock */
338-
rtc_init_struct.factor_asyn = 0x7F;
339-
rtc_init_struct.factor_syn = 0xFF;
266+
/* Use default prescaler values */
267+
rtc_init_struct.factor_asyn = PRESCALER_A;
268+
rtc_init_struct.factor_syn = PRESCALER_S;
340269
rtc_init_struct.am_pm = RTC_AM;
341270

342271
status = rtc_init(&rtc_init_struct);
@@ -353,7 +282,7 @@ static rt_err_t set_rtc_timestamp(time_t time_stamp)
353282
return -RT_ERROR;
354283
}
355284

356-
LOG_D("RTC time set successfully");
285+
LOG_D("RTC time set successfully: %lu", time_stamp);
357286
return RT_EOK;
358287
}
359288

@@ -367,11 +296,11 @@ static rt_err_t gd_set_secs(time_t *sec)
367296
rt_err_t result = set_rtc_timestamp(*sec);
368297
if (result == RT_EOK)
369298
{
370-
LOG_D("RTC: set timestamp %lu", *sec);
299+
LOG_D("RTC: set rtc_time %lu", *sec);
371300
}
372301
else
373302
{
374-
LOG_E("RTC: set timestamp failed %lu", *sec);
303+
LOG_E("RTC: set rtc_time failed %lu", *sec);
375304
}
376305

377306
return result;
@@ -385,8 +314,9 @@ static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm)
385314
return -RT_EINVAL;
386315
}
387316

388-
/* GD32H7xx supports two alarms, we use ALARM0 by default */
389317
rtc_alarm_struct rtc_alarm;
318+
319+
/* Get current alarm configuration */
390320
rtc_alarm_get(BSP_RTC_ALARM, &rtc_alarm);
391321

392322
/* Convert RTC alarm to RT-Thread alarm format */
@@ -395,7 +325,7 @@ static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm)
395325
alarm->tm_sec = bcd_to_bin(rtc_alarm.alarm_second);
396326

397327
/* Check if alarm is enabled */
398-
alarm->enable = (RTC_CTL & RTC_CTL_ALRM0EN) ? 1 : 0;
328+
alarm->enable = (RTC_CTL & (BSP_RTC_ALARM == RTC_ALARM0 ? RTC_CTL_ALRM0EN : RTC_CTL_ALRM1EN)) ? 1 : 0;
399329

400330
LOG_D("RTC: get alarm %02d:%02d:%02d, enable: %d",
401331
alarm->tm_hour, alarm->tm_min, alarm->tm_sec, alarm->enable);
@@ -412,7 +342,7 @@ static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm)
412342

413343
rtc_alarm_struct rtc_alarm;
414344

415-
rtc_alarm_disable(RTC_ALARM0);
345+
rtc_alarm_disable(BSP_RTC_ALARM);
416346
/* Initialize alarm structure */
417347
rtc_alarm.alarm_mask = RTC_ALARM_ALL_MASK;
418348
rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
@@ -425,28 +355,33 @@ static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm)
425355
/* Configure alarm */
426356
rtc_alarm_config(BSP_RTC_ALARM, &rtc_alarm);
427357

428-
rtc_interrupt_enable(RTC_INT_ALARM0);
429-
rtc_alarm_enable(BSP_RTC_ALARM);
430-
431358
/* Enable or disable alarm */
432359
if (alarm->enable)
433360
{
434361
/* Clear any pending alarm flag first */
435362
rtc_flag_clear(BSP_ALARM_FLAG);
363+
364+
/* Clear EXTI line 17 flag */
436365
exti_flag_clear(EXTI_17);
437366

438-
/* Enable alarm interrupt */
439-
rtc_interrupt_enable(RTC_INT_ALARM0);
367+
/* Enable RTC alarm interrupt */
368+
rtc_interrupt_enable(BSP_RTC_INT_ALARM);
440369

441370
/* Enable alarm */
442371
rtc_alarm_enable(BSP_RTC_ALARM);
443372

444-
LOG_D("RTC Alarm0 enabled with interrupt");
373+
/* Configure EXTI line 17 for RTC alarm interrupt */
374+
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
375+
376+
/* Enable RTC Alarm global interrupt in NVIC */
377+
nvic_irq_enable(RTC_Alarm_IRQn, 0, 0);
378+
379+
LOG_D("RTC Alarm enabled with interrupt");
445380
}
446381
else
447382
{
448383
/* Disable alarm interrupt first */
449-
rtc_interrupt_disable(RTC_INT_ALARM0);
384+
rtc_interrupt_disable(BSP_RTC_INT_ALARM);
450385

451386
/* Disable alarm */
452387
rtc_alarm_disable(BSP_RTC_ALARM);
@@ -455,7 +390,7 @@ static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm)
455390
rtc_flag_clear(BSP_ALARM_FLAG);
456391
exti_flag_clear(EXTI_17);
457392

458-
LOG_D("RTC Alarm0 disabled");
393+
LOG_D("RTC Alarm disabled");
459394
}
460395

461396
LOG_D("RTC: set alarm %02d:%02d:%02d, enable: %d",

0 commit comments

Comments
 (0)