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