13
13
#include <board.h>
14
14
#include <rtdevice.h>
15
15
#include <rthw.h>
16
+ #include <sys/time.h>
16
17
17
18
#define DBG_TAG "drv.rtc"
18
19
#define DBG_LVL DBG_INFO
29
30
#elif defined(BSP_USING_ALARM0 )
30
31
#define BSP_ALARM_FLAG RTC_FLAG_ALARM0
31
32
#define BSP_RTC_ALARM RTC_ALARM0
33
+ #define BSP_RTC_INT_ALARM RTC_INT_ALARM0
32
34
#elif defined(BSP_USING_ALARM1 )
33
35
#define BSP_ALARM_FLAG RTC_FLAG_ALARM1
34
36
#define BSP_RTC_ALARM RTC_ALARM1
37
+ #define BSP_RTC_INT_ALARM RTC_INT_ALARM1
35
38
#endif
36
39
#endif
37
40
@@ -87,64 +90,32 @@ void RTC_Alarm_IRQHandler(void)
87
90
{
88
91
/* Clear alarm flag */
89
92
rtc_flag_clear (RTC_FLAG_ALARM0 );
90
-
91
- /* Clear EXTI line 17 flag */
92
93
exti_flag_clear (EXTI_17 );
93
94
94
95
/* Notify RTC framework about alarm event */
95
96
if (g_rtc_device != RT_NULL )
96
97
{
97
98
rt_alarm_update (g_rtc_device , 1 );
98
99
}
99
-
100
100
LOG_D ("RTC Alarm0 triggered" );
101
101
}
102
102
103
- /* Check if alarm1 interrupt occurred */
104
103
if (rtc_flag_get (RTC_FLAG_ALARM1 ) != RESET )
105
104
{
106
105
/* Clear alarm flag */
107
106
rtc_flag_clear (RTC_FLAG_ALARM1 );
108
-
109
- /* Clear EXTI line 17 flag */
110
107
exti_flag_clear (EXTI_17 );
111
108
112
109
/* Notify RTC framework about alarm event */
113
110
if (g_rtc_device != RT_NULL )
114
111
{
115
112
rt_alarm_update (g_rtc_device , 1 );
116
113
}
117
-
118
114
LOG_D ("RTC Alarm1 triggered" );
119
115
}
120
116
121
-
122
117
rt_interrupt_leave ();
123
118
}
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
- }
148
119
#endif /* RT_USING_ALARM */
149
120
150
121
static rt_err_t gd_rtc_init (void )
@@ -181,48 +152,18 @@ static rt_err_t gd_rtc_init(void)
181
152
#endif
182
153
}
183
154
184
- #if defined (RTC_CLOCK_SOURCE_LXTAL )
185
155
/* 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 );
186
160
if (rcu_osci_stab_wait (RCU_LXTAL ) != SUCCESS )
187
161
{
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 ;
194
164
}
195
165
rcu_rtc_clock_config (RCU_RTCSRC_LXTAL );
196
166
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
226
167
227
168
/* Wait for RTC registers synchronization */
228
169
if (rtc_register_sync_wait () != SUCCESS )
@@ -243,11 +184,6 @@ static rt_err_t gd_rtc_init(void)
243
184
LOG_D ("RTC set to default time: 2024-01-01 00:00:00" );
244
185
}
245
186
246
- #ifdef RT_USING_ALARM
247
- /* Initialize alarm interrupt */
248
- rtc_alarm_interrupt_init ();
249
- #endif
250
-
251
187
LOG_D ("RTC initialization successful" );
252
188
return RT_EOK ;
253
189
}
@@ -279,10 +215,11 @@ static time_t get_rtc_timestamp(void)
279
215
tm_new .tm_wday = (rtc_wday == 7 ) ? 0 : rtc_wday ; /* Sunday conversion */
280
216
281
217
/* 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 */
283
219
tm_new .tm_isdst = 0 ; /* No daylight saving */
284
220
285
- return mktime (& tm_new );
221
+ /* Use timegm instead of mktime to avoid timezone issues */
222
+ return timegm (& tm_new );
286
223
}
287
224
288
225
static rt_err_t gd_get_secs (time_t * sec )
@@ -300,43 +237,35 @@ static rt_err_t gd_get_secs(time_t *sec)
300
237
301
238
static rt_err_t set_rtc_timestamp (time_t time_stamp )
302
239
{
303
- struct tm * p_tm ;
240
+ struct tm now ;
304
241
rtc_parameter_struct rtc_init_struct ;
305
242
ErrStatus status ;
306
243
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 );
313
246
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 )
316
248
{
317
249
LOG_E ("Year must be >= 2000" );
318
250
return - RT_ERROR ;
319
251
}
320
252
321
- /* Initialize RTC parameter structure */
322
- rtc_init (& rtc_init_struct );
323
-
324
253
/* 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 );
328
257
329
258
/* 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 );
331
260
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 );
335
264
rtc_init_struct .rtc_display_format = RTC_24HOUR ;
336
265
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 ;
340
269
rtc_init_struct .am_pm = RTC_AM ;
341
270
342
271
status = rtc_init (& rtc_init_struct );
@@ -353,7 +282,7 @@ static rt_err_t set_rtc_timestamp(time_t time_stamp)
353
282
return - RT_ERROR ;
354
283
}
355
284
356
- LOG_D ("RTC time set successfully" );
285
+ LOG_D ("RTC time set successfully: %lu" , time_stamp );
357
286
return RT_EOK ;
358
287
}
359
288
@@ -367,11 +296,11 @@ static rt_err_t gd_set_secs(time_t *sec)
367
296
rt_err_t result = set_rtc_timestamp (* sec );
368
297
if (result == RT_EOK )
369
298
{
370
- LOG_D ("RTC: set timestamp %lu" , * sec );
299
+ LOG_D ("RTC: set rtc_time %lu" , * sec );
371
300
}
372
301
else
373
302
{
374
- LOG_E ("RTC: set timestamp failed %lu" , * sec );
303
+ LOG_E ("RTC: set rtc_time failed %lu" , * sec );
375
304
}
376
305
377
306
return result ;
@@ -385,8 +314,9 @@ static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm)
385
314
return - RT_EINVAL ;
386
315
}
387
316
388
- /* GD32H7xx supports two alarms, we use ALARM0 by default */
389
317
rtc_alarm_struct rtc_alarm ;
318
+
319
+ /* Get current alarm configuration */
390
320
rtc_alarm_get (BSP_RTC_ALARM , & rtc_alarm );
391
321
392
322
/* Convert RTC alarm to RT-Thread alarm format */
@@ -395,7 +325,7 @@ static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm)
395
325
alarm -> tm_sec = bcd_to_bin (rtc_alarm .alarm_second );
396
326
397
327
/* 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 ;
399
329
400
330
LOG_D ("RTC: get alarm %02d:%02d:%02d, enable: %d" ,
401
331
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)
412
342
413
343
rtc_alarm_struct rtc_alarm ;
414
344
415
- rtc_alarm_disable (RTC_ALARM0 );
345
+ rtc_alarm_disable (BSP_RTC_ALARM );
416
346
/* Initialize alarm structure */
417
347
rtc_alarm .alarm_mask = RTC_ALARM_ALL_MASK ;
418
348
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)
425
355
/* Configure alarm */
426
356
rtc_alarm_config (BSP_RTC_ALARM , & rtc_alarm );
427
357
428
- rtc_interrupt_enable (RTC_INT_ALARM0 );
429
- rtc_alarm_enable (BSP_RTC_ALARM );
430
-
431
358
/* Enable or disable alarm */
432
359
if (alarm -> enable )
433
360
{
434
361
/* Clear any pending alarm flag first */
435
362
rtc_flag_clear (BSP_ALARM_FLAG );
363
+
364
+ /* Clear EXTI line 17 flag */
436
365
exti_flag_clear (EXTI_17 );
437
366
438
- /* Enable alarm interrupt */
439
- rtc_interrupt_enable (RTC_INT_ALARM0 );
367
+ /* Enable RTC alarm interrupt */
368
+ rtc_interrupt_enable (BSP_RTC_INT_ALARM );
440
369
441
370
/* Enable alarm */
442
371
rtc_alarm_enable (BSP_RTC_ALARM );
443
372
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" );
445
380
}
446
381
else
447
382
{
448
383
/* Disable alarm interrupt first */
449
- rtc_interrupt_disable (RTC_INT_ALARM0 );
384
+ rtc_interrupt_disable (BSP_RTC_INT_ALARM );
450
385
451
386
/* Disable alarm */
452
387
rtc_alarm_disable (BSP_RTC_ALARM );
@@ -455,7 +390,7 @@ static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm)
455
390
rtc_flag_clear (BSP_ALARM_FLAG );
456
391
exti_flag_clear (EXTI_17 );
457
392
458
- LOG_D ("RTC Alarm0 disabled" );
393
+ LOG_D ("RTC Alarm disabled" );
459
394
}
460
395
461
396
LOG_D ("RTC: set alarm %02d:%02d:%02d, enable: %d" ,
0 commit comments