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_gpt.h"
11 #include "r_gpt_cfg.h"
12 
13 /***********************************************************************************************************************
14  * Macro definitions
15  **********************************************************************************************************************/
16 
17 /* "GPT" in ASCII, used to determine if channel is open. */
18 #define GPT_OPEN                                         (0x00475054ULL)
19 
20 #define GPT_PRV_GTINTAD_INTERRUPT_ENABLE                 (0x0043U)
21 #define GPT_PRV_GTINTAD_UNDERFLOW_INTERRUPT_ENABLE       (0x0080U)
22 
23 #define GPT_PRV_GTWP_RESET_VALUE                         (0xA500U)
24 #define GPT_PRV_GTWP_WRITE_PROTECT                       (0xA501U)
25 
26 #define GPT_PRV_GTIOR_STOP_LEVEL_BIT                     (6)
27 #define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT                  (4)
28 
29 #define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END    (0x6U)
30 #define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END    (0x9U)
31 
32 #define GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH                (0x3U)
33 
34 #define GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER       (0x550000U)
35 
36 #define GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE             (0x80000000U)
37 
38 /* GPT_CFG_OUTPUT_SUPPORT_ENABLE is set to 2 to enable extra features. */
39 #define GPT_PRV_EXTRA_FEATURES_ENABLED                   (2U)
40 
41 /***********************************************************************************************************************
42  * Typedef definitions
43  **********************************************************************************************************************/
44 
45 /* Duty cycle mode. */
46 typedef enum e_gpt_duty_cycle_mode
47 {
48     GPT_DUTY_CYCLE_MODE_REGISTER    = 0, // Duty cycle depends on compare match
49     GPT_DUTY_CYCLE_MODE_0_PERCENT   = 2, // Output low
50     GPT_DUTY_CYCLE_MODE_100_PERCENT = 3, // Output high
51 } gpt_duty_cycle_mode_t;
52 
53 /* Count direction */
54 typedef enum e_gpt_dir
55 {
56     GPT_DIR_COUNT_DOWN = 0,
57     GPT_DIR_COUNT_UP   = 1
58 } gpt_dir_t;
59 
60 typedef struct st_gpt_prv_duty_registers
61 {
62     uint32_t gtccr_buffer;
63     uint32_t omdty;
64 } gpt_prv_duty_registers_t;
65 
66 typedef enum e_gpt_prv_capture_event
67 {
68     GPT_PRV_CAPTURE_EVENT_A,
69     GPT_PRV_CAPTURE_EVENT_B,
70 } gpt_prv_capture_event_t;
71 
72 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
73 typedef void (BSP_CMSE_NONSECURE_CALL * gpt_prv_ns_callback)(timer_callback_args_t * p_args);
74 #elif defined(__GNUC__)
75 typedef BSP_CMSE_NONSECURE_CALL void (*volatile gpt_prv_ns_callback)(timer_callback_args_t * p_args);
76 #endif
77 
78 /***********************************************************************************************************************
79  * Private function prototypes
80  **********************************************************************************************************************/
81 static void gpt_hardware_initialize(gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg);
82 
83 static void gpt_common_open(gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg);
84 
85 static uint32_t gpt_clock_frequency_get(gpt_instance_ctrl_t * const p_instance_ctrl);
86 
87 static void gpt_hardware_events_disable(gpt_instance_ctrl_t * p_instance_ctrl);
88 
89 static void r_gpt_disable_irq(IRQn_Type irq);
90 
91 static inline void r_gpt_write_protect_enable(gpt_instance_ctrl_t * const p_instance_ctrl,
92                                               uint32_t                    write_protect_setting);
93 static inline uint32_t r_gpt_write_protect_disable(gpt_instance_ctrl_t * const p_instance_ctrl);
94 
95 /* Noinline attribute added to reduce code size for CM23 GCC build. */
96 static void r_gpt_enable_irq(IRQn_Type const irq, uint32_t priority, void * p_context) __attribute__((noinline));
97 
98 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
99 
100 static void gpt_calculate_duty_cycle(gpt_instance_ctrl_t * const p_instance_ctrl,
101                                      uint32_t const              duty_cycle_counts,
102                                      gpt_prv_duty_registers_t  * p_duty_reg,
103                                      uint32_t                    pin);
104 
105 static uint32_t gpt_gtior_calculate(timer_cfg_t const * const p_cfg, gpt_pin_level_t const stop_level);
106 
107 #endif
108 
109 static void r_gpt_call_callback(gpt_instance_ctrl_t * p_ctrl, timer_event_t event, uint32_t capture);
110 
111 /***********************************************************************************************************************
112  * ISR prototypes
113  **********************************************************************************************************************/
114 void gpt_counter_overflow_isr(void);
115 void gpt_counter_underflow_isr(void);
116 void gpt_capture_a_isr(void);
117 void gpt_capture_b_isr(void);
118 
119 /***********************************************************************************************************************
120  * Private global variables
121  **********************************************************************************************************************/
122 
123 /***********************************************************************************************************************
124  * Global Variables
125  **********************************************************************************************************************/
126 
127 /* GPT implementation of timer interface  */
128 const timer_api_t g_timer_on_gpt =
129 {
130     .open         = R_GPT_Open,
131     .stop         = R_GPT_Stop,
132     .start        = R_GPT_Start,
133     .reset        = R_GPT_Reset,
134     .enable       = R_GPT_Enable,
135     .disable      = R_GPT_Disable,
136     .periodSet    = R_GPT_PeriodSet,
137     .dutyCycleSet = R_GPT_DutyCycleSet,
138     .infoGet      = R_GPT_InfoGet,
139     .statusGet    = R_GPT_StatusGet,
140     .callbackSet  = R_GPT_CallbackSet,
141     .close        = R_GPT_Close,
142 };
143 
144 /*******************************************************************************************************************//**
145  * @addtogroup GPT
146  * @{
147  **********************************************************************************************************************/
148 
149 /***********************************************************************************************************************
150  * Functions
151  **********************************************************************************************************************/
152 
153 /*******************************************************************************************************************//**
154  * Initializes the timer module and applies configurations. Implements @ref timer_api_t::open.
155  *
156  * GPT hardware does not support one-shot functionality natively.  When using one-shot mode, the timer will be stopped
157  * in an ISR after the requested period has elapsed.
158  *
159  * The GPT implementation of the general timer can accept a gpt_extended_cfg_t extension parameter.
160  *
161  * @retval FSP_SUCCESS                    Initialization was successful and timer has started.
162  * @retval FSP_ERR_ASSERTION              A required input pointer is NULL or the source divider is invalid.
163  * @retval FSP_ERR_ALREADY_OPEN           Module is already open.
164  * @retval FSP_ERR_IRQ_BSP_DISABLED       timer_cfg_t::mode is ::TIMER_MODE_ONE_SHOT or timer_cfg_t::p_callback is not
165  *                                        NULL, but ISR is not enabled.  ISR must be enabled to use one-shot mode or
166  *                                        callback.
167  * @retval FSP_ERR_INVALID_MODE           Triangle wave PWM is only supported if GPT_CFG_OUTPUT_SUPPORT_ENABLE is 2.
168  *                                        Selected channel does not support external count sources.
169  *                                        External and event count sources not are available in this mode.
170  * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The channel requested in the p_cfg parameter is not available on this device.
171  **********************************************************************************************************************/
R_GPT_Open(timer_ctrl_t * const p_ctrl,timer_cfg_t const * const p_cfg)172 fsp_err_t R_GPT_Open (timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg)
173 {
174     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
175 #if GPT_CFG_PARAM_CHECKING_ENABLE
176     FSP_ASSERT(NULL != p_cfg);
177     FSP_ASSERT(NULL != p_cfg->p_extend);
178     FSP_ASSERT(NULL != p_instance_ctrl);
179 
180  #if (2U == BSP_FEATURE_GPT_CLOCK_DIVIDER_STEP_SIZE)
181   #if (BSP_FEATURE_GPT_CLOCK_DIVIDER_VALUE_7_9_VALID)
182     FSP_ASSERT(p_cfg->source_div <= 10U);
183   #else
184     FSP_ASSERT((p_cfg->source_div != 7U) && (p_cfg->source_div != 9U) && (p_cfg->source_div <= 10));
185   #endif
186  #else
187     FSP_ASSERT((0U == (p_cfg->source_div % 2U)) && (p_cfg->source_div <= 10));
188  #endif
189 
190  #if GPT_PRV_EXTRA_FEATURES_ENABLED != GPT_CFG_OUTPUT_SUPPORT_ENABLE
191     FSP_ERROR_RETURN(p_cfg->mode <= TIMER_MODE_ONE_SHOT_PULSE, FSP_ERR_INVALID_MODE);
192  #endif
193 
194     FSP_ERROR_RETURN(GPT_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
195 #endif
196 
197     p_instance_ctrl->channel_mask = 1U << p_cfg->channel;
198 
199 #if GPT_CFG_PARAM_CHECKING_ENABLE
200     FSP_ERROR_RETURN((p_instance_ctrl->channel_mask & BSP_FEATURE_GPT_VALID_CHANNEL_MASK),
201                      FSP_ERR_IP_CHANNEL_NOT_PRESENT);
202     if ((p_cfg->p_callback) || (TIMER_MODE_ONE_SHOT == p_cfg->mode))
203     {
204         FSP_ERROR_RETURN(p_cfg->cycle_end_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
205     }
206 
207     gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_cfg->p_extend;
208     FSP_ERROR_RETURN((!p_extend->count_up_source && !p_extend->count_down_source) ||
209                      (BSP_FEATURE_GPT_EVENT_COUNT_CHANNEL_MASK & p_instance_ctrl->channel_mask),
210                      FSP_ERR_INVALID_MODE);
211 
212  #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
213 
214     /* Alternate count sources cannot be used in triangle PWM modes */
215     FSP_ERROR_RETURN(!((p_cfg->mode >= TIMER_MODE_ONE_SHOT_PULSE) &&
216                        (p_extend->count_up_source || p_extend->count_down_source)),
217                      FSP_ERR_INVALID_MODE);
218 
219     /* Callback is required if underflow interrupt is enabled. */
220     gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
221 
222     if (NULL != p_pwm_cfg)
223     {
224         if (p_pwm_cfg->trough_irq >= 0)
225         {
226             FSP_ASSERT(NULL != p_cfg->p_callback);
227         }
228     }
229  #endif
230 #endif
231 
232     /* Initialize control structure based on configurations. */
233     gpt_common_open(p_instance_ctrl, p_cfg);
234 
235     gpt_hardware_initialize(p_instance_ctrl, p_cfg);
236 
237     p_instance_ctrl->open = GPT_OPEN;
238 
239     return FSP_SUCCESS;
240 }
241 
242 /*******************************************************************************************************************//**
243  * Stops timer. Implements @ref timer_api_t::stop.
244  *
245  * @retval FSP_SUCCESS                 Timer successfully stopped.
246  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
247  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
248  **********************************************************************************************************************/
R_GPT_Stop(timer_ctrl_t * const p_ctrl)249 fsp_err_t R_GPT_Stop (timer_ctrl_t * const p_ctrl)
250 {
251     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
252 #if GPT_CFG_PARAM_CHECKING_ENABLE
253     FSP_ASSERT(NULL != p_instance_ctrl);
254     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
255 #endif
256 
257     /* Stop timer */
258     p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
259 
260     return FSP_SUCCESS;
261 }
262 
263 /*******************************************************************************************************************//**
264  * Starts timer. Implements @ref timer_api_t::start.
265  *
266  * @retval FSP_SUCCESS                 Timer successfully started.
267  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
268  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
269  **********************************************************************************************************************/
R_GPT_Start(timer_ctrl_t * const p_ctrl)270 fsp_err_t R_GPT_Start (timer_ctrl_t * const p_ctrl)
271 {
272     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
273 #if GPT_CFG_PARAM_CHECKING_ENABLE
274     FSP_ASSERT(NULL != p_instance_ctrl);
275     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
276 #endif
277 
278     /* Start timer */
279     p_instance_ctrl->p_reg->GTSTR = p_instance_ctrl->channel_mask;
280 
281     return FSP_SUCCESS;
282 }
283 
284 /*******************************************************************************************************************//**
285  * Resets the counter value to 0. Implements @ref timer_api_t::reset.
286  *
287  * @note This function also updates to the new period if no counter overflow has occurred since the last call to
288  * R_GPT_PeriodSet().
289  *
290  * @retval FSP_SUCCESS                 Counter value written successfully.
291  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
292  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
293  **********************************************************************************************************************/
R_GPT_Reset(timer_ctrl_t * const p_ctrl)294 fsp_err_t R_GPT_Reset (timer_ctrl_t * const p_ctrl)
295 {
296     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
297 #if GPT_CFG_PARAM_CHECKING_ENABLE
298     FSP_ASSERT(NULL != p_instance_ctrl);
299     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
300 #endif
301 
302     /* Clear timer counter. */
303     p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
304 
305     return FSP_SUCCESS;
306 }
307 
308 /*******************************************************************************************************************//**
309  * Enables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::enable.
310  *
311  * @retval FSP_SUCCESS                 External events successfully enabled.
312  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
313  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
314  **********************************************************************************************************************/
R_GPT_Enable(timer_ctrl_t * const p_ctrl)315 fsp_err_t R_GPT_Enable (timer_ctrl_t * const p_ctrl)
316 {
317     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
318 #if GPT_CFG_PARAM_CHECKING_ENABLE
319     FSP_ASSERT(NULL != p_instance_ctrl);
320     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
321 #endif
322 
323     /* Enable use of GTSTR, GTSTP, and GTCLR for this channel. */
324     gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
325     uint32_t             gtssr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
326     uint32_t             gtpsr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
327     uint32_t             gtcsr    = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
328 
329     /* OR with user settings. */
330     gtssr |= p_extend->start_source;
331     gtpsr |= p_extend->stop_source;
332     gtcsr |= p_extend->clear_source;
333 
334     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
335 
336     /* Set the count sources. Ensure stop and clear sources are set before start source, and capture sources are set
337      * after start source. */
338     p_instance_ctrl->p_reg->GTPSR   = gtpsr;
339     p_instance_ctrl->p_reg->GTCSR   = gtcsr;
340     p_instance_ctrl->p_reg->GTSSR   = gtssr;
341     p_instance_ctrl->p_reg->GTICASR = p_extend->capture_a_source;
342     p_instance_ctrl->p_reg->GTICBSR = p_extend->capture_b_source;
343 
344     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
345 
346     return FSP_SUCCESS;
347 }
348 
349 /*******************************************************************************************************************//**
350  * Disables external event triggers that start, stop, clear, or capture the counter. Implements @ref timer_api_t::disable.
351  *
352  * @note The timer could be running after R_GPT_Disable(). To ensure it is stopped, call R_GPT_Stop().
353  *
354  * @retval FSP_SUCCESS                 External events successfully disabled.
355  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
356  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
357  **********************************************************************************************************************/
R_GPT_Disable(timer_ctrl_t * const p_ctrl)358 fsp_err_t R_GPT_Disable (timer_ctrl_t * const p_ctrl)
359 {
360     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
361 #if GPT_CFG_PARAM_CHECKING_ENABLE
362     FSP_ASSERT(NULL != p_instance_ctrl);
363     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
364 #endif
365 
366     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
367 
368     gpt_hardware_events_disable(p_instance_ctrl);
369 
370     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
371 
372     return FSP_SUCCESS;
373 }
374 
375 /*******************************************************************************************************************//**
376  * Sets period value provided. If the timer is running, the period will be updated after the next counter overflow.
377  * If the timer is stopped, this function resets the counter and updates the period.
378  * Implements @ref timer_api_t::periodSet.
379  *
380  * @warning If periodic output is used, the duty cycle buffer registers are updated after the period buffer register.
381  * If this function is called while the timer is running and a GPT overflow occurs during processing, the duty cycle
382  * will not be the desired 50% duty cycle until the counter overflow after processing completes.
383  *
384  * @retval FSP_SUCCESS                 Period value written successfully.
385  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
386  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
387  **********************************************************************************************************************/
R_GPT_PeriodSet(timer_ctrl_t * const p_ctrl,uint32_t const period_counts)388 fsp_err_t R_GPT_PeriodSet (timer_ctrl_t * const p_ctrl, uint32_t const period_counts)
389 {
390     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
391 #if GPT_CFG_PARAM_CHECKING_ENABLE
392     FSP_ASSERT(NULL != p_instance_ctrl);
393     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
394 #endif
395 
396     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
397 
398     /* Update period buffer register. The actual period is one cycle longer than the register value for saw waves
399      * and twice the register value for triangle waves. Reference section "General PWM Timer Cycle Setting
400      * Register (GTPR)". The setting passed to the configuration is expected to be half the desired period for
401      * triangle waves. */
402     uint32_t new_gtpr = period_counts - 1U;
403 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
404     if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
405     {
406         new_gtpr = period_counts;
407     }
408 #endif
409 
410     p_instance_ctrl->p_reg->GTPBR = new_gtpr;
411 
412 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
413 
414     /* Set a 50% duty cycle so the period of the waveform on the output pin matches the requested period. */
415     if (TIMER_MODE_PERIODIC == p_instance_ctrl->p_cfg->mode)
416     {
417         /* The  GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used. Reference
418          * figure "Example setting for saw-wave PWM mode" in the user's manual. To get a duty cycle as close
419          * to 50% as possible, duty cycle (register) = (period (counts) / 2) - 1. */
420         uint32_t duty_cycle_50_percent = (period_counts >> 1) - 1U;
421         p_instance_ctrl->p_reg->GTCCRC = duty_cycle_50_percent;
422         p_instance_ctrl->p_reg->GTCCRE = duty_cycle_50_percent;
423     }
424 #endif
425 
426     /* If the counter is not counting, update period register and reset counter. */
427     if (0U == p_instance_ctrl->p_reg->GTCR_b.CST)
428     {
429         p_instance_ctrl->p_reg->GTPR = new_gtpr;
430 
431 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
432         p_instance_ctrl->p_reg->GTBER = GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER;
433 #endif
434 
435         p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
436     }
437 
438     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
439 
440     return FSP_SUCCESS;
441 }
442 
443 /*******************************************************************************************************************//**
444  * Sets duty cycle on requested pin. Implements @ref timer_api_t::dutyCycleSet.
445  *
446  * Duty cycle is updated in the buffer register. The updated duty cycle is reflected after the next cycle end (counter
447  * overflow).
448  *
449  * @param[in] p_ctrl                   Pointer to instance control block.
450  * @param[in] duty_cycle_counts        Duty cycle to set in counts.
451  * @param[in] pin                      Use gpt_io_pin_t to select GPT_IO_PIN_GTIOCA or GPT_IO_PIN_GTIOCB
452  *
453  * @retval FSP_SUCCESS                 Duty cycle updated successfully.
454  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL or the pin is not one of gpt_io_pin_t
455  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
456  * @retval FSP_ERR_INVALID_ARGUMENT    Duty cycle is larger than period.
457  * @retval FSP_ERR_INVALID_MODE        GPT_IO_PIN_TROUGH, and GPT_IO_PIN_CREST settings are invalid in the this mode.
458  * @retval FSP_ERR_UNSUPPORTED         GPT_CFG_OUTPUT_SUPPORT_ENABLE is 0.
459  **********************************************************************************************************************/
R_GPT_DutyCycleSet(timer_ctrl_t * const p_ctrl,uint32_t const duty_cycle_counts,uint32_t const pin)460 fsp_err_t R_GPT_DutyCycleSet (timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin)
461 {
462 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
463     uint32_t              tmp_pin         = pin & 3U;
464     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
465  #if GPT_CFG_PARAM_CHECKING_ENABLE
466     FSP_ASSERT(NULL != p_instance_ctrl);
467     FSP_ASSERT(tmp_pin <= GPT_IO_PIN_GTIOCA_AND_GTIOCB);
468     bool pwm_mode3_pin = 0 != (pin & (GPT_IO_PIN_CREST | GPT_IO_PIN_TROUGH));
469     if (TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM_MODE3 == p_instance_ctrl->p_cfg->mode)
470     {
471         /* In TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM_MODE3, the duty cycle must be for either a trough or crest. */
472         FSP_ERROR_RETURN(pwm_mode3_pin, FSP_ERR_INVALID_MODE);
473     }
474     else
475     {
476         FSP_ERROR_RETURN((!pwm_mode3_pin) || (TIMER_MODE_ONE_SHOT_PULSE == p_instance_ctrl->p_cfg->mode),
477                          FSP_ERR_INVALID_MODE);
478     }
479 
480     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
481     FSP_ERROR_RETURN(duty_cycle_counts <= (p_instance_ctrl->p_reg->GTPR + 1), FSP_ERR_INVALID_ARGUMENT);
482  #endif
483 
484     /* Set duty cycle. */
485     gpt_prv_duty_registers_t duty_regs = {UINT32_MAX, 0};
486     gpt_calculate_duty_cycle(p_instance_ctrl, duty_cycle_counts, &duty_regs, pin);
487 
488     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
489 
490     /* Read modify write bit field access is used to update GTUDDTYC to make sure we don't clobber settings for the
491      * other pin. */
492 
493     uint32_t gtuddtyc = p_instance_ctrl->p_reg->GTUDDTYC;
494 
495     if (!duty_regs.omdty)
496     {
497         if (0U != (pin & GPT_IO_PIN_CREST))
498         {
499             /*
500              * In TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM_MODE3, if this is a crest duty cycle, then update the crest
501              * duty cycle register. Otherwise, update the trough duty cycle register.
502              * Or in case of One-Shot pulse mode, buffer registers are either GTCCRC and GTCCRD for pulses on GTIOCnA pin
503              * or GTCCRE and GTCCRF for pulses on GTIOCnB pin.
504              * Hence update registers GTCCRD, GTCCRF for trailing edge dutycycle counts on GTIOCnA, GTIOCnB respectively, otherwise update
505              * registers GTCCRC,GTCCRE for leading edge dutycycle counts on GTIOCnA, GTIOCnB respectively.
506              */
507             if (0U != (pin & GPT_IO_PIN_GTIOCA_AND_GTIOCB))
508             {
509                 p_instance_ctrl->p_reg->GTCCRD = duty_regs.gtccr_buffer;
510                 p_instance_ctrl->p_reg->GTCCRF = duty_regs.gtccr_buffer;
511             }
512             else
513             {
514                 if (0U != (pin & GPT_IO_PIN_GTIOCB))
515                 {
516                     p_instance_ctrl->p_reg->GTCCRF = duty_regs.gtccr_buffer;
517                 }
518                 else
519                 {
520                     p_instance_ctrl->p_reg->GTCCRD = duty_regs.gtccr_buffer;
521                 }
522             }
523         }
524         else
525         {
526             if (0U != (pin & GPT_IO_PIN_GTIOCA_AND_GTIOCB))
527             {
528                 p_instance_ctrl->p_reg->GTCCRC = duty_regs.gtccr_buffer;
529                 p_instance_ctrl->p_reg->GTCCRE = duty_regs.gtccr_buffer;
530             }
531             else
532             {
533                 if (0U != (pin & GPT_IO_PIN_GTIOCB))
534                 {
535                     p_instance_ctrl->p_reg->GTCCRE = duty_regs.gtccr_buffer;
536                 }
537                 else
538                 {
539                     p_instance_ctrl->p_reg->GTCCRC = duty_regs.gtccr_buffer;
540                 }
541             }
542         }
543     }
544 
545     if (0U != (pin & GPT_BUFFER_FORCE_PUSH))
546     {
547         /* Enable the compare match buffer. */
548         p_instance_ctrl->p_reg->GTBER |= 1U << R_GPT0_GTBER_CCRSWT_Pos;
549     }
550 
551     if (GPT_IO_PIN_GTIOCB != tmp_pin)
552     {
553         /* GTIOCA or both GTIOCA and GTIOCB. */
554         gtuddtyc &= ~R_GPT0_GTUDDTYC_OADTY_Msk;
555         gtuddtyc |= duty_regs.omdty << R_GPT0_GTUDDTYC_OADTY_Pos;
556     }
557 
558     if ((GPT_IO_PIN_GTIOCA_AND_GTIOCB == pin) && duty_regs.omdty)
559     {
560         /* When setting both pins to 0%/100% duty recalculate OBDTY before setting */
561         gpt_calculate_duty_cycle(p_instance_ctrl, duty_cycle_counts, &duty_regs, GPT_IO_PIN_GTIOCB);
562     }
563 
564     if (GPT_IO_PIN_GTIOCA != tmp_pin)
565     {
566         /* GTIOCB or both GTIOCA and GTIOCB. */
567         gtuddtyc &= ~R_GPT0_GTUDDTYC_OBDTY_Msk;
568         gtuddtyc |= duty_regs.omdty << R_GPT0_GTUDDTYC_OBDTY_Pos;
569     }
570 
571     p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc;
572 
573     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
574 
575     return FSP_SUCCESS;
576 #else
577     FSP_PARAMETER_NOT_USED(p_ctrl);
578     FSP_PARAMETER_NOT_USED(duty_cycle_counts);
579     FSP_PARAMETER_NOT_USED(pin);
580 
581     FSP_RETURN(FSP_ERR_UNSUPPORTED);
582 #endif
583 }
584 
585 /*******************************************************************************************************************//**
586  * Get timer information and store it in provided pointer p_info. Implements @ref timer_api_t::infoGet.
587  *
588  * @retval FSP_SUCCESS                 Period, count direction and frequency written to caller's
589  *                                     structure successfully.
590  * @retval FSP_ERR_ASSERTION           p_ctrl or p_info was NULL.
591  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
592  **********************************************************************************************************************/
R_GPT_InfoGet(timer_ctrl_t * const p_ctrl,timer_info_t * const p_info)593 fsp_err_t R_GPT_InfoGet (timer_ctrl_t * const p_ctrl, timer_info_t * const p_info)
594 {
595     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
596 #if GPT_CFG_PARAM_CHECKING_ENABLE
597     FSP_ASSERT(NULL != p_instance_ctrl);
598     FSP_ASSERT(NULL != p_info);
599     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
600 #endif
601 
602     /* Get and store period */
603     uint32_t gtpr          = p_instance_ctrl->p_reg->GTPR;
604     uint32_t period_counts = gtpr + 1;
605 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
606     if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
607     {
608         period_counts = gtpr;
609     }
610 #endif
611     p_info->period_counts = period_counts;
612 
613     /* Get and store clock frequency */
614     p_info->clock_frequency = gpt_clock_frequency_get(p_instance_ctrl);
615 
616     /* Get and store clock counting direction. Read count direction setting */
617     p_info->count_direction = TIMER_DIRECTION_UP;
618 
619     return FSP_SUCCESS;
620 }
621 
622 /*******************************************************************************************************************//**
623  * Get current timer status and store it in provided pointer p_status. Implements @ref timer_api_t::statusGet.
624  *
625  * @retval FSP_SUCCESS                 Current timer state and counter value set successfully.
626  * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
627  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
628  **********************************************************************************************************************/
R_GPT_StatusGet(timer_ctrl_t * const p_ctrl,timer_status_t * const p_status)629 fsp_err_t R_GPT_StatusGet (timer_ctrl_t * const p_ctrl, timer_status_t * const p_status)
630 {
631     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
632 #if GPT_CFG_PARAM_CHECKING_ENABLE
633     FSP_ASSERT(NULL != p_instance_ctrl);
634     FSP_ASSERT(NULL != p_status);
635     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
636 #endif
637 
638     /* Get counter state. */
639     p_status->state = (timer_state_t) p_instance_ctrl->p_reg->GTCR_b.CST;
640 
641     /* Get counter value */
642     p_status->counter = p_instance_ctrl->p_reg->GTCNT;
643 
644     return FSP_SUCCESS;
645 }
646 
647 /*******************************************************************************************************************//**
648  * Set counter value.
649  *
650  * @note Do not call this API while the counter is counting.  The counter value can only be updated while the counter
651  * is stopped.
652  *
653  * @retval FSP_SUCCESS                 Counter value updated.
654  * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
655  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
656  * @retval FSP_ERR_IN_USE              The timer is running.  Stop the timer before calling this function.
657  **********************************************************************************************************************/
R_GPT_CounterSet(timer_ctrl_t * const p_ctrl,uint32_t counter)658 fsp_err_t R_GPT_CounterSet (timer_ctrl_t * const p_ctrl, uint32_t counter)
659 {
660     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
661 #if GPT_CFG_PARAM_CHECKING_ENABLE
662     FSP_ASSERT(NULL != p_instance_ctrl);
663     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
664     FSP_ERROR_RETURN(0U == p_instance_ctrl->p_reg->GTCR_b.CST, FSP_ERR_IN_USE);
665 #endif
666 
667     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
668 
669     /* Set counter value */
670     p_instance_ctrl->p_reg->GTCNT = counter;
671 
672     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
673 
674     return FSP_SUCCESS;
675 }
676 
677 /*******************************************************************************************************************//**
678  * Enable output for GTIOCA and/or GTIOCB.
679  *
680  * @retval FSP_SUCCESS                 Output is enabled.
681  * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
682  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
683  **********************************************************************************************************************/
R_GPT_OutputEnable(timer_ctrl_t * const p_ctrl,gpt_io_pin_t pin)684 fsp_err_t R_GPT_OutputEnable (timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin)
685 {
686     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
687 #if GPT_CFG_PARAM_CHECKING_ENABLE
688     FSP_ASSERT(NULL != p_instance_ctrl);
689     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
690 #endif
691 
692     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
693 
694     uint32_t gtior = p_instance_ctrl->p_reg->GTIOR;
695     if (GPT_IO_PIN_GTIOCB != pin)
696     {
697         /* GTIOCA or both GTIOCA and GTIOCB. */
698         gtior |= R_GPT0_GTIOR_OAE_Msk;
699     }
700 
701     if (GPT_IO_PIN_GTIOCA != pin)
702     {
703         /* GTIOCB or both GTIOCA and GTIOCB. */
704         gtior |= R_GPT0_GTIOR_OBE_Msk;
705     }
706 
707     p_instance_ctrl->p_reg->GTIOR = gtior;
708 
709     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
710 
711     return FSP_SUCCESS;
712 }
713 
714 /*******************************************************************************************************************//**
715  * Disable output for GTIOCA and/or GTIOCB.
716  *
717  * @retval FSP_SUCCESS                 Output is disabled.
718  * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
719  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
720  **********************************************************************************************************************/
R_GPT_OutputDisable(timer_ctrl_t * const p_ctrl,gpt_io_pin_t pin)721 fsp_err_t R_GPT_OutputDisable (timer_ctrl_t * const p_ctrl, gpt_io_pin_t pin)
722 {
723     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
724 #if GPT_CFG_PARAM_CHECKING_ENABLE
725     FSP_ASSERT(NULL != p_instance_ctrl);
726     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
727 #endif
728 
729     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
730 
731     uint32_t gtior = p_instance_ctrl->p_reg->GTIOR;
732     if (GPT_IO_PIN_GTIOCB != pin)
733     {
734         /* GTIOCA or both GTIOCA and GTIOCB. */
735         gtior &= ~R_GPT0_GTIOR_OAE_Msk;
736     }
737 
738     if (GPT_IO_PIN_GTIOCA != pin)
739     {
740         /* GTIOCB or both GTIOCA and GTIOCB. */
741         gtior &= ~R_GPT0_GTIOR_OBE_Msk;
742     }
743 
744     p_instance_ctrl->p_reg->GTIOR = gtior;
745 
746     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
747 
748     return FSP_SUCCESS;
749 }
750 
751 /*******************************************************************************************************************//**
752  * Set A/D converter start request compare match value.
753  *
754  * @retval FSP_SUCCESS                 Counter value updated.
755  * @retval FSP_ERR_ASSERTION           p_ctrl or p_status was NULL.
756  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
757  **********************************************************************************************************************/
R_GPT_AdcTriggerSet(timer_ctrl_t * const p_ctrl,gpt_adc_compare_match_t which_compare_match,uint32_t compare_match_value)758 fsp_err_t R_GPT_AdcTriggerSet (timer_ctrl_t * const    p_ctrl,
759                                gpt_adc_compare_match_t which_compare_match,
760                                uint32_t                compare_match_value)
761 {
762     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
763 #if GPT_CFG_PARAM_CHECKING_ENABLE
764     FSP_ASSERT(NULL != p_instance_ctrl);
765     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
766 #endif
767 
768     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
769 
770     /* Set A/D converter start request compare match value. */
771     volatile uint32_t * p_gtadtr = &p_instance_ctrl->p_reg->GTADTRA;
772     p_gtadtr[which_compare_match] = compare_match_value;
773 
774     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
775 
776     return FSP_SUCCESS;
777 }
778 
779 /*******************************************************************************************************************//**
780  * Set the Output Delay setting for the PWM output pin.
781  *
782  * @retval FSP_SUCCESS                 The output delay was set.
783  * @retval FSP_ERR_ASSERTION           An input parameter was invalid.
784  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
785  * @retval FSP_ERR_INVALID_CHANNEL     The channel does not support this feature.
786  * @retval FSP_ERR_NOT_INITIALIZED     The PWM Output Delay Circuit has not been initialized.
787  * @retval FSP_ERR_INVALID_STATE       The PWM Output Delay setting cannot be updated in the current state.
788  * @retval FSP_ERR_UNSUPPORTED         This feature is not supported on this MCU.
789  **********************************************************************************************************************/
R_GPT_PwmOutputDelaySet(timer_ctrl_t * const p_ctrl,gpt_pwm_output_delay_edge_t edge,gpt_pwm_output_delay_setting_t delay_setting,uint32_t const pin)790 fsp_err_t R_GPT_PwmOutputDelaySet (timer_ctrl_t * const           p_ctrl,
791                                    gpt_pwm_output_delay_edge_t    edge,
792                                    gpt_pwm_output_delay_setting_t delay_setting,
793                                    uint32_t const                 pin)
794 {
795 #if 0U != BSP_FEATURE_GPT_ODC_VALID_CHANNEL_MASK && GPT_CFG_OUTPUT_SUPPORT_ENABLE
796     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
797 
798  #if GPT_CFG_PARAM_CHECKING_ENABLE
799     FSP_ASSERT(NULL != p_instance_ctrl);
800     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
801     FSP_ERROR_RETURN(0U != (BSP_FEATURE_GPT_ODC_VALID_CHANNEL_MASK & p_instance_ctrl->channel_mask),
802                      FSP_ERR_INVALID_CHANNEL);
803     FSP_ERROR_RETURN(0U != (R_GPT_ODC->GTDLYCR1 & R_GPT_ODC_GTDLYCR1_DLLEN_Msk), FSP_ERR_NOT_INITIALIZED);
804 
805     if (TIMER_MODE_PWM == p_instance_ctrl->p_cfg->mode)
806     {
807         /* In Saw-wave mode, do not change the settings for the delay while the compare-match value is greater than or
808          * equal to GTPR - 2. */
809         uint32_t gtpr          = p_instance_ctrl->p_reg->GTPR;
810         uint32_t compare_match = p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRC + pin];
811         FSP_ERROR_RETURN(gtpr - 2 > compare_match, FSP_ERR_INVALID_STATE);
812     }
813     else
814     {
815         uint32_t compare_match;
816         if ((TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM_MODE3 == p_instance_ctrl->p_cfg->mode) ||
817             (TIMER_MODE_ONE_SHOT_PULSE == p_instance_ctrl->p_cfg->mode))
818         {
819             /* In TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM_MODE3, the trough compare match value is set in
820              * GTCCRD, and GTCCRF. */
821             compare_match = p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRD + pin];
822         }
823         else
824         {
825             /* In TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM and TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM, the trough compare match value is
826              * set in GTCCRC, and GTCCRE. */
827             compare_match = p_instance_ctrl->p_reg->GTCCR[GPT_PRV_GTCCRC + pin];
828         }
829 
830         timer_direction_t count_direction = (timer_direction_t) p_instance_ctrl->p_reg->GTST_b.TUCF;
831 
832         /* In Triangle-wave mode, do not change the settings for the delay while the counter if going down and the compare-match
833          * value is less than or equal to 2. */
834         FSP_ERROR_RETURN(TIMER_DIRECTION_DOWN != count_direction || 2 < compare_match, FSP_ERR_INVALID_STATE);
835     }
836  #endif
837 
838     FSP_CRITICAL_SECTION_DEFINE;
839 
840     if (GPT_PWM_OUTPUT_DELAY_SETTING_BYPASS == delay_setting)
841     {
842         /* Enter a critical section in order to ensure that multiple GPT channels don't access the common
843          * register simultaneously. */
844         FSP_CRITICAL_SECTION_ENTER;
845 
846  #if GPT_CFG_WRITE_PROTECT_ENABLE
847 
848         /* GTDLYCR2 is protected by R_GPT::GTWP. */
849         uint32_t wp = R_GPT0->GTWP;
850         R_GPT0->GTWP = GPT_PRV_GTWP_RESET_VALUE;
851         R_GPT0->GTWP;
852  #endif
853 
854         /* Enable the Delay Generation Circuit bypass. */
855         R_GPT_ODC->GTDLYCR2 &= (uint16_t) (~p_instance_ctrl->channel_mask & UINT16_MAX);
856 
857  #if GPT_CFG_WRITE_PROTECT_ENABLE
858 
859         /* Restore the previous value of GTWP. */
860         R_GPT0->GTWP = wp | GPT_PRV_GTWP_RESET_VALUE;
861  #endif
862 
863         FSP_CRITICAL_SECTION_EXIT;
864     }
865     else
866     {
867         /* Calculate the offset for the register than needs to be set. */
868         uint32_t channel_offset = sizeof(uint32_t) * p_instance_ctrl->p_cfg->channel;
869         uint32_t pin_offset     =
870             (uint32_t) ((uint32_t) &R_GPT_ODC->GTDLYR[0].B - (uint32_t) &R_GPT_ODC->GTDLYR[0].A) * pin;
871         uint32_t edge_offset =
872             (uint32_t) ((uint32_t) &R_GPT_ODC->GTDLYF[0].A - (uint32_t) &R_GPT_ODC->GTDLYR[0].A) * edge;
873         uint16_t * p_gtdlyfnx =
874             (uint16_t *) ((uint32_t) &R_GPT_ODC->GTDLYR[0].A + channel_offset + pin_offset + edge_offset);
875 
876         /* Unprotect the delay setting register. */
877         uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
878 
879         /* Write the delay setting to the register. */
880         *p_gtdlyfnx = (uint16_t) delay_setting;
881 
882         /* Restore the previous value of GTWP. */
883         r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
884 
885         /* Check if the channel has already been enabled. */
886         if (0U == (R_GPT_ODC->GTDLYCR2 & p_instance_ctrl->channel_mask))
887         {
888             /* Enter a critical section in order to ensure that multiple GPT channels don't access the common
889              * register simultaneously. */
890             FSP_CRITICAL_SECTION_ENTER;
891 
892  #if GPT_CFG_WRITE_PROTECT_ENABLE
893 
894             /* GTDLYCR2 is protected by R_GPT::GTWP. */
895             wp           = R_GPT0->GTWP;
896             R_GPT0->GTWP = GPT_PRV_GTWP_RESET_VALUE;
897             R_GPT0->GTWP;
898  #endif
899 
900             /* Disable the Delay Generation Circuit bypass. */
901             R_GPT_ODC->GTDLYCR2 |= (uint16_t) p_instance_ctrl->channel_mask;
902 
903  #if GPT_CFG_WRITE_PROTECT_ENABLE
904 
905             /* Restore the previous value of GTWP. */
906             R_GPT0->GTWP = wp | GPT_PRV_GTWP_RESET_VALUE;
907  #endif
908 
909             FSP_CRITICAL_SECTION_EXIT;
910         }
911     }
912 
913     return FSP_SUCCESS;
914 #else
915     FSP_PARAMETER_NOT_USED(p_ctrl);
916     FSP_PARAMETER_NOT_USED(edge);
917     FSP_PARAMETER_NOT_USED(delay_setting);
918     FSP_PARAMETER_NOT_USED(pin);
919 
920     return FSP_ERR_UNSUPPORTED;
921 #endif
922 }
923 
924 /*******************************************************************************************************************//**
925  * Updates the user callback with the option to provide memory for the callback argument structure.
926  * Implements @ref timer_api_t::callbackSet.
927  *
928  * @retval  FSP_SUCCESS                  Callback updated successfully.
929  * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
930  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
931  * @retval  FSP_ERR_NO_CALLBACK_MEMORY   p_callback is non-secure and p_callback_memory is either secure or NULL.
932  **********************************************************************************************************************/
R_GPT_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)933 fsp_err_t R_GPT_CallbackSet (timer_ctrl_t * const          p_api_ctrl,
934                              void (                      * p_callback)(timer_callback_args_t *),
935                              void const * const            p_context,
936                              timer_callback_args_t * const p_callback_memory)
937 {
938     gpt_instance_ctrl_t * p_ctrl = (gpt_instance_ctrl_t *) p_api_ctrl;
939 
940 #if GPT_CFG_PARAM_CHECKING_ENABLE
941     FSP_ASSERT(p_ctrl);
942     FSP_ASSERT(p_callback);
943     FSP_ERROR_RETURN(GPT_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
944 #endif
945 
946 #if BSP_TZ_SECURE_BUILD
947 
948     /* Get security state of p_callback */
949     bool callback_is_secure =
950         (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
951 
952  #if GPT_CFG_PARAM_CHECKING_ENABLE
953 
954     /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
955     timer_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
956                                                                                         CMSE_AU_NONSECURE);
957     FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
958  #endif
959 #endif
960 
961     /* Store callback and context */
962 #if BSP_TZ_SECURE_BUILD
963     p_ctrl->p_callback = callback_is_secure ? p_callback :
964                          (void (*)(timer_callback_args_t *))cmse_nsfptr_create(p_callback);
965 #else
966     p_ctrl->p_callback = p_callback;
967 #endif
968     p_ctrl->p_context         = p_context;
969     p_ctrl->p_callback_memory = p_callback_memory;
970 
971     return FSP_SUCCESS;
972 }
973 
974 /*******************************************************************************************************************//**
975  * Stops counter, disables output pins, and clears internal driver data. Implements @ref timer_api_t::close.
976  *
977  * @retval FSP_SUCCESS                 Successful close.
978  * @retval FSP_ERR_ASSERTION           p_ctrl was NULL.
979  * @retval FSP_ERR_NOT_OPEN            The instance is not opened.
980  **********************************************************************************************************************/
R_GPT_Close(timer_ctrl_t * const p_ctrl)981 fsp_err_t R_GPT_Close (timer_ctrl_t * const p_ctrl)
982 {
983     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) p_ctrl;
984     fsp_err_t             err             = FSP_SUCCESS;
985 
986 #if GPT_CFG_PARAM_CHECKING_ENABLE
987     FSP_ASSERT(NULL != p_instance_ctrl);
988     FSP_ERROR_RETURN(GPT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
989 #endif
990 
991     /* Disable interrupts. */
992     gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
993     r_gpt_disable_irq(p_instance_ctrl->p_cfg->cycle_end_irq);
994     r_gpt_disable_irq(p_extend->capture_a_irq);
995     r_gpt_disable_irq(p_extend->capture_b_irq);
996 
997 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
998     gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
999     if (NULL != p_pwm_cfg)
1000     {
1001         r_gpt_disable_irq(p_pwm_cfg->trough_irq);
1002     }
1003 #endif
1004 
1005     /* Clear open flag. */
1006     p_instance_ctrl->open = 0U;
1007 
1008     uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
1009 
1010     /* Stop counter. */
1011     p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
1012 
1013     /* Disable output. */
1014     p_instance_ctrl->p_reg->GTIOR = 0U;
1015 
1016     /* Disable interrupts.
1017      * Set General PWM Timer Interrupt Output Setting Register(GTINTAD)
1018      */
1019     p_instance_ctrl->p_reg->GTINTAD = 0x00000000;
1020 
1021     r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
1022 
1023     return err;
1024 }
1025 
1026 /*******************************************************************************************************************//**
1027  * Initialize the PWM Delay Generation Circuit (PDG).
1028  * This function must be called before calling @ref R_GPT_PwmOutputDelaySet.
1029  *
1030  * @note This function will delay for 20 microseconds.
1031  *
1032  * @retval FSP_SUCCESS                 Initialization sequence completed successfully.
1033  * @retval FSP_ERR_INVALID_STATE       The source clock frequnecy is out of the required range for the PDG.
1034  * @retval FSP_ERR_UNSUPPORTED         This feature is not supported.
1035  **********************************************************************************************************************/
R_GPT_PwmOutputDelayInitialize()1036 fsp_err_t R_GPT_PwmOutputDelayInitialize ()
1037 {
1038 #if 0U != BSP_FEATURE_GPT_ODC_VALID_CHANNEL_MASK && GPT_CFG_OUTPUT_SUPPORT_ENABLE
1039  #if BSP_FEATURE_GPT_ODC_FRANGE_FREQ_MIN > 0 || GPT_CFG_PARAM_CHECKING_ENABLE
1040   #if BSP_FEATURE_BSP_HAS_GPT_CLOCK && GPT_CFG_GPTCLK_BYPASS == 0
1041 
1042     /* Calculate the GPTCK Divider. */
1043     uint32_t divider = R_SYSTEM->GPTCKDIVCR;
1044 
1045     if (0U == divider)
1046     {
1047         divider = 1U;
1048     }
1049     else
1050     {
1051         divider *= 2U;
1052     }
1053 
1054     /* Calculate the GPTCK Frequency. */
1055     uint32_t gpt_frequency = R_BSP_SourceClockHzGet((fsp_priv_source_clock_t) R_SYSTEM->GPTCKCR_b.GPTCKSEL) / divider;
1056   #else
1057 
1058     /* Calculate the PCLKD Frequency. */
1059     uint32_t gpt_frequency = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKD);
1060   #endif
1061  #endif
1062 
1063  #if GPT_CFG_PARAM_CHECKING_ENABLE
1064     FSP_ERROR_RETURN(BSP_FEATURE_GPT_ODC_FREQ_MAX >= gpt_frequency, FSP_ERR_INVALID_STATE);
1065     FSP_ERROR_RETURN(BSP_FEATURE_GPT_ODC_FREQ_MIN <= gpt_frequency, FSP_ERR_INVALID_STATE);
1066  #endif
1067 
1068     uint32_t gtdlycr1 = R_GPT_ODC_GTDLYCR1_DLYRST_Msk;
1069 
1070  #if BSP_FEATURE_GPT_ODC_FRANGE_FREQ_MIN > 0
1071     if (BSP_FEATURE_GPT_ODC_FRANGE_FREQ_MIN >= gpt_frequency)
1072     {
1073         gtdlycr1 |= R_GPT_ODC_GTDLYCR1_FRANGE_Msk;
1074     }
1075  #endif
1076 
1077  #if BSP_FEATURE_BSP_HAS_GPT_CLOCK && GPT_CFG_GPTCLK_BYPASS
1078 
1079     /* Bypass the GPTCLK. GPT instances will use PCLKD as the GPT Core clock. */
1080     R_GPT_GTCLK->GTCLKCR = 1U;
1081  #endif
1082 
1083     /* Cancel the module-stop state for the PDG. */
1084     R_BSP_MODULE_START(FSP_IP_GPT, 0);
1085 
1086  #if GPT_CFG_WRITE_PROTECT_ENABLE
1087 
1088     /* Disable write protection for GPT registers if they are protected. */
1089     R_GPT0->GTWP = GPT_PRV_GTWP_RESET_VALUE;
1090     R_GPT0->GTWP;
1091  #endif
1092 
1093     /* Reset the PWM Delay Generation Circuit. */
1094     R_GPT_ODC->GTDLYCR1 = (uint16_t) gtdlycr1;
1095     R_GPT_ODC->GTDLYCR2 = 0;
1096 
1097     /* Enable the DLL. */
1098     R_GPT_ODC->GTDLYCR1 = (uint16_t) (gtdlycr1 | R_GPT_ODC_GTDLYCR1_DLLEN_Msk);
1099 
1100     /* Wait for the DLL to be enabled. */
1101     R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MICROSECONDS);
1102 
1103     /* Release the PWM Delay Generation Circuit from reset. */
1104     R_GPT_ODC->GTDLYCR1 &= (uint16_t) ~R_GPT_ODC_GTDLYCR1_DLYRST_Msk;
1105 
1106  #if GPT_CFG_WRITE_PROTECT_ENABLE
1107 
1108     /* Re-enable write protection for GPT registers. */
1109     R_GPT0->GTWP = GPT_PRV_GTWP_WRITE_PROTECT;
1110  #endif
1111 
1112     return FSP_SUCCESS;
1113 #else
1114 
1115     return FSP_ERR_UNSUPPORTED;
1116 #endif
1117 }
1118 
1119 /** @} (end addtogroup GPT) */
1120 
1121 /*******************************************************************************************************************//**
1122  * Private Functions
1123  **********************************************************************************************************************/
1124 
1125 /*******************************************************************************************************************//**
1126  * Enables write protection.
1127  *
1128  * @param[in]  p_instance_ctrl         Instance control block.
1129  * @param[in]  write_protect_setting   The value of GTWP prior to being cleared.
1130  **********************************************************************************************************************/
r_gpt_write_protect_enable(gpt_instance_ctrl_t * const p_instance_ctrl,uint32_t write_protect_setting)1131 static inline void r_gpt_write_protect_enable (gpt_instance_ctrl_t * const p_instance_ctrl,
1132                                                uint32_t                    write_protect_setting)
1133 {
1134 #if GPT_CFG_WRITE_PROTECT_ENABLE
1135     p_instance_ctrl->p_reg->GTWP = write_protect_setting;
1136 #else
1137     FSP_PARAMETER_NOT_USED(p_instance_ctrl);
1138     FSP_PARAMETER_NOT_USED(write_protect_setting);
1139 #endif
1140 }
1141 
1142 /*******************************************************************************************************************//**
1143  * Disables write protection.
1144  *
1145  * @param[in]  p_instance_ctrl         Instance control block.
1146  **********************************************************************************************************************/
r_gpt_write_protect_disable(gpt_instance_ctrl_t * const p_instance_ctrl)1147 static inline uint32_t r_gpt_write_protect_disable (gpt_instance_ctrl_t * const p_instance_ctrl)
1148 {
1149 #if GPT_CFG_WRITE_PROTECT_ENABLE
1150     uint32_t write_protect_setting = p_instance_ctrl->p_reg->GTWP;
1151     p_instance_ctrl->p_reg->GTWP = GPT_PRV_GTWP_RESET_VALUE;
1152 
1153     return write_protect_setting;
1154 #else
1155     FSP_PARAMETER_NOT_USED(p_instance_ctrl);
1156 
1157     return 0U;
1158 #endif
1159 }
1160 
1161 /*******************************************************************************************************************//**
1162  * Initializes control structure based on configuration.
1163  *
1164  * @param[in]  p_instance_ctrl         Instance control block.
1165  * @param[in]  p_cfg                   Pointer to timer configuration.
1166  **********************************************************************************************************************/
gpt_common_open(gpt_instance_ctrl_t * const p_instance_ctrl,timer_cfg_t const * const p_cfg)1167 static void gpt_common_open (gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg)
1168 {
1169     /* Initialize control structure.  */
1170     p_instance_ctrl->p_cfg = p_cfg;
1171 
1172     /* If callback is not null or timer mode is one shot, make sure the IRQ is enabled and store callback in the
1173      *  control block.
1174      *  @note The GPT hardware does not support one-shot mode natively.  To support one-shot mode, the timer will be
1175      *  stopped and cleared using software in the ISR. *//* Determine if this is a 32-bit or a 16-bit timer. */
1176     p_instance_ctrl->variant = TIMER_VARIANT_32_BIT;
1177 
1178     /* Save register base address. */
1179     uint32_t base_address = (uint32_t) R_GPT0 + (p_cfg->channel * ((uint32_t) R_GPT1 - (uint32_t) R_GPT0));
1180     p_instance_ctrl->p_reg = (R_GPT0_Type *) base_address;
1181 
1182     /* Set callback and context pointers, if configured */
1183     p_instance_ctrl->p_callback        = p_cfg->p_callback;
1184     p_instance_ctrl->p_context         = p_cfg->p_context;
1185     p_instance_ctrl->p_callback_memory = NULL;
1186 }
1187 
1188 /*******************************************************************************************************************//**
1189  * Performs hardware initialization of the GPT.
1190  *
1191  * @param[in]  p_instance_ctrl        Instance control block.
1192  * @param[in]  p_cfg                  Pointer to timer configuration.
1193  **********************************************************************************************************************/
gpt_hardware_initialize(gpt_instance_ctrl_t * const p_instance_ctrl,timer_cfg_t const * const p_cfg)1194 static void gpt_hardware_initialize (gpt_instance_ctrl_t * const p_instance_ctrl, timer_cfg_t const * const p_cfg)
1195 {
1196     /* Save pointer to extended configuration structure. */
1197     gpt_extended_cfg_t * p_extend = (gpt_extended_cfg_t *) p_cfg->p_extend;
1198 
1199 #if BSP_FEATURE_BSP_HAS_GPT_CLOCK && GPT_CFG_GPTCLK_BYPASS
1200 
1201     /* Bypass the GPTCLK. GPT instances will use PCLKD as the GPT Core clock. */
1202     R_GPT_GTCLK->GTCLKCR = 1U;
1203 #endif
1204 
1205     /* Power on GPT before setting any hardware registers. Make sure the counter is stopped before setting mode
1206      * register, P0 clock divisor register, and counter register.
1207      */
1208     R_BSP_MODULE_START(FSP_IP_GPT, p_cfg->channel);
1209 
1210 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE && BSP_FEATURE_GPT_ODC_VALID_CHANNEL_MASK
1211     if (0U != (BSP_FEATURE_GPT_ODC_VALID_CHANNEL_MASK & p_instance_ctrl->channel_mask))
1212     {
1213         /* Enter a critical section in order to ensure that multiple GPT channels don't access the common
1214          * register simultaneously. */
1215         FSP_CRITICAL_SECTION_DEFINE;
1216         FSP_CRITICAL_SECTION_ENTER;
1217 
1218  #if GPT_CFG_WRITE_PROTECT_ENABLE
1219 
1220         /* Disable write protection for GPT registers if they are protected. */
1221         uint32_t wp = R_GPT0->GTWP;
1222         R_GPT0->GTWP = GPT_PRV_GTWP_RESET_VALUE;
1223         R_GPT0->GTWP;
1224  #endif
1225 
1226         /* Enable the Delay Generation Circuit bypass. */
1227         R_GPT_ODC->GTDLYCR2 &= (uint16_t) (~p_instance_ctrl->channel_mask & UINT16_MAX);
1228 
1229  #if GPT_CFG_WRITE_PROTECT_ENABLE
1230         R_GPT0->GTWP = wp | GPT_PRV_GTWP_RESET_VALUE;
1231  #endif
1232 
1233         FSP_CRITICAL_SECTION_EXIT;
1234     }
1235 #endif
1236 
1237     /* Initialize all registers that may affect operation of this driver to reset values.  Skip these since they
1238      * affect all channels, and are initialized in GTCR and GTCNT: GTSTR, GTSTP, GTCLR. GTCR is set immediately after
1239      * clearing the module stop bit to ensure the timer is stopped before proceeding with configuration. */
1240     p_instance_ctrl->p_reg->GTWP  = GPT_PRV_GTWP_RESET_VALUE;
1241     p_instance_ctrl->p_reg->GTCR  = 0U;
1242     p_instance_ctrl->p_reg->GTST  = 0U;
1243     p_instance_ctrl->p_reg->GTCNT = 0U;
1244 
1245     /* GTPR, GTCCRn, GTIOR, GTSSR, GTPSR, GTCSR, GTUPSR, GTDNSR, GTPBR, and GTUDDTYC are set by this driver. */
1246 
1247     /* Initialization sets all register required for up counting as described in user's manual
1248      * (Figure "Example setting for a periodic count operation in up-counting by the count clock"
1249      *  in the user's manual) and other registers required by the driver. */
1250 
1251     /* Dividers for GPT are half the enum value. */
1252     uint32_t gtcr_tpcs = p_cfg->source_div >> BSP_FEATURE_GPT_TPCS_SHIFT;
1253     uint32_t gtcr      = gtcr_tpcs << R_GPT0_GTCR_TPCS_Pos;
1254 
1255     /* Store period register setting. The actual period and is one cycle longer than the register value for saw waves
1256      * and twice the register value for triangle waves. Reference section "General PWM Timer Cycle Setting
1257      * Register (GTPR)". The setting passed to the configuration is expected to be half the desired period for
1258      * triangle waves. */
1259     uint32_t gtpr = p_cfg->period_counts - 1U;
1260 
1261     /* Set GTCR.MD = 0x001 for TIMER_MODE_ONE_SHOT_PULSE mode. */
1262     if (TIMER_MODE_ONE_SHOT_PULSE == p_cfg->mode)
1263     {
1264         gtcr |= (1U << R_GPT0_GTCR_MD_Pos);
1265     }
1266 
1267 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1268 
1269     /* Saw-wave PWM mode is set in GTCR.MD for all modes except TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM and
1270      * TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM. */
1271     if (p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
1272     {
1273         gtcr |= ((uint32_t) p_cfg->mode << R_GPT0_GTCR_MD_Pos);
1274         gtpr  = p_cfg->period_counts;
1275     }
1276 #endif
1277 
1278     /* Counter must be stopped to update TPCS. Reference section "General PWM Timer Control Register (GTCR)"
1279      * in the user's manual. */
1280     p_instance_ctrl->p_reg->GTCR = gtcr;
1281 
1282     gpt_hardware_events_disable(p_instance_ctrl);
1283 
1284     /* Configure the up/down count sources. These are not affected by enable/disable. */
1285     p_instance_ctrl->p_reg->GTUPSR = p_extend->count_up_source;
1286     p_instance_ctrl->p_reg->GTDNSR = p_extend->count_down_source;
1287 
1288     /* Set period. The actual period is one cycle longer than the register value. Reference section
1289      * "General PWM Timer Cycle Setting Register (GTPR)". */
1290     p_instance_ctrl->p_reg->GTPBR = gtpr;
1291     p_instance_ctrl->p_reg->GTPR  = gtpr;
1292 
1293     uint32_t gtuddtyc = 0U;
1294     uint32_t gtior    = p_extend->gtior_setting.gtior;
1295 
1296 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
1297 
1298     /* For one shot mode, the compare match buffer register must be loaded with a value that exceeds the timer
1299      * cycle end value so that second compare match event would never occur and hence there will be only a
1300      * single pulse. */
1301     gpt_prv_duty_registers_t duty_regs = {UINT32_MAX, 0};
1302 
1303     if (TIMER_MODE_PERIODIC == p_cfg->mode)
1304     {
1305         /* The  GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used. Reference
1306          * figure "Example setting for saw-wave PWM mode" in the user's manual. To get a duty cycle as close
1307          * to 50% as possible, duty cycle (register) = (period (counts) / 2) - 1. */
1308         uint32_t duty_cycle_50_percent = (p_cfg->period_counts >> 1) - 1U;
1309         duty_regs.gtccr_buffer = duty_cycle_50_percent;
1310     }
1311 
1312     if (p_cfg->mode >= TIMER_MODE_PWM)
1313     {
1314         gpt_calculate_duty_cycle(p_instance_ctrl, p_cfg->duty_cycle_counts, &duty_regs, GPT_IO_PIN_GTIOCA);
1315     }
1316 
1317     /* Set the compare match and compare match buffer registers based on previously calculated values. */
1318     p_instance_ctrl->p_reg->GTCCRC = duty_regs.gtccr_buffer;
1319     p_instance_ctrl->p_reg->GTCCRE = duty_regs.gtccr_buffer;
1320 
1321     /* If the requested duty cycle is 0% or 100%, set this in the registers. */
1322     gtuddtyc |= duty_regs.omdty << R_GPT0_GTUDDTYC_OADTY_Pos;
1323     gtuddtyc |= duty_regs.omdty << R_GPT0_GTUDDTYC_OBDTY_Pos;
1324 
1325     /* Check if custom GTIOR settings are provided. */
1326     if (0 == p_extend->gtior_setting.gtior)
1327     {
1328         /* If custom GTIOR settings are not provided, calculate GTIOR. */
1329         if (p_extend->gtioca.output_enabled)
1330         {
1331             uint32_t gtioca_gtior = gpt_gtior_calculate(p_cfg, p_extend->gtioca.stop_level);
1332             gtior |= gtioca_gtior << R_GPT0_GTIOR_GTIOA_Pos;
1333         }
1334 
1335         if (p_extend->gtiocb.output_enabled)
1336         {
1337             uint32_t gtiocb_gtior = gpt_gtior_calculate(p_cfg, p_extend->gtiocb.stop_level);
1338             gtior |= gtiocb_gtior << R_GPT0_GTIOR_GTIOB_Pos;
1339         }
1340     }
1341 #endif
1342 
1343     /* It must be cleared before setting. When modifying the
1344      * IVTT[2:0] bits, first set the IVTC[1:0] bits to 00b.  Reference section "General PWM Timer Interrupt
1345      * and A/D Converter Start Request Skipping Setting Register (GTITC)"" of the user's manual. */
1346     p_instance_ctrl->p_reg->GTITC = 0U;
1347 
1348 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1349     gpt_extended_pwm_cfg_t const * p_pwm_cfg = p_extend->p_pwm_cfg;
1350     if (NULL != p_pwm_cfg)
1351     {
1352         p_instance_ctrl->p_reg->GTINTAD = ((uint32_t) p_pwm_cfg->output_disable << R_GPT0_GTINTAD_GRPDTE_Pos) |
1353                                           ((uint32_t) p_pwm_cfg->poeg_link << R_GPT0_GTINTAD_GRP_Pos) |
1354                                           ((uint32_t) p_pwm_cfg->adc_trigger << R_GPT0_GTINTAD_ADTRAUEN_Pos);
1355         p_instance_ctrl->p_reg->GTDVU = p_pwm_cfg->dead_time_count_up;
1356 
1357         /* Set GTDTCR.TDE only if one of the dead time values is non-zero. */
1358         uint32_t gtdtcr = ((p_pwm_cfg->dead_time_count_up > 0) || (p_pwm_cfg->dead_time_count_down > 0));
1359 
1360         p_instance_ctrl->p_reg->GTITC = ((uint32_t) p_pwm_cfg->interrupt_skip_source << R_GPT0_GTITC_IVTC_Pos) |
1361                                         ((uint32_t) p_pwm_cfg->interrupt_skip_count << R_GPT0_GTITC_IVTT_Pos) |
1362                                         ((uint32_t) p_pwm_cfg->interrupt_skip_adc << R_GPT0_GTITC_ADTAL_Pos);
1363         p_instance_ctrl->p_reg->GTDVD   = p_pwm_cfg->dead_time_count_down;
1364         p_instance_ctrl->p_reg->GTADTRA = p_pwm_cfg->adc_a_compare_match;
1365         p_instance_ctrl->p_reg->GTADTRB = p_pwm_cfg->adc_b_compare_match;
1366 
1367         /* Check if custom GTIOR settings are provided. */
1368         if (0 == p_extend->gtior_setting.gtior)
1369         {
1370             /* If custom GTIOR settings are not provided, set gtioca_disable_settings and gtiocb_disable_settings. */
1371             gtior |= (uint32_t) (p_pwm_cfg->gtioca_disable_setting << R_GPT0_GTIOR_OADF_Pos);
1372             gtior |= (uint32_t) (p_pwm_cfg->gtiocb_disable_setting << R_GPT0_GTIOR_OBDF_Pos);
1373         }
1374 
1375         p_instance_ctrl->p_reg->GTDTCR = gtdtcr;
1376     }
1377     else
1378 #endif
1379     {
1380         /* General PWM Timer Interrupt Output Setting Register (GTINTAD).
1381          * GTADTR registers are unused if GTINTAD is cleared. */
1382         p_instance_ctrl->p_reg->GTINTAD = 0U;
1383         p_instance_ctrl->p_reg->GTDTCR  = 0U;
1384 
1385         /* GTDVU, GTDVD, GTDBU, GTDBD, and GTSOTR are not used if GTDTCR is cleared. */
1386     }
1387 
1388     /* Check if custom GTIOR settings are provided. */
1389     if (0 == p_extend->gtior_setting.gtior)
1390     {
1391         /*
1392          * If custom GTIOR settings are not provided, configure the noise filter for
1393          * the GTIOC pins.
1394          */
1395         gtior |= (uint32_t) (p_extend->capture_filter_gtioca << R_GPT0_GTIOR_NFAEN_Pos);
1396         gtior |= (uint32_t) (p_extend->capture_filter_gtiocb << R_GPT0_GTIOR_NFBEN_Pos);
1397     }
1398 
1399     /* Enable the compare match buffer. */
1400     p_instance_ctrl->p_reg->GTBER = GPT_PRV_GTBER_BUFFER_ENABLE_FORCE_TRANSFER;
1401 
1402 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
1403     if (TIMER_MODE_ONE_SHOT == p_cfg->mode)
1404     {
1405         /* In one shot mode, the output pin toggles when counting starts, then again when the period expires.
1406          * The buffer is enabled to set the compare match to UINT32_MAX after the one shot pulse is output
1407          * so that the pin level will not change if the period expires again before the timer is stopped in
1408          * the interrupt.*/
1409         p_instance_ctrl->p_reg->GTCCRA = 0U;
1410         p_instance_ctrl->p_reg->GTCCRB = 0U;
1411     }
1412 #endif
1413 
1414     /* Reset counter to 0. */
1415     p_instance_ctrl->p_reg->GTCLR = p_instance_ctrl->channel_mask;
1416 
1417     /* Set the I/O control register. */
1418     p_instance_ctrl->p_reg->GTIOR = gtior;
1419 
1420     /* Configure duty cycle and force timer to count up. GTUDDTYC must be set, then cleared to force the count
1421      * direction to be reflected when counting starts. Reference section "General PWM Timer Count Direction
1422      * and Duty Setting Register (GTUDDTYC)" in the user's manual. */
1423     p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc | 3U;
1424     p_instance_ctrl->p_reg->GTUDDTYC = gtuddtyc | 1U;
1425 
1426     /* Enable CPU interrupts if callback is not null.  Also enable interrupts for one shot mode.
1427      *  @note The GPT hardware does not support one-shot mode natively. To support one-shot mode, the timer will be
1428      *  stopped and cleared using software in the ISR. */
1429     r_gpt_enable_irq(p_cfg->cycle_end_irq, p_cfg->cycle_end_ipl, p_instance_ctrl);
1430     r_gpt_enable_irq(p_extend->capture_a_irq, p_extend->capture_a_ipl, p_instance_ctrl);
1431     r_gpt_enable_irq(p_extend->capture_b_irq, p_extend->capture_b_ipl, p_instance_ctrl);
1432 
1433     /* Enable interrupts.
1434      * Set General PWM Timer Interrupt Output Setting Register(GTINTAD). */
1435     p_instance_ctrl->p_reg->GTINTAD |= GPT_PRV_GTINTAD_INTERRUPT_ENABLE;
1436 
1437 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1438     if (NULL != p_pwm_cfg)
1439     {
1440         r_gpt_enable_irq(p_pwm_cfg->trough_irq, p_pwm_cfg->trough_ipl, p_instance_ctrl);
1441         p_instance_ctrl->p_reg->GTINTAD |= GPT_PRV_GTINTAD_UNDERFLOW_INTERRUPT_ENABLE;
1442     }
1443 #endif
1444 
1445     r_gpt_write_protect_enable(p_instance_ctrl, GPT_PRV_GTWP_WRITE_PROTECT);
1446 }
1447 
1448 /*******************************************************************************************************************//**
1449  * Disables hardware events that would cause the timer to start, stop, clear, or capture.
1450  *
1451  * @param[in]  p_instance_ctrl         Instance control structure
1452  **********************************************************************************************************************/
gpt_hardware_events_disable(gpt_instance_ctrl_t * p_instance_ctrl)1453 static void gpt_hardware_events_disable (gpt_instance_ctrl_t * p_instance_ctrl)
1454 {
1455     /* Enable use of GTSTR, GTSTP, and GTCLR for this channel. */
1456     p_instance_ctrl->p_reg->GTSSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
1457     p_instance_ctrl->p_reg->GTPSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
1458     p_instance_ctrl->p_reg->GTCSR   = GPT_PRV_ENABLE_GROUP_SOFTWARE_UPDATE;
1459     p_instance_ctrl->p_reg->GTICASR = GPT_SOURCE_NONE;
1460     p_instance_ctrl->p_reg->GTICBSR = GPT_SOURCE_NONE;
1461 }
1462 
1463 /*******************************************************************************************************************//**
1464  * Disables interrupt if it is a valid vector number.
1465  *
1466  * @param[in]  irq                     Interrupt number
1467  **********************************************************************************************************************/
r_gpt_disable_irq(IRQn_Type irq)1468 static void r_gpt_disable_irq (IRQn_Type irq)
1469 {
1470     /* Disable interrupts. */
1471     if (irq >= 0)
1472     {
1473         R_BSP_IrqDisable(irq);
1474         R_FSP_IsrContextSet(irq, NULL);
1475     }
1476 }
1477 
1478 /*******************************************************************************************************************//**
1479  * Configures and enables interrupt if it is a valid vector number.
1480  *
1481  * @param[in]  irq                     Interrupt number
1482  * @param[in]  priority                NVIC priority of the interrupt
1483  * @param[in]  p_context               The interrupt context is a pointer to data required in the ISR.
1484  **********************************************************************************************************************/
r_gpt_enable_irq(IRQn_Type const irq,uint32_t priority,void * p_context)1485 static void r_gpt_enable_irq (IRQn_Type const irq, uint32_t priority, void * p_context)
1486 {
1487     if (irq >= 0)
1488     {
1489         R_BSP_IrqCfgEnable(irq, priority, p_context);
1490     }
1491 }
1492 
1493 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
1494 
1495 /*******************************************************************************************************************//**
1496  * Calculates duty cycle register values.  GTPR must be set before entering this function.
1497  *
1498  * @param[in]  p_instance_ctrl         Instance control structure
1499  * @param[in]  duty_cycle_counts       Duty cycle to set
1500  * @param[out] p_duty_reg              Duty cycle register values
1501  **********************************************************************************************************************/
gpt_calculate_duty_cycle(gpt_instance_ctrl_t * const p_instance_ctrl,uint32_t const duty_cycle_counts,gpt_prv_duty_registers_t * p_duty_reg,uint32_t pin)1502 static void gpt_calculate_duty_cycle (gpt_instance_ctrl_t * const p_instance_ctrl,
1503                                       uint32_t const              duty_cycle_counts,
1504                                       gpt_prv_duty_registers_t  * p_duty_reg,
1505                                       uint32_t                    pin)
1506 {
1507     /* Determine the current period. The actual period is one cycle longer than the register value for saw waves
1508      * and twice the register value for triangle waves. Reference section "General PWM Timer Cycle Setting
1509      * Register (GTPR)". The setting passed to the configuration is expected to be half the desired duty cycle for
1510      * triangle waves. */
1511     uint32_t current_period = p_instance_ctrl->p_reg->GTPR;
1512  #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1513     if (p_instance_ctrl->p_cfg->mode < TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
1514  #endif
1515     {
1516         current_period++;
1517     }
1518 
1519     bool duty_zero = (0U == duty_cycle_counts);
1520     bool duty_high = (duty_cycle_counts >= current_period);
1521 
1522     if (duty_zero || duty_high)
1523     {
1524         uint32_t gtior;
1525 
1526         if (!(GPT_IO_PIN_GTIOCB & pin))
1527         {
1528             gtior = p_instance_ctrl->p_reg->GTIOR_b.GTIOA;
1529         }
1530         else
1531         {
1532             gtior = p_instance_ctrl->p_reg->GTIOR_b.GTIOB;
1533         }
1534 
1535         bool first_level_low;
1536 
1537         if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
1538         {
1539             /* In triangle PWM modes use the initial pin level to determine 0%/100% setting. */
1540             first_level_low = !(gtior & 0x10);
1541         }
1542         else
1543         {
1544             /* In normal PWM mode use the cycle end setting to determine 0%/100% setting */
1545             first_level_low = (gtior & 0xC) == 0x4;
1546         }
1547 
1548         if ((duty_zero && !first_level_low) || (duty_high && first_level_low))
1549         {
1550             p_duty_reg->omdty = GPT_DUTY_CYCLE_MODE_0_PERCENT;
1551         }
1552         else
1553         {
1554             p_duty_reg->omdty = GPT_DUTY_CYCLE_MODE_100_PERCENT;
1555         }
1556     }
1557     else
1558     {
1559         uint32_t temp_duty_cycle = duty_cycle_counts;
1560 
1561  #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1562         if (p_instance_ctrl->p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
1563         {
1564             p_duty_reg->gtccr_buffer = temp_duty_cycle;
1565         }
1566         else
1567  #endif
1568         {
1569             /* The GTIOCA/GTIOCB pins transition 1 cycle after compare match when buffer operation is used. Reference
1570              * figure "Example setting for saw-wave PWM mode" in the user's manual. */
1571             temp_duty_cycle--;
1572             p_duty_reg->gtccr_buffer = temp_duty_cycle;
1573         }
1574     }
1575 }
1576 
1577 #endif
1578 
1579 /*******************************************************************************************************************//**
1580  * Calculates clock frequency of GPT counter.  Divides GPT clock by GPT clock divisor.
1581  *
1582  * @param[in]  p_instance_ctrl           Instance control block
1583  *
1584  * @return     Clock frequency of the GPT counter.
1585  **********************************************************************************************************************/
gpt_clock_frequency_get(gpt_instance_ctrl_t * const p_instance_ctrl)1586 static uint32_t gpt_clock_frequency_get (gpt_instance_ctrl_t * const p_instance_ctrl)
1587 {
1588     /* Look up GPT clock frequency and divide it by GPT clock divider. */
1589     timer_source_div_t gptclk_divisor =
1590         (timer_source_div_t) ((p_instance_ctrl->p_reg->GTCR_b.TPCS) << BSP_FEATURE_GPT_TPCS_SHIFT);
1591     uint32_t gptclk_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_P0CLK);
1592 
1593     return gptclk_freq_hz >> gptclk_divisor;
1594 }
1595 
1596 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
1597 
1598 /*******************************************************************************************************************//**
1599  * Calculates GTIOR settings for given mode and stop level.
1600  *
1601  * @param[in]  p_instance_ctrl         Instance control block
1602  * @param[in]  p_cfg                   Timer configuration
1603  * @param[in]  level                   Output level after timer stops
1604  **********************************************************************************************************************/
gpt_gtior_calculate(timer_cfg_t const * const p_cfg,gpt_pin_level_t const stop_level)1605 static uint32_t gpt_gtior_calculate (timer_cfg_t const * const p_cfg, gpt_pin_level_t const stop_level)
1606 {
1607     /* The stop level is used as both the initial level and the stop level. */
1608     uint32_t gtior = R_GPT0_GTIOR_OAE_Msk | ((uint32_t) stop_level << R_GPT0_GTIOR_OADFLT_Pos) |
1609                      ((uint32_t) stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT);
1610 
1611     uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END;
1612 
1613     if (TIMER_MODE_PWM == p_cfg->mode)
1614     {
1615         /* Use default: GTIOn is high at cycle end, then low at compare match. */
1616     }
1617 
1618  #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1619     else if (p_cfg->mode >= TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM)
1620     {
1621         gtion = GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH;
1622     }
1623  #endif
1624     else if (TIMER_MODE_ONE_SHOT_PULSE == p_cfg->mode)
1625     {
1626         gtion = GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH;
1627     }
1628     else
1629     {
1630         /* In one-shot mode, the output pin goes high after the first compare match (one cycle after the timer starts counting). */
1631         if (GPT_PIN_LEVEL_LOW == stop_level)
1632         {
1633             gtion = GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END;
1634         }
1635     }
1636 
1637     gtior |= gtion;
1638 
1639     return gtior;
1640 }
1641 
1642 #endif
1643 
1644 /*******************************************************************************************************************//**
1645  * Calls user callback.
1646  *
1647  * @param[in]     p_ctrl     Pointer to GPT instance control block
1648  * @param[in]     event      Event code
1649  * @param[in]     capture    Event capture counts (if applicable)
1650  **********************************************************************************************************************/
r_gpt_call_callback(gpt_instance_ctrl_t * p_ctrl,timer_event_t event,uint32_t capture)1651 static void r_gpt_call_callback (gpt_instance_ctrl_t * p_ctrl, timer_event_t event, uint32_t capture)
1652 {
1653     timer_callback_args_t args;
1654 
1655     /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
1656      * stored in non-secure memory so they can be accessed by a non-secure callback function. */
1657     timer_callback_args_t * p_args = p_ctrl->p_callback_memory;
1658     if (NULL == p_args)
1659     {
1660         /* Store on stack */
1661         p_args = &args;
1662     }
1663     else
1664     {
1665         /* Save current arguments on the stack in case this is a nested interrupt. */
1666         args = *p_args;
1667     }
1668 
1669     p_args->event     = event;
1670     p_args->capture   = capture;
1671     p_args->p_context = p_ctrl->p_context;
1672 
1673 #if BSP_TZ_SECURE_BUILD
1674 
1675     /* p_callback can point to a secure function or a non-secure function. */
1676     if (!cmse_is_nsfptr(p_ctrl->p_callback))
1677     {
1678         /* If p_callback is secure, then the project does not need to change security state. */
1679         p_ctrl->p_callback(p_args);
1680     }
1681     else
1682     {
1683         /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
1684         gpt_prv_ns_callback p_callback = (gpt_prv_ns_callback) (p_ctrl->p_callback);
1685         p_callback(p_args);
1686     }
1687 
1688 #else
1689 
1690     /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
1691     p_ctrl->p_callback(p_args);
1692 #endif
1693 
1694     if (NULL != p_ctrl->p_callback_memory)
1695     {
1696         /* Restore callback memory in case this is a nested interrupt. */
1697         *p_ctrl->p_callback_memory = args;
1698     }
1699 }
1700 
1701 /*******************************************************************************************************************//**
1702  * Common processing for input capture interrupt.
1703  *
1704  * @param[in]  event  Which input capture event occurred
1705  **********************************************************************************************************************/
r_gpt_capture_common_isr(gpt_prv_capture_event_t event)1706 static void r_gpt_capture_common_isr (gpt_prv_capture_event_t event)
1707 {
1708     /* Save context if RTOS is used */
1709     FSP_CONTEXT_SAVE
1710 
1711     IRQn_Type irq     = R_FSP_CurrentIrqGet();
1712     uint32_t  counter = 0U;
1713 
1714     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1715     R_BSP_IrqStatusClear(irq);
1716 
1717     /* Recover ISR context saved in open. */
1718     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1719 
1720     /* Get captured value. */
1721     if (event == GPT_PRV_CAPTURE_EVENT_A)
1722     {
1723         counter = p_instance_ctrl->p_reg->GTCCRA;
1724     }
1725     else
1726     {
1727         counter = p_instance_ctrl->p_reg->GTCCRB;
1728     }
1729 
1730     /* If we captured a one-shot pulse, then disable future captures. */
1731     if (TIMER_MODE_ONE_SHOT == p_instance_ctrl->p_cfg->mode)
1732     {
1733         /* Disable captures. */
1734         gpt_hardware_events_disable(p_instance_ctrl);
1735 
1736         /* Clear pending interrupt to make sure it doesn't fire again if another overflow has already occurred. */
1737         R_BSP_IrqClearPending(irq);
1738     }
1739 
1740     /* If a callback is provided, then call it with the captured counter value. */
1741     if (NULL != p_instance_ctrl->p_callback)
1742     {
1743         r_gpt_call_callback(p_instance_ctrl,
1744                             (timer_event_t) ((uint32_t) TIMER_EVENT_CAPTURE_A + (uint32_t) event),
1745                             counter);
1746     }
1747 
1748     /* Restore context if RTOS is used */
1749     FSP_CONTEXT_RESTORE
1750 }
1751 
1752 /*******************************************************************************************************************//**
1753  * Stops the timer if one-shot mode, clears interrupts, and calls callback if one was provided in the open function.
1754  **********************************************************************************************************************/
gpt_counter_overflow_isr(void)1755 void gpt_counter_overflow_isr (void)
1756 {
1757     /* Save context if RTOS is used */
1758     FSP_CONTEXT_SAVE
1759 
1760     IRQn_Type irq = R_FSP_CurrentIrqGet();
1761 
1762     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1763     R_BSP_IrqStatusClear(irq);
1764 
1765     /* Recover ISR context saved in open. */
1766     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1767 
1768     /* If one-shot mode is selected, stop the timer since period has expired. */
1769     if (TIMER_MODE_ONE_SHOT == p_instance_ctrl->p_cfg->mode)
1770     {
1771         uint32_t wp = r_gpt_write_protect_disable(p_instance_ctrl);
1772 
1773         p_instance_ctrl->p_reg->GTSTP = p_instance_ctrl->channel_mask;
1774 
1775         /* Clear the GPT counter and the overflow flag after the one shot pulse has being generated */
1776         p_instance_ctrl->p_reg->GTCNT  = 0;
1777         p_instance_ctrl->p_reg->GTCCRA = 0;
1778         p_instance_ctrl->p_reg->GTCCRB = 0;
1779 
1780         r_gpt_write_protect_enable(p_instance_ctrl, wp | GPT_PRV_GTWP_RESET_VALUE);
1781 
1782         /* Clear pending interrupt to make sure it doesn't fire again if another overflow has already occurred. */
1783         R_BSP_IrqClearPending(irq);
1784     }
1785 
1786     if (NULL != p_instance_ctrl->p_callback)
1787     {
1788         r_gpt_call_callback(p_instance_ctrl, TIMER_EVENT_CYCLE_END, 0);
1789     }
1790 
1791     /* Restore context if RTOS is used */
1792     FSP_CONTEXT_RESTORE
1793 }
1794 
1795 #if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE
1796 
1797 /*******************************************************************************************************************//**
1798  * Only supported for asymmetric triangle-wave PWM. Notifies application of trough event.
1799  **********************************************************************************************************************/
gpt_counter_underflow_isr(void)1800 void gpt_counter_underflow_isr (void)
1801 {
1802     /* Save context if RTOS is used */
1803     FSP_CONTEXT_SAVE
1804 
1805     IRQn_Type irq = R_FSP_CurrentIrqGet();
1806 
1807     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1808     R_BSP_IrqStatusClear(irq);
1809 
1810     /* Recover ISR context saved in open. */
1811     gpt_instance_ctrl_t * p_instance_ctrl = (gpt_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1812 
1813     /* Call user callback. */
1814     r_gpt_call_callback(p_instance_ctrl, TIMER_EVENT_TROUGH, 0);
1815 
1816     /* Restore context if RTOS is used */
1817     FSP_CONTEXT_RESTORE
1818 }
1819 
1820 #endif
1821 
1822 /*******************************************************************************************************************//**
1823  * Interrupt triggered by a capture A source.
1824  *
1825  * Clears interrupt, disables captures if one-shot mode, and calls callback if one was provided in the open function.
1826  **********************************************************************************************************************/
gpt_capture_a_isr(void)1827 void gpt_capture_a_isr (void)
1828 {
1829     r_gpt_capture_common_isr(GPT_PRV_CAPTURE_EVENT_A);
1830 }
1831 
1832 /*******************************************************************************************************************//**
1833  * Interrupt triggered by a capture B source.
1834  *
1835  * Clears interrupt, disables captures if one-shot mode, and calls callback if one was provided in the open function.
1836  **********************************************************************************************************************/
gpt_capture_b_isr(void)1837 void gpt_capture_b_isr (void)
1838 {
1839     r_gpt_capture_common_isr(GPT_PRV_CAPTURE_EVENT_B);
1840 }
1841