1717
1818#ifdef RT_USING_CLOCK_TIME
1919
20+ #define GPT_GTWP_RESET_VALUE (0xA500U)
21+
22+ #ifdef SOC_SERIES_R9A07G0
23+ #define TIMER_FSP_PRIV_CLOCK FSP_PRIV_CLOCK_PCLKGPTL
24+ #else
25+ #define TIMER_FSP_PRIV_CLOCK FSP_PRIV_CLOCK_PCLKD
26+ #endif
27+
2028static struct ra_clock_timer ra_clock_timer_obj [BSP_TIMERS_NUM ] =
2129{
2230#ifdef BSP_USING_TIM0
@@ -156,17 +164,48 @@ static rt_err_t timer_ctrl(rt_clock_timer_t *timer, rt_uint32_t cmd, void *arg)
156164 {
157165 case CLOCK_TIMER_CTRL_FREQ_SET :
158166 {
159- rt_uint8_t index = 0 ;
160- rt_uint32_t freq = * ((rt_uint32_t * )arg );
167+ rt_uint32_t req_freq = * ((rt_uint32_t * )arg );
168+ rt_uint32_t source_div = 0 ;
169+ rt_uint32_t actual_freq = 0 ;
170+ rt_uint32_t src_clk_hz = R_FSP_SystemClockHzGet (TIMER_FSP_PRIV_CLOCK );
161171
162- for (rt_uint8_t i = 0 ; i < PLCKD_PRESCALER_MAX_SELECT ; i ++ )
172+ #if (2U == BSP_FEATURE_GPT_CLOCK_DIVIDER_STEP_SIZE )
173+ for (rt_uint32_t div = 0 ; div <= 10U ; div ++ )
174+ #else
175+ for (rt_uint32_t div = 0 ; div <= 10U ; div += 2U )
176+ #endif
163177 {
164- if (freq <= PLCKD_FREQ_PRESCALER [i ])
178+ #if (2U == BSP_FEATURE_GPT_CLOCK_DIVIDER_STEP_SIZE ) && (0U == BSP_FEATURE_GPT_CLOCK_DIVIDER_VALUE_7_9_VALID )
179+ if ((7U == div ) || (9U == div ))
180+ {
181+ continue ;
182+ }
183+ #endif
184+ rt_uint32_t cand = src_clk_hz >> div ;
185+ if (req_freq <= cand )
165186 {
166- index = i ;
187+ source_div = div ;
188+ actual_freq = cand ;
167189 }
168190 }
169- tim -> g_ctrl -> p_reg -> GTCR_b .TPCS = index ;
191+
192+ if (0U == actual_freq )
193+ {
194+ /* Keep behavior bounded even with an unexpected input. */
195+ source_div = 10U ;
196+ actual_freq = src_clk_hz >> source_div ;
197+ }
198+
199+ /* GPT TPCS can only be updated when counter is stopped and GTWP is unlocked. */
200+ R_GPT_Stop (tim -> g_ctrl );
201+ uint32_t wp = tim -> g_ctrl -> p_reg -> GTWP ;
202+ tim -> g_ctrl -> p_reg -> GTWP = GPT_GTWP_RESET_VALUE ;
203+ (void ) tim -> g_ctrl -> p_reg -> GTWP ;
204+ tim -> g_ctrl -> p_reg -> GTCR_b .TPCS = (source_div >> BSP_FEATURE_GPT_TPCS_SHIFT );
205+ tim -> g_ctrl -> p_reg -> GTWP = (wp | GPT_GTWP_RESET_VALUE );
206+
207+ /* Return real hardware frequency to clock_timer core to keep conversion consistent. */
208+ * ((rt_uint32_t * )arg ) = actual_freq ;
170209 }
171210 break ;
172211 default :
@@ -271,13 +310,50 @@ static int rt_hw_clock_timer_init(void)
271310}
272311INIT_BOARD_EXPORT (rt_hw_clock_timer_init );
273312
274- /* This is a clock_timer example */
275- #define CLOCK_TIMER_DEV_NAME "timer0" /* device name */
313+ /* This is a clock_timer example.
314+ * Use timer1 by default to avoid conflicting with the clock_time default event timer (timer0). */
315+ #ifdef BSP_USING_TIM1
316+ #define CLOCK_TIMER_DEV_NAME "timer1" /* device name */
317+ #else
318+ #define CLOCK_TIMER_DEV_NAME "timer0" /* fallback */
319+ #endif
320+
321+ static rt_tick_t s_last_cb_tick = 0 ;
322+
323+ static void clock_timer_sample_prepare (rt_device_t hw_dev )
324+ {
325+ struct ra_clock_timer * tim = (struct ra_clock_timer * )hw_dev -> user_data ;
326+
327+ if (tim && tim -> g_ctrl && tim -> g_cfg )
328+ {
329+ R_GPT_Stop (tim -> g_ctrl );
330+ R_GPT_CounterSet (tim -> g_ctrl , 0 );
331+ if (tim -> g_cfg -> cycle_end_irq >= 0 )
332+ {
333+ R_BSP_IrqClearPending (tim -> g_cfg -> cycle_end_irq );
334+ }
335+ }
336+ }
276337
277338static rt_err_t timeout_cb (rt_device_t dev , rt_size_t size )
278339{
340+ rt_tick_t now_tick = rt_tick_get ();
341+
279342 rt_kprintf ("this is clock_timer timeout callback fucntion!\n" );
280- rt_kprintf ("tick is :%d !\n" , rt_tick_get ());
343+ if (s_last_cb_tick )
344+ {
345+ rt_tick_t dt_tick = now_tick - s_last_cb_tick ;
346+ rt_uint32_t dt_ms = (rt_uint32_t )(((rt_uint64_t )dt_tick * 1000ULL ) / RT_TICK_PER_SECOND );
347+ rt_kprintf ("tick is :%d ! dt_tick=%d, dt_ms=%d\n" ,
348+ (int )now_tick ,
349+ (int )dt_tick ,
350+ (int )dt_ms );
351+ }
352+ else
353+ {
354+ rt_kprintf ("tick is :%d ! dt_tick=0, dt_ms=0 (first)\n" , (int )now_tick );
355+ }
356+ s_last_cb_tick = now_tick ;
281357
282358 return RT_EOK ;
283359}
@@ -288,14 +364,15 @@ int clock_timer_sample(void)
288364 rt_clock_timerval_t timeout_s ;
289365 rt_device_t hw_dev = RT_NULL ;
290366 rt_clock_timer_mode_t mode ;
291- rt_uint32_t freq = 1875000 ; /* 1Mhz */
367+ rt_uint32_t freq = 1875000 ; /* 1.875MHz */
292368
293369 hw_dev = rt_device_find (CLOCK_TIMER_DEV_NAME );
294370 if (hw_dev == RT_NULL )
295371 {
296372 rt_kprintf ("clock_timer sample run failed! can't find %s device!\n" , CLOCK_TIMER_DEV_NAME );
297373 return - RT_ERROR ;
298374 }
375+ rt_kprintf ("clock_timer sample using %s\n" , CLOCK_TIMER_DEV_NAME );
299376
300377 ret = rt_device_open (hw_dev , RT_DEVICE_OFLAG_RDWR );
301378 if (ret != RT_EOK )
@@ -304,6 +381,11 @@ int clock_timer_sample(void)
304381 return ret ;
305382 }
306383
384+ /* Stop old run and clear pending flag before a new period is configured. */
385+ rt_device_control (hw_dev , CLOCK_TIMER_CTRL_STOP , RT_NULL );
386+ clock_timer_sample_prepare (hw_dev );
387+ s_last_cb_tick = 0 ;
388+
307389 rt_device_set_rx_indicate (hw_dev , timeout_cb );
308390
309391 rt_device_control (hw_dev , CLOCK_TIMER_CTRL_FREQ_SET , & freq );
0 commit comments