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
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
150121static 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
288225static rt_err_t gd_get_secs (time_t * sec )
@@ -300,43 +237,35 @@ static rt_err_t gd_get_secs(time_t *sec)
300237
301238static 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