1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes
9  **********************************************************************************************************************/
10 #include "r_gtm.h"
11 
12 /***********************************************************************************************************************
13  * Macro definitions
14  **********************************************************************************************************************/
15 
16 /** "GTM" in ASCII, used to determine if channel is open. */
17 #define GTM_OPEN    (0x0047544DULL)
18 
19 /**********************************************************************************************************************
20  * Typedef definitions
21  **********************************************************************************************************************/
22 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
23 typedef void (BSP_CMSE_NONSECURE_CALL * gtm_prv_ns_callback)(timer_callback_args_t * p_args);
24 #elif defined(__GNUC__)
25 typedef BSP_CMSE_NONSECURE_CALL void (*volatile gtm_prv_ns_callback)(timer_callback_args_t * p_args);
26 #endif
27 
28 /***********************************************************************************************************************
29  * Private function prototypes
30  **********************************************************************************************************************/
31 static void r_gtm_period_register_set(gtm_instance_ctrl_t * p_instance_ctrl, uint32_t period_counts);
32 
33 static uint32_t r_gtm_clock_frequency_get(R_GTM0_Type * p_gtm_regs);
34 
35 static fsp_err_t r_gtm_common_preamble(gtm_instance_ctrl_t * p_instance_ctrl);
36 
37 #if GTM_CFG_PARAM_CHECKING_ENABLE
38 static fsp_err_t r_gtm_open_param_checking(gtm_instance_ctrl_t * p_instance_ctrl, timer_cfg_t const * const p_cfg);
39 
40 #endif
41 
42 /* ISRs. */
43 void gtm_int_isr(void);
44 
45 /***********************************************************************************************************************
46  * Private global variables
47  **********************************************************************************************************************/
48 
49 /***********************************************************************************************************************
50  * Global Variables
51  **********************************************************************************************************************/
52 
53 /** GTM Implementation of General Timer Driver  */
54 const timer_api_t g_timer_on_gtm =
55 {
56     .open         = R_GTM_Open,
57     .stop         = R_GTM_Stop,
58     .start        = R_GTM_Start,
59     .reset        = R_GTM_Reset,
60     .enable       = R_GTM_Enable,
61     .disable      = R_GTM_Disable,
62     .periodSet    = R_GTM_PeriodSet,
63     .dutyCycleSet = R_GTM_DutyCycleSet,
64     .infoGet      = R_GTM_InfoGet,
65     .statusGet    = R_GTM_StatusGet,
66     .callbackSet  = R_GTM_CallbackSet,
67     .close        = R_GTM_Close,
68 };
69 
70 /*******************************************************************************************************************//**
71  * @addtogroup GTM
72  * @{
73  **********************************************************************************************************************/
74 
75 /***********************************************************************************************************************
76  * Functions
77  **********************************************************************************************************************/
78 
79 /*******************************************************************************************************************//**
80  * Initializes the GTM module instance. Implements @ref timer_api_t::open.
81  *
82  * The GTM hardware does not support one-shot functionality natively.  The one-shot feature is therefore implemented in
83  * the GTM HAL layer. For a timer configured as a one-shot timer, the timer is stopped upon the first timer expiration.
84  *
85  * The GTM implementation of the general timer can accept an optional gtm_extended_cfg_t extension parameter.  For
86  * GTM, the extension specifies the clock to be used as timer source and the output pin configurations.  If the
87  * extension parameter is not specified (NULL), the default clock P0CLK is used and the output pins are disabled.
88  *
89  * @retval FSP_SUCCESS                 Initialization was successful and timer has started.
90  * @retval FSP_ERR_ASSERTION           A required input pointer is NULL or the period is not in the valid range of
91  *                                     1 to 0xFFFF.
92  * @retval FSP_ERR_ALREADY_OPEN        R_GTM_Open has already been called for this p_ctrl.
93  * @retval FSP_ERR_IRQ_BSP_DISABLED    A required interrupt has not been enabled in the vector table.
94  * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT  Requested channel number is not available on GTM.
95  **********************************************************************************************************************/
R_GTM_Open(timer_ctrl_t * const p_ctrl,timer_cfg_t const * const p_cfg)96 fsp_err_t R_GTM_Open (timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg)
97 {
98     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
99 
100 #if GTM_CFG_PARAM_CHECKING_ENABLE
101     fsp_err_t err = r_gtm_open_param_checking(p_instance_ctrl, p_cfg);
102     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
103 #endif
104 
105     /* calculate base address for specified channel */
106     intptr_t base_address = (intptr_t) R_GTM0_BASE +
107                             (p_cfg->channel * ((intptr_t) R_GTM1_BASE - (intptr_t) R_GTM0_BASE));
108     p_instance_ctrl->p_reg = (R_GTM0_Type *) base_address;
109     p_instance_ctrl->p_cfg = p_cfg;
110 
111     /* Power on the GTM channel. */
112     R_BSP_MODULE_START(FSP_IP_GTM, p_cfg->channel);
113 
114     /* Forcibly stop timer. */
115     p_instance_ctrl->p_reg->OSTMnTT = 1;
116 
117     /* Set period register */
118     r_gtm_period_register_set(p_instance_ctrl, p_cfg->period_counts);
119 
120     /* Set counter mode (GTMnMD) */
121     uint32_t             gtmnmd = 0;
122     gtm_extended_cfg_t * p_ext  = (gtm_extended_cfg_t *) p_cfg->p_extend;
123     if (GTM_GIWS_TYPE_ENABLED == p_ext->generate_interrupt_when_starts)
124     {
125         gtmnmd |= R_GTM0_OSTMnCTL_OSTMnMD0_Msk;
126     }
127 
128     if (GTM_TIMER_MODE_FREERUN == p_ext->gtm_mode)
129     {
130         gtmnmd |= R_GTM0_OSTMnCTL_OSTMnMD1_Msk;
131     }
132 
133     p_instance_ctrl->p_reg->OSTMnCTL = (uint8_t) gtmnmd;
134 
135     if (p_cfg->cycle_end_irq >= 0)
136     {
137         R_BSP_IrqCfgEnable(p_cfg->cycle_end_irq, p_cfg->cycle_end_ipl, p_instance_ctrl);
138     }
139 
140     /* Set callback and context pointers */
141 
142     p_instance_ctrl->p_callback        = p_cfg->p_callback;
143     p_instance_ctrl->p_context         = p_cfg->p_context;
144     p_instance_ctrl->p_callback_memory = NULL;
145 
146     p_instance_ctrl->open = GTM_OPEN;
147 
148     /* All done.  */
149     return FSP_SUCCESS;
150 }
151 
152 /*******************************************************************************************************************//**
153  * Starts timer. Implements @ref timer_api_t::start.
154  *
155  * @retval FSP_SUCCESS                 Timer started.
156  * @retval FSP_ERR_ASSERTION           p_ctrl is null.
157  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
158  **********************************************************************************************************************/
R_GTM_Start(timer_ctrl_t * const p_ctrl)159 fsp_err_t R_GTM_Start (timer_ctrl_t * const p_ctrl)
160 {
161     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
162 
163     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
164     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
165 
166     /* Start timer */
167     p_instance_ctrl->p_reg->OSTMnTS = 1;
168 
169     return FSP_SUCCESS;
170 }
171 
172 /*******************************************************************************************************************//**
173  * Stops the timer.  Implements @ref timer_api_t::stop.
174  *
175  * @retval FSP_SUCCESS                 Timer stopped.
176  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
177  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
178  **********************************************************************************************************************/
R_GTM_Stop(timer_ctrl_t * const p_ctrl)179 fsp_err_t R_GTM_Stop (timer_ctrl_t * const p_ctrl)
180 {
181     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
182 
183     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
184     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
185 
186     /* Stop timer */
187     p_instance_ctrl->p_reg->OSTMnTT = 1;
188 
189     return FSP_SUCCESS;
190 }
191 
192 /*******************************************************************************************************************//**
193  * Resets the counter value to the period minus one. Implements @ref timer_api_t::reset.
194  *
195  * @retval FSP_ERR_UNSUPPORTED Selected function not supported by this module.
196  **********************************************************************************************************************/
R_GTM_Reset(timer_ctrl_t * const p_ctrl)197 fsp_err_t R_GTM_Reset (timer_ctrl_t * const p_ctrl)
198 {
199     (void) p_ctrl;
200 
201     return FSP_ERR_UNSUPPORTED;
202 }
203 
204 /*******************************************************************************************************************//**
205  * Enables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::enable.
206  *
207  * @retval FSP_ERR_UNSUPPORTED Selected function not supported by this module.
208  **********************************************************************************************************************/
R_GTM_Enable(timer_ctrl_t * const p_ctrl)209 fsp_err_t R_GTM_Enable (timer_ctrl_t * const p_ctrl)
210 {
211     (void) p_ctrl;
212 
213     return FSP_ERR_UNSUPPORTED;
214 }
215 
216 /*******************************************************************************************************************//**
217  * Disables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::disable.
218  *
219  * @retval FSP_ERR_UNSUPPORTED Selected function not supported by this module.
220  **********************************************************************************************************************/
R_GTM_Disable(timer_ctrl_t * const p_ctrl)221 fsp_err_t R_GTM_Disable (timer_ctrl_t * const p_ctrl)
222 {
223     (void) p_ctrl;
224 
225     return FSP_ERR_UNSUPPORTED;
226 }
227 
228 /*******************************************************************************************************************//**
229  * Updates period. The new period is updated immediately and the counter is reset to the maximum value. Implements
230  * @ref timer_api_t::periodSet.
231  *
232  * @warning If periodic output is used, the duty cycle buffer registers are updated after the period buffer register.
233  * If this function is called while the timer is running and an GTM underflow occurs during processing, the duty cycle
234  * will not be the desired 50% duty cycle until the counter underflow after processing completes.
235  *
236  * @warning Stop the timer before calling this function if one-shot output is used.
237  *
238  * @retval FSP_SUCCESS                 Period value updated.
239  * @retval FSP_ERR_ASSERTION           A required pointer was NULL, or the period was not in the valid range of
240  *                                     1 to 0xFFFF.
241  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
242  **********************************************************************************************************************/
R_GTM_PeriodSet(timer_ctrl_t * const p_ctrl,uint32_t const period_counts)243 fsp_err_t R_GTM_PeriodSet (timer_ctrl_t * const p_ctrl, uint32_t const period_counts)
244 {
245     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
246 #if GTM_CFG_PARAM_CHECKING_ENABLE
247 
248     /* Validate period parameter. */
249     FSP_ASSERT(0U != period_counts);
250 #endif
251 
252     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
253     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
254 
255     /* Set period. */
256     r_gtm_period_register_set(p_instance_ctrl, period_counts);
257 
258     return FSP_SUCCESS;
259 }
260 
261 /*******************************************************************************************************************//**
262  * Updates duty cycle. If the timer is counting, the new duty cycle is reflected after the next counter underflow.
263  * Implements @ref timer_api_t::dutyCycleSet.
264  *
265  * @retval FSP_ERR_UNSUPPORTED
266  **********************************************************************************************************************/
R_GTM_DutyCycleSet(timer_ctrl_t * const p_ctrl,uint32_t const duty_cycle_counts,uint32_t const pin)267 fsp_err_t R_GTM_DutyCycleSet (timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin)
268 {
269     (void) p_ctrl;
270     (void) duty_cycle_counts;
271     (void) pin;
272 
273     return FSP_ERR_UNSUPPORTED;
274 }
275 
276 /*******************************************************************************************************************//**
277  * Gets timer information and store it in provided pointer p_info. Implements @ref timer_api_t::infoGet.
278  *
279  * @retval FSP_SUCCESS                 Period, count direction, and frequency stored in p_info.
280  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
281  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
282  **********************************************************************************************************************/
R_GTM_InfoGet(timer_ctrl_t * const p_ctrl,timer_info_t * const p_info)283 fsp_err_t R_GTM_InfoGet (timer_ctrl_t * const p_ctrl, timer_info_t * const p_info)
284 {
285     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
286 #if GTM_CFG_PARAM_CHECKING_ENABLE
287     FSP_ASSERT(NULL != p_info);
288 #endif
289 
290     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
291     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
292 
293     /* Get and store period */
294     p_info->period_counts = p_instance_ctrl->period;
295 
296     /* Get and store clock frequency */
297     p_info->clock_frequency = r_gtm_clock_frequency_get(p_instance_ctrl->p_reg);
298 
299     /* GTM counting direction */
300     p_info->count_direction =
301         (p_instance_ctrl->p_reg->OSTMnCTL & R_GTM0_OSTMnCTL_OSTMnMD1_Msk) ?
302         TIMER_DIRECTION_UP : TIMER_DIRECTION_DOWN;
303 
304     return FSP_SUCCESS;
305 }
306 
307 /*******************************************************************************************************************//**
308  * Retrieves the current state and counter value stores them in p_status. Implements @ref timer_api_t::statusGet.
309  *
310  * @retval FSP_SUCCESS                 Current status and counter value provided in p_status.
311  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
312  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
313  **********************************************************************************************************************/
R_GTM_StatusGet(timer_ctrl_t * const p_ctrl,timer_status_t * const p_status)314 fsp_err_t R_GTM_StatusGet (timer_ctrl_t * const p_ctrl, timer_status_t * const p_status)
315 {
316     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
317 
318 #if GTM_CFG_PARAM_CHECKING_ENABLE
319     FSP_ASSERT(NULL != p_status);
320 #endif
321 
322     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
323     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
324 
325     /* Read the state. */
326     p_status->state = p_instance_ctrl->p_reg->OSTMnTE_b.OSTMnTE ?
327                       TIMER_STATE_COUNTING : TIMER_STATE_STOPPED;
328 
329     /* Read counter value */
330     p_status->counter = p_instance_ctrl->p_reg->OSTMnCNT;
331 
332     return FSP_SUCCESS;
333 }
334 
335 /*******************************************************************************************************************//**
336  * Updates the user callback with the option to provide memory for the callback argument structure.
337  * Implements @ref timer_api_t::callbackSet.
338  *
339  * @retval  FSP_SUCCESS                  Callback updated successfully.
340  * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
341  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
342  * @retval  FSP_ERR_NO_CALLBACK_MEMORY   p_callback is non-secure and p_callback_memory is either secure or NULL.
343  **********************************************************************************************************************/
R_GTM_CallbackSet(timer_ctrl_t * const p_api_ctrl,void (* p_callback)(timer_callback_args_t *),void const * const p_context,timer_callback_args_t * const p_callback_memory)344 fsp_err_t R_GTM_CallbackSet (timer_ctrl_t * const          p_api_ctrl,
345                              void (                      * p_callback)(timer_callback_args_t *),
346                              void const * const            p_context,
347                              timer_callback_args_t * const p_callback_memory)
348 {
349     gtm_instance_ctrl_t * p_ctrl = (gtm_instance_ctrl_t *) p_api_ctrl;
350 
351 #if GTM_CFG_PARAM_CHECKING_ENABLE
352     FSP_ASSERT(p_ctrl);
353     FSP_ASSERT(p_callback);
354     FSP_ERROR_RETURN(GTM_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
355 #endif
356 
357 #if BSP_TZ_SECURE_BUILD
358 
359     /* Get security state of p_callback */
360     bool callback_is_secure =
361         (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
362 
363  #if GTM_CFG_PARAM_CHECKING_ENABLE
364 
365     /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
366     timer_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
367                                                                                         CMSE_AU_NONSECURE);
368     FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
369  #endif
370 #endif
371 
372     /* Store callback and context */
373 #if BSP_TZ_SECURE_BUILD
374     p_ctrl->p_callback = callback_is_secure ? p_callback :
375                          (void (*)(timer_callback_args_t *))cmse_nsfptr_create(p_callback);
376 #else
377     p_ctrl->p_callback = p_callback;
378 #endif
379     p_ctrl->p_context         = p_context;
380     p_ctrl->p_callback_memory = p_callback_memory;
381 
382     return FSP_SUCCESS;
383 }
384 
385 /*******************************************************************************************************************//**
386  * Stops counter, disables interrupts, disables output pins, and clears internal driver data.  Implements
387  * @ref timer_api_t::close.
388  *
389  *
390  *
391  * @retval FSP_SUCCESS                 Timer closed.
392  * @retval FSP_ERR_ASSERTION           p_ctrl is NULL.
393  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
394  **********************************************************************************************************************/
R_GTM_Close(timer_ctrl_t * const p_ctrl)395 fsp_err_t R_GTM_Close (timer_ctrl_t * const p_ctrl)
396 {
397     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) p_ctrl;
398 
399     fsp_err_t err = r_gtm_common_preamble(p_instance_ctrl);
400     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
401 
402     /* Cleanup the device: Stop counter, disable interrupts, and power down if no other channels are in use. */
403 
404     /* Stop timer */
405     p_instance_ctrl->p_reg->OSTMnTT = 1;
406 
407     if (FSP_INVALID_VECTOR != p_instance_ctrl->p_cfg->cycle_end_irq)
408     {
409         NVIC_DisableIRQ(p_instance_ctrl->p_cfg->cycle_end_irq);
410         R_FSP_IsrContextSet(p_instance_ctrl->p_cfg->cycle_end_irq, p_instance_ctrl);
411     }
412 
413     p_instance_ctrl->open = 0U;
414 
415     /* Remove power to the channel. */
416     R_BSP_MODULE_STOP(FSP_IP_GTM, p_instance_ctrl->p_cfg->channel);
417 
418     return FSP_SUCCESS;
419 }
420 
421 /** @} (end addtogroup GTM) */
422 
423 /***********************************************************************************************************************
424  * Private Functions
425  **********************************************************************************************************************/
426 
427 #if GTM_CFG_PARAM_CHECKING_ENABLE
428 
429 /*******************************************************************************************************************//**
430  * Parameter checking for R_GTM_Open.
431  *
432  * @param[in] p_instance_ctrl          Pointer to instance control structure.
433  * @param[in]  p_cfg              Configuration structure for this instance
434  *
435  * @retval FSP_SUCCESS                 Initialization was successful and timer has started.
436  * @retval FSP_ERR_ASSERTION           A required input pointer is NULL or the period is not in the valid range of
437  *                                     1 to 0xFFFF.
438  * @retval FSP_ERR_ALREADY_OPEN        R_GTM_Open has already been called for this p_ctrl.
439  * @retval FSP_ERR_IRQ_BSP_DISABLED    A required interrupt has not been enabled in the vector table.
440  * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT  Requested channel number is not available on GTM.
441  **********************************************************************************************************************/
r_gtm_open_param_checking(gtm_instance_ctrl_t * p_instance_ctrl,timer_cfg_t const * const p_cfg)442 static fsp_err_t r_gtm_open_param_checking (gtm_instance_ctrl_t * p_instance_ctrl, timer_cfg_t const * const p_cfg)
443 {
444     FSP_ASSERT(NULL != p_instance_ctrl);
445     FSP_ASSERT(NULL != p_cfg);
446     FSP_ASSERT(NULL != p_cfg->p_extend);
447     FSP_ERROR_RETURN(GTM_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
448 
449     /* Enable IRQ if user supplied a callback function,
450      *  or if the timer is a one-shot timer (so the driver is able to
451      *  turn off the timer after one period. */
452     if ((NULL != p_cfg->p_callback) || (TIMER_MODE_ONE_SHOT == p_cfg->mode))
453     {
454         /* Return error if IRQ is required and not in the vector table. */
455         FSP_ERROR_RETURN(p_cfg->cycle_end_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
456     }
457 
458     FSP_ASSERT(0U != p_cfg->period_counts);
459 
460     /* Validate channel number. */
461     FSP_ERROR_RETURN(((1U << p_cfg->channel) & BSP_FEATURE_GTM_VALID_CHANNEL_MASK), FSP_ERR_IP_CHANNEL_NOT_PRESENT);
462 
463     return FSP_SUCCESS;
464 }
465 
466 #endif                                 /* GTM_CFG_PARAM_CHECKING_ENABLE */
467 
468 /*******************************************************************************************************************//**
469  * Common code at the beginning of all GTM functions except open.
470  *
471  * @param[in] p_instance_ctrl          Pointer to instance control structure.
472  *
473  * @retval FSP_SUCCESS                 No invalid conditions detected, timer state matches expected state.
474  * @retval FSP_ERR_ASSERTION           p_ctrl is null.
475  * @retval FSP_ERR_NOT_OPEN            The instance control structure is not opened.
476  **********************************************************************************************************************/
r_gtm_common_preamble(gtm_instance_ctrl_t * p_instance_ctrl)477 static fsp_err_t r_gtm_common_preamble (gtm_instance_ctrl_t * p_instance_ctrl)
478 {
479 #if GTM_CFG_PARAM_CHECKING_ENABLE
480     FSP_ASSERT(NULL != p_instance_ctrl);
481     FSP_ERROR_RETURN(GTM_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
482 #else
483     (void) p_instance_ctrl;
484 #endif
485 
486     return FSP_SUCCESS;
487 }
488 
489 /*******************************************************************************************************************//**
490  * Sets period register and updates compare match registers in one-shot and periodic mode.
491  *
492  * @param[in]  p_instance_ctrl    Control block for this instance
493  * @param[in]  period_counts      GTM period in counts
494  **********************************************************************************************************************/
r_gtm_period_register_set(gtm_instance_ctrl_t * p_instance_ctrl,uint32_t period_counts)495 static void r_gtm_period_register_set (gtm_instance_ctrl_t * p_instance_ctrl, uint32_t period_counts)
496 {
497     /* Store the period value so it can be retrieved later. */
498     p_instance_ctrl->period = period_counts;
499 
500     /* Set counter to period. */
501     p_instance_ctrl->p_reg->OSTMnCMP = period_counts;
502 }
503 
504 /*******************************************************************************************************************//**
505  * Obtains the clock frequency of GTM for all clock sources except GTM0 underflow, with divisor applied.
506  *
507  * @param[in]  p_gtm_regs         Registers of GTM channel used
508  *
509  * @return Source clock frequency of GTM in Hz, divider applied.
510  **********************************************************************************************************************/
r_gtm_clock_frequency_get(R_GTM0_Type * p_gtm_regs)511 static uint32_t r_gtm_clock_frequency_get (R_GTM0_Type * p_gtm_regs)
512 {
513     (void) p_gtm_regs;
514     uint32_t clock_freq_hz = 0U;
515 
516     /* Call CGC function to obtain current PCLKB clock frequency. */
517     clock_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_P0CLK);
518 
519     return clock_freq_hz;
520 }
521 
522 /*********************************************************************************************************************
523  * GTM counter underflow interrupt.
524  **********************************************************************************************************************/
gtm_int_isr(void)525 void gtm_int_isr (void)
526 {
527     /* Save context if RTOS is used */
528     FSP_CONTEXT_SAVE
529 
530     IRQn_Type irq = R_FSP_CurrentIrqGet();
531 
532     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
533     R_BSP_IrqStatusClear(irq);
534 
535     /* Recover ISR context saved in open. */
536     gtm_instance_ctrl_t * p_instance_ctrl = (gtm_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
537 
538     /* If the channel is configured to be one-shot mode, stop the timer. */
539     if (TIMER_MODE_ONE_SHOT == p_instance_ctrl->p_cfg->mode)
540     {
541         /* Stop timer */
542         p_instance_ctrl->p_reg->OSTMnTT = 1;
543     }
544 
545     /* Invoke the callback function if it is set. */
546     if (NULL != p_instance_ctrl->p_callback)
547     {
548         /* Setup parameters for the user-supplied callback function. */
549         timer_callback_args_t callback_args;
550 
551         /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
552          * stored in non-secure memory so they can be accessed by a non-secure callback function. */
553         timer_callback_args_t * p_args = p_instance_ctrl->p_callback_memory;
554         if (NULL == p_args)
555         {
556             /* Store on stack */
557             p_args = &callback_args;
558         }
559         else
560         {
561             /* Save current arguments on the stack in case this is a nested interrupt. */
562             callback_args = *p_args;
563         }
564 
565         p_args->event     = TIMER_EVENT_CYCLE_END;
566         p_args->p_context = p_instance_ctrl->p_context;
567 
568 #if BSP_TZ_SECURE_BUILD
569 
570         /* p_callback can point to a secure function or a non-secure function. */
571         if (!cmse_is_nsfptr(p_instance_ctrl->p_callback))
572         {
573             /* If p_callback is secure, then the project does not need to change security state. */
574             p_instance_ctrl->p_callback(p_args);
575         }
576         else
577         {
578             /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
579             gtm_prv_ns_callback p_callback = (gtm_prv_ns_callback) (p_instance_ctrl->p_callback);
580             p_callback(p_args);
581         }
582 
583 #else
584 
585         /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
586         p_instance_ctrl->p_callback(p_args);
587 #endif
588 
589         if (NULL != p_instance_ctrl->p_callback_memory)
590         {
591             /* Restore callback memory in case this is a nested interrupt. */
592             *p_instance_ctrl->p_callback_memory = callback_args;
593         }
594     }
595 
596     /* Restore context if RTOS is used */
597     FSP_CONTEXT_RESTORE
598 }
599