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 "bsp_api.h"
11 #include "r_sci_uart.h"
12 #include <string.h>
13 
14 /***********************************************************************************************************************
15  * Macro definitions
16  **********************************************************************************************************************/
17 #ifndef SCI_UART_CFG_RX_ENABLE
18  #define SCI_UART_CFG_RX_ENABLE                 1
19 #endif
20 #ifndef SCI_UART_CFG_TX_ENABLE
21  #define SCI_UART_CFG_TX_ENABLE                 1
22 #endif
23 
24 /* Number of divisors in the data table used for baud rate calculation. */
25 #define SCI_UART_NUM_DIVISORS_ASYNC             (13U)
26 
27 /* Valid range of values for the modulation duty register is 128 - 256 (256 = modulation disabled). */
28 #define SCI_UART_MDDR_MIN                       (128U)
29 #define SCI_UART_MDDR_MAX                       (256U)
30 
31 /* The bit rate register is 8-bits, so the maximum value is 255. */
32 #define SCI_UART_BRR_MAX                        (255U)
33 
34 /* No limit to the number of bytes to read or write if DTC is not used. */
35 #define SCI_UART_MAX_READ_WRITE_NO_DTC          (0xFFFFFFFFU)
36 
37 /* Mask of invalid data bits in 9-bit mode. */
38 #define SCI_UART_ALIGN_2_BYTES                  (0x1U)
39 
40 /* "SCIU" in ASCII.  Used to determine if the control block is open. */
41 #define SCI_UART_OPEN                           (0x53434955U)
42 
43 #define SCI_UART_SCMR_DEFAULT_VALUE             (0xF2U)
44 #define SCI_UART_BRR_DEFAULT_VALUE              (0xFFU)
45 #define SCI_UART_MDDR_DEFAULT_VALUE             (0xFFU)
46 #define SCI_UART_FCR_DEFAULT_VALUE              (0xF800)
47 #define SCI_UART_DCCR_DEFAULT_VALUE             (0x40U)
48 
49 #define SCI_UART_FIFO_DAT_MASK                  (0x1FFU)
50 
51 #define FRDR_TDAT_MASK_9BITS                    (0x01FFU)
52 #define SPTR_SPB2D_BIT                          (1U)
53 #define SPTR_OUTPUT_ENABLE_MASK                 (0x04U)
54 
55 #define SCI_UART_SSR_FIFO_DR_RDF                (0x41)
56 
57 #define SCI_UART_SPMR_CTSE_OFFSET               (1U)
58 
59 /* SCI SCR register bit masks */
60 #define SCI_SCR_TEIE_MASK                       (0x04U) ///< Transmit End Interrupt Enable
61 #define SCI_SCR_RE_MASK                         (0x10U) ///< Receive Enable
62 #define SCI_SCR_TE_MASK                         (0x20U) ///< Transmit Enable
63 #define SCI_SCR_RIE_MASK                        (0x40U) ///< Receive Interrupt Enable
64 #define SCI_SCR_TIE_MASK                        (0x80U) ///< Transmit Interrupt Enable
65 
66 /* SCI SEMR register bit offsets */
67 #define SCI_UART_SEMR_BRME_OFFSET               (2U)
68 #define SCI_UART_SEMR_ABCSE_OFFSET              (3U)
69 #define SCI_UART_SEMR_ABCS_OFFSET               (4U)
70 #define SCI_UART_SEMR_BGDM_OFFSET               (6U)
71 #define SCI_UART_SEMR_BAUD_SETTING_MASK         ((1U << SCI_UART_SEMR_BRME_OFFSET) |  \
72                                                  (1U << SCI_UART_SEMR_ABCSE_OFFSET) | \
73                                                  (1U << SCI_UART_SEMR_ABCS_OFFSET) | (1U << SCI_UART_SEMR_BGDM_OFFSET))
74 
75 /* SCI SMR register bit masks */
76 #define SCI_SMR_CKS_VALUE_MASK                  (0x03U) ///< CKS: 2 bits
77 
78 /* SCI SSR register receiver error bit masks */
79 #define SCI_SSR_ORER_MASK                       (0x20U) ///< overflow error
80 #define SCI_SSR_FER_MASK                        (0x10U) ///< framing error
81 #define SCI_SSR_PER_MASK                        (0x08U) ///< parity err
82 #define SCI_SSR_FIFO_RESERVED_MASK              (0x02U) ///< Reserved bit mask for SSR_FIFO register
83 #define SCI_RCVR_ERR_MASK                       (SCI_SSR_ORER_MASK | SCI_SSR_FER_MASK | SCI_SSR_PER_MASK)
84 
85 #define SCI_REG_SIZE                            (R_SCI1_BASE - R_SCI0_BASE)
86 
87 #define SCI_UART_INVALID_8BIT_PARAM             (0xFFU)
88 #define SCI_UART_INVALID_16BIT_PARAM            (0xFFFFU)
89 
90 #define SCI_UART_DTC_MAX_TRANSFER               (0x10000U)
91 
92 #define SCI_UART_FCR_TRIGGER_MASK               (0xF)
93 #define SCI_UART_FCR_RSTRG_OFFSET               (12)
94 #define SCI_UART_FCR_RTRG_OFFSET                (8)
95 #define SCI_UART_FCR_TTRG_OFFSET                (4)
96 #define SCI_UART_FCR_RESET_TX_RX                (0x6)
97 
98 #define SCI_UART_9BIT_TRANSFER_BUFFER_OFFSET    (0xB)
99 #define SCI_UART_FIFO_TRANSFER_BUFFER_OFFSET    (0xC)
100 
101 #define SCI_UART_DTC_RX_TRANSFER_SETTINGS       ((TRANSFER_MODE_NORMAL << TRANSFER_SETTINGS_MODE_BITS) |         \
102                                                  (TRANSFER_SIZE_1_BYTE << TRANSFER_SETTINGS_SIZE_BITS) |         \
103                                                  (TRANSFER_ADDR_MODE_FIXED << TRANSFER_SETTINGS_SRC_ADDR_BITS) | \
104                                                  (TRANSFER_IRQ_END << TRANSFER_SETTINGS_IRQ_BITS) |              \
105                                                  (TRANSFER_ADDR_MODE_INCREMENTED << TRANSFER_SETTINGS_DEST_ADDR_BITS))
106 #define SCI_UART_DTC_TX_TRANSFER_SETTINGS       ((TRANSFER_MODE_NORMAL << TRANSFER_SETTINGS_MODE_BITS) |               \
107                                                  (TRANSFER_SIZE_1_BYTE << TRANSFER_SETTINGS_SIZE_BITS) |               \
108                                                  (TRANSFER_ADDR_MODE_INCREMENTED << TRANSFER_SETTINGS_SRC_ADDR_BITS) | \
109                                                  (TRANSFER_IRQ_END << TRANSFER_SETTINGS_IRQ_BITS) |                    \
110                                                  (TRANSFER_ADDR_MODE_FIXED << TRANSFER_SETTINGS_DEST_ADDR_BITS))
111 #ifndef SCI_UART_FLOW_CONTROL_ACTIVE
112  #define SCI_UART_FLOW_CONTROL_ACTIVE           BSP_IO_LEVEL_HIGH
113 #endif
114 
115 #ifndef SCI_UART_FLOW_CONTROL_INACTIVE
116  #define SCI_UART_FLOW_CONTROL_INACTIVE         BSP_IO_LEVEL_LOW
117 #endif
118 
119 /***********************************************************************************************************************
120  * Private constants
121  **********************************************************************************************************************/
122 static const int32_t SCI_UART_100_PERCENT_X_1000 = 100000;
123 static const int32_t SCI_UART_MDDR_DIVISOR       = 256;
124 
125 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
126 static const uint32_t SCI_UART_MAX_BAUD_RATE_ERROR_X_1000 = 15000;
127 #endif
128 
129 /***********************************************************************************************************************
130  * Typedef definitions
131  **********************************************************************************************************************/
132 typedef struct st_baud_setting_const_t
133 {
134     uint8_t bgdm  : 1;                 /**< BGDM value to get divisor */
135     uint8_t abcs  : 1;                 /**< ABCS value to get divisor */
136     uint8_t abcse : 1;                 /**< ABCSE value to get divisor */
137     uint8_t cks   : 2;                 /**< CKS  value to get divisor (CKS = N) */
138 } baud_setting_const_t;
139 
140 /* Noise filter setting definition */
141 typedef enum e_noise_cancel_lvl
142 {
143     NOISE_CANCEL_LVL1,                 /**< Noise filter level 1(weak) */
144     NOISE_CANCEL_LVL2,                 /**< Noise filter level 2 */
145     NOISE_CANCEL_LVL3,                 /**< Noise filter level 3 */
146     NOISE_CANCEL_LVL4                  /**< Noise filter level 4(strong) */
147 } noise_cancel_lvl_t;
148 
149 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
150 typedef void (BSP_CMSE_NONSECURE_CALL * sci_uart_prv_ns_callback)(uart_callback_args_t * p_args);
151 #elif defined(__GNUC__)
152 typedef BSP_CMSE_NONSECURE_CALL void (*volatile sci_uart_prv_ns_callback)(uart_callback_args_t * p_args);
153 #endif
154 
155 /***********************************************************************************************************************
156  * Private function prototypes
157  **********************************************************************************************************************/
158 
159 static void r_sci_negate_de_pin(sci_uart_instance_ctrl_t const * const p_ctrl);
160 
161 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
162 
163 static fsp_err_t r_sci_read_write_param_check(sci_uart_instance_ctrl_t const * const p_ctrl,
164                                               uint8_t const * const                  addr,
165                                               uint32_t const                         bytes);
166 
167 #endif
168 
169 static void r_sci_uart_config_set(sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg);
170 
171 #if SCI_UART_CFG_DTC_SUPPORTED
172 static fsp_err_t r_sci_uart_transfer_configure(sci_uart_instance_ctrl_t * const p_ctrl,
173                                                transfer_instance_t const      * p_transfer,
174                                                uint32_t                       * p_transfer_reg,
175                                                uint32_t                         address);
176 
177 static fsp_err_t r_sci_uart_transfer_open(sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg);
178 
179 static void r_sci_uart_transfer_close(sci_uart_instance_ctrl_t * p_ctrl);
180 
181 #endif
182 
183 static void r_sci_uart_baud_set(R_SCI0_Type * p_sci_reg, baud_setting_t const * const p_baud_setting);
184 static void r_sci_uart_call_callback(sci_uart_instance_ctrl_t * p_ctrl, uint32_t data, uart_event_t event);
185 
186 #if SCI_UART_CFG_FIFO_SUPPORT
187 static void r_sci_uart_fifo_cfg(sci_uart_instance_ctrl_t * const p_ctrl);
188 
189 #endif
190 
191 static void r_sci_irq_cfg(sci_uart_instance_ctrl_t * const p_ctrl, uint8_t const ipl, IRQn_Type const p_irq);
192 
193 static void r_sci_irqs_cfg(sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg);
194 
195 #if (SCI_UART_CFG_TX_ENABLE)
196 void r_sci_uart_write_no_transfer(sci_uart_instance_ctrl_t * const p_ctrl);
197 
198 #endif
199 
200 #if (SCI_UART_CFG_RX_ENABLE)
201 void r_sci_uart_rxi_read_no_transfer(sci_uart_instance_ctrl_t * const p_ctrl);
202 
203 void sci_uart_rxi_isr(void);
204 
205 void r_sci_uart_read_data(sci_uart_instance_ctrl_t * const p_ctrl, uint32_t * const p_data);
206 
207 void sci_uart_eri_isr(void);
208 
209 #endif
210 
211 #if (SCI_UART_CFG_TX_ENABLE)
212 void sci_uart_txi_isr(void);
213 void sci_uart_tei_isr(void);
214 
215 #endif
216 
217 /***********************************************************************************************************************
218  * Private global variables
219  **********************************************************************************************************************/
220 
221 /* Name of module used by error logger macro */
222 #if BSP_CFG_ERROR_LOG != 0
223 static const char g_module_name[] = "sci_uart";
224 #endif
225 
226 /* Baud rate divisor information (UART mode) */
227 static const baud_setting_const_t g_async_baud[SCI_UART_NUM_DIVISORS_ASYNC] =
228 {
229     {0U, 0U, 1U, 0U},                  /* BGDM, ABCS, ABCSE, n */
230     {1U, 1U, 0U, 0U},
231     {1U, 0U, 0U, 0U},
232     {0U, 0U, 1U, 1U},
233     {0U, 0U, 0U, 0U},
234     {1U, 0U, 0U, 1U},
235     {0U, 0U, 1U, 2U},
236     {0U, 0U, 0U, 1U},
237     {1U, 0U, 0U, 2U},
238     {0U, 0U, 1U, 3U},
239     {0U, 0U, 0U, 2U},
240     {1U, 0U, 0U, 3U},
241     {0U, 0U, 0U, 3U}
242 };
243 
244 static const uint16_t g_div_coefficient[SCI_UART_NUM_DIVISORS_ASYNC] =
245 {
246     6U,
247     8U,
248     16U,
249     24U,
250     32U,
251     64U,
252     96U,
253     128U,
254     256U,
255     384U,
256     512U,
257     1024U,
258     2048U,
259 };
260 
261 /* UART on SCI HAL API mapping for UART interface */
262 const uart_api_t g_uart_on_sci =
263 {
264     .open               = R_SCI_UART_Open,
265     .close              = R_SCI_UART_Close,
266     .write              = R_SCI_UART_Write,
267     .read               = R_SCI_UART_Read,
268     .infoGet            = R_SCI_UART_InfoGet,
269     .baudSet            = R_SCI_UART_BaudSet,
270     .communicationAbort = R_SCI_UART_Abort,
271     .callbackSet        = R_SCI_UART_CallbackSet,
272     .readStop           = R_SCI_UART_ReadStop,
273 };
274 
275 /*******************************************************************************************************************//**
276  * @addtogroup SCI_UART
277  * @{
278  **********************************************************************************************************************/
279 
280 /***********************************************************************************************************************
281  * Functions
282  **********************************************************************************************************************/
283 
284 /*******************************************************************************************************************//**
285  * Configures the UART driver based on the input configurations.  If reception is enabled at compile time, reception is
286  * enabled at the end of this function. Implements @ref uart_api_t::open
287  *
288  * @retval  FSP_SUCCESS                    Channel opened successfully.
289  * @retval  FSP_ERR_ASSERTION              Pointer to UART control block or configuration structure is NULL.
290  * @retval  FSP_ERR_IP_CHANNEL_NOT_PRESENT The requested channel does not exist on this MCU.
291  * @retval  FSP_ERR_INVALID_ARGUMENT       Flow control is enabled but flow control pin is not defined or selected channel
292  *                                         does not support "Hardware CTS and Hardware RTS" flow control.
293  * @retval  FSP_ERR_ALREADY_OPEN           Control block has already been opened or channel is being used by another
294  *                                         instance. Call close() then open() to reconfigure.
295  *
296  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
297  *                               return codes. This function calls:
298  *                                   * @ref transfer_api_t::open
299  **********************************************************************************************************************/
R_SCI_UART_Open(uart_ctrl_t * const p_api_ctrl,uart_cfg_t const * const p_cfg)300 fsp_err_t R_SCI_UART_Open (uart_ctrl_t * const p_api_ctrl, uart_cfg_t const * const p_cfg)
301 {
302     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
303 
304 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
305 
306     /* Check parameters. */
307     FSP_ASSERT(p_ctrl);
308     FSP_ASSERT(p_cfg);
309 
310     FSP_ASSERT(p_cfg->p_extend);
311     FSP_ASSERT(((sci_uart_extended_cfg_t *) p_cfg->p_extend)->p_baud_setting);
312     FSP_ERROR_RETURN(SCI_UART_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN);
313 
314     /* Make sure this channel exists. */
315     FSP_ERROR_RETURN(BSP_FEATURE_SCI_CHANNELS & (1U << p_cfg->channel), FSP_ERR_IP_CHANNEL_NOT_PRESENT);
316 
317     if (((sci_uart_extended_cfg_t *) p_cfg->p_extend)->flow_control == SCI_UART_FLOW_CONTROL_CTSRTS)
318     {
319         FSP_ERROR_RETURN(
320             ((sci_uart_extended_cfg_t *) p_cfg->p_extend)->flow_control_pin != SCI_UART_INVALID_16BIT_PARAM,
321             FSP_ERR_INVALID_ARGUMENT);
322     }
323 
324     if (((sci_uart_extended_cfg_t *) p_cfg->p_extend)->flow_control == SCI_UART_FLOW_CONTROL_HARDWARE_CTSRTS)
325     {
326         FSP_ERROR_RETURN((0U != (((1U << (p_cfg->channel)) & BSP_FEATURE_SCI_UART_CSTPEN_CHANNELS))),
327                          FSP_ERR_INVALID_ARGUMENT);
328     }
329 
330  #if (SCI_UART_CFG_RS485_SUPPORT)
331     if (((sci_uart_extended_cfg_t *) p_cfg->p_extend)->rs485_setting.enable == SCI_UART_RS485_ENABLE)
332     {
333         FSP_ERROR_RETURN(
334             ((sci_uart_extended_cfg_t *) p_cfg->p_extend)->rs485_setting.de_control_pin != SCI_UART_INVALID_16BIT_PARAM,
335             FSP_ERR_INVALID_ARGUMENT);
336     }
337  #endif
338 
339     FSP_ASSERT(p_cfg->rxi_irq >= 0);
340     FSP_ASSERT(p_cfg->txi_irq >= 0);
341     FSP_ASSERT(p_cfg->tei_irq >= 0);
342     FSP_ASSERT(p_cfg->eri_irq >= 0);
343 #endif
344 
345     p_ctrl->p_reg = ((R_SCI0_Type *) (R_SCI0_BASE + (SCI_REG_SIZE * p_cfg->channel)));
346 
347     p_ctrl->fifo_depth = 0U;
348 #if SCI_UART_CFG_FIFO_SUPPORT
349 
350     /* Check if the channel supports fifo */
351     if (BSP_FEATURE_SCI_UART_FIFO_CHANNELS & (1U << p_cfg->channel))
352     {
353         p_ctrl->fifo_depth = BSP_FEATURE_SCI_UART_FIFO_DEPTH;
354     }
355 #endif
356 
357     p_ctrl->p_cfg = p_cfg;
358 
359     p_ctrl->p_callback        = p_cfg->p_callback;
360     p_ctrl->p_context         = p_cfg->p_context;
361     p_ctrl->p_callback_memory = NULL;
362 
363     p_ctrl->data_bytes = 1U;
364     if (UART_DATA_BITS_9 == p_cfg->data_bits)
365     {
366         p_ctrl->data_bytes = 2U;
367     }
368 
369     /* Configure the interrupts. */
370     r_sci_irqs_cfg(p_ctrl, p_cfg);
371 
372 #if SCI_UART_CFG_DTC_SUPPORTED
373 
374     /* Configure the transfer interface for transmission and reception if provided. */
375     fsp_err_t err = r_sci_uart_transfer_open(p_ctrl, p_cfg);
376 
377     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
378 #endif
379 
380     /* Negate driver enable if RS-485 mode is enabled. */
381     r_sci_negate_de_pin(p_ctrl);
382 
383     /* Enable the SCI channel */
384     R_BSP_MODULE_START(FSP_IP_SCI, p_cfg->channel);
385 
386     /* Initialize registers as defined in section 34.3.7 "SCI Initialization in Asynchronous Mode" in the RA6M3 manual
387      * R01UH0886EJ0100 or the relevant section for the MCU being used. */
388     p_ctrl->p_reg->SCR   = 0U;
389     p_ctrl->p_reg->SSR   = 0U;
390     p_ctrl->p_reg->SIMR1 = 0U;
391     p_ctrl->p_reg->SIMR2 = 0U;
392     p_ctrl->p_reg->SIMR3 = 0U;
393     p_ctrl->p_reg->CDR   = 0U;
394 
395     /* Check if the channel supports address matching */
396     if (BSP_FEATURE_SCI_ADDRESS_MATCH_CHANNELS & (1U << p_cfg->channel))
397     {
398         p_ctrl->p_reg->DCCR = SCI_UART_DCCR_DEFAULT_VALUE;
399     }
400 
401     /* Set the default level of the TX pin to 1. */
402     p_ctrl->p_reg->SPTR = (uint8_t) (1U << SPTR_SPB2D_BIT) | SPTR_OUTPUT_ENABLE_MASK;
403 
404     /* Set the UART configuration settings provided in ::uart_cfg_t and ::sci_uart_extended_cfg_t. */
405     r_sci_uart_config_set(p_ctrl, p_cfg);
406 
407     p_ctrl->p_tx_src      = NULL;
408     p_ctrl->tx_src_bytes  = 0U;
409     p_ctrl->p_rx_dest     = NULL;
410     p_ctrl->rx_dest_bytes = 0;
411 
412     sci_uart_extended_cfg_t * p_extend = (sci_uart_extended_cfg_t *) p_cfg->p_extend;
413 
414     uint32_t scr = ((uint8_t) p_extend->clock) & 0x3U;
415 #if (SCI_UART_CFG_RX_ENABLE)
416 
417     /* If reception is enabled at build time, enable reception. */
418     /* NOTE: Transmitter and its interrupt are enabled in R_SCI_UART_Write(). */
419     scr |= SCI_SCR_RE_MASK;
420     R_BSP_IrqEnable(p_ctrl->p_cfg->rxi_irq);
421     R_BSP_IrqEnable(p_ctrl->p_cfg->eri_irq);
422 
423     scr |= SCI_SCR_RIE_MASK;
424 #endif
425 
426 #if (SCI_UART_CFG_TX_ENABLE)
427     R_BSP_IrqEnable(p_ctrl->p_cfg->txi_irq);
428     R_BSP_IrqEnable(p_ctrl->p_cfg->tei_irq);
429     scr |= SCI_SCR_TE_MASK;
430 #endif
431     p_ctrl->p_reg->SCR = (uint8_t) scr;
432 
433     p_ctrl->flow_pin = p_extend->flow_control_pin;
434 
435 #if SCI_UART_CFG_FLOW_CONTROL_SUPPORT
436     if (p_ctrl->flow_pin != SCI_UART_INVALID_16BIT_PARAM)
437     {
438         R_BSP_PinAccessEnable();
439         R_BSP_PinWrite(p_ctrl->flow_pin, SCI_UART_FLOW_CONTROL_INACTIVE);
440         R_BSP_PinAccessDisable();
441     }
442 #endif
443 
444     p_ctrl->open = SCI_UART_OPEN;
445 
446     return FSP_SUCCESS;
447 }
448 
449 /*******************************************************************************************************************//**
450  * Aborts any in progress transfers. Disables interrupts, receiver, and transmitter.  Closes lower level transfer
451  * drivers if used. Removes power. Implements @ref uart_api_t::close
452  *
453  * @retval  FSP_SUCCESS              Channel successfully closed.
454  * @retval  FSP_ERR_ASSERTION        Pointer to UART control block is NULL.
455  * @retval  FSP_ERR_NOT_OPEN         The control block has not been opened
456  **********************************************************************************************************************/
R_SCI_UART_Close(uart_ctrl_t * const p_api_ctrl)457 fsp_err_t R_SCI_UART_Close (uart_ctrl_t * const p_api_ctrl)
458 {
459     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
460 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
461     FSP_ASSERT(p_ctrl);
462     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
463 #endif
464 
465     /* Mark the channel not open so other APIs cannot use it. */
466     p_ctrl->open = 0U;
467 
468     /* Disable interrupts, receiver, and transmitter. Disable baud clock output.*/
469     p_ctrl->p_reg->SCR = 0U;
470 
471 #if (SCI_UART_CFG_RX_ENABLE)
472 
473     /* If reception is enabled at build time, disable reception irqs. */
474     R_BSP_IrqDisable(p_ctrl->p_cfg->rxi_irq);
475     R_BSP_IrqDisable(p_ctrl->p_cfg->eri_irq);
476 #endif
477 #if (SCI_UART_CFG_TX_ENABLE)
478 
479     /* If transmission is enabled at build time, disable transmission irqs. */
480     R_BSP_IrqDisable(p_ctrl->p_cfg->txi_irq);
481     R_BSP_IrqDisable(p_ctrl->p_cfg->tei_irq);
482 #endif
483 
484 #if SCI_UART_CFG_DTC_SUPPORTED
485 
486     /* Close the lower level transfer instances. */
487     r_sci_uart_transfer_close(p_ctrl);
488 #endif
489 
490     /* Remove power to the channel. */
491     R_BSP_MODULE_STOP(FSP_IP_SCI, p_ctrl->p_cfg->channel);
492 
493     /* Negate driver enable if RS-485 mode is enabled. */
494     r_sci_negate_de_pin(p_ctrl);
495 
496     return FSP_SUCCESS;
497 }
498 
499 /*******************************************************************************************************************//**
500  * Receives user specified number of bytes into destination buffer pointer. Implements @ref uart_api_t::read
501  *
502  * @retval  FSP_SUCCESS                  Data reception successfully ends.
503  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL.
504  *                                       Number of transfers outside the max or min boundary when transfer instance used
505  * @retval  FSP_ERR_INVALID_ARGUMENT     Destination address or data size is not valid for 9-bit mode.
506  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened
507  * @retval  FSP_ERR_IN_USE               A previous read operation is still in progress.
508  * @retval  FSP_ERR_UNSUPPORTED          SCI_UART_CFG_RX_ENABLE is set to 0
509  *
510  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
511  *                               return codes. This function calls:
512  *                                   * @ref transfer_api_t::reset
513  *
514  * @note If 9-bit data length is specified at R_SCI_UART_Open call, p_dest must be aligned 16-bit boundary.
515  **********************************************************************************************************************/
R_SCI_UART_Read(uart_ctrl_t * const p_api_ctrl,uint8_t * const p_dest,uint32_t const bytes)516 fsp_err_t R_SCI_UART_Read (uart_ctrl_t * const p_api_ctrl, uint8_t * const p_dest, uint32_t const bytes)
517 {
518 #if (SCI_UART_CFG_RX_ENABLE)
519     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
520     fsp_err_t err = FSP_SUCCESS;
521 
522  #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
523     err = r_sci_read_write_param_check(p_ctrl, p_dest, bytes);
524     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
525     FSP_ERROR_RETURN(0U == p_ctrl->rx_dest_bytes, FSP_ERR_IN_USE);
526  #endif
527 
528  #if SCI_UART_CFG_DTC_SUPPORTED
529 
530     /* Configure transfer instance to receive the requested number of bytes if transfer is used for reception. */
531     if (NULL != p_ctrl->p_cfg->p_transfer_rx)
532     {
533         uint32_t size = bytes >> (p_ctrl->data_bytes - 1);
534   #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
535 
536         /* Check that the number of transfers is within the 16-bit limit. */
537         FSP_ASSERT(size <= SCI_UART_DTC_MAX_TRANSFER);
538   #endif
539         err =
540             p_ctrl->p_cfg->p_transfer_rx->p_api->reset(p_ctrl->p_cfg->p_transfer_rx->p_ctrl, NULL, (void *) p_dest,
541                                                        (uint16_t) size);
542         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
543     }
544  #endif
545 
546     /* Save the destination address and size for use in rxi_isr. */
547     p_ctrl->p_rx_dest     = p_dest;
548     p_ctrl->rx_dest_bytes = bytes;
549 
550     return err;
551 #else
552     FSP_PARAMETER_NOT_USED(p_api_ctrl);
553     FSP_PARAMETER_NOT_USED(p_dest);
554     FSP_PARAMETER_NOT_USED(bytes);
555 
556     return FSP_ERR_UNSUPPORTED;
557 #endif
558 }
559 
560 /*******************************************************************************************************************//**
561  * Transmits user specified number of bytes from the source buffer pointer. Implements @ref uart_api_t::write
562  *
563  * @retval  FSP_SUCCESS                  Data transmission finished successfully.
564  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL.
565  *                                       Number of transfers outside the max or min boundary when transfer instance used
566  * @retval  FSP_ERR_INVALID_ARGUMENT     Source address or data size is not valid for 9-bit mode.
567  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened
568  * @retval  FSP_ERR_IN_USE               A UART transmission is in progress
569  * @retval  FSP_ERR_UNSUPPORTED          SCI_UART_CFG_TX_ENABLE is set to 0
570  *
571  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
572  *                               return codes. This function calls:
573  *                                   * @ref transfer_api_t::reset
574  *
575  * @note If 9-bit data length is specified at R_SCI_UART_Open call, p_src must be aligned on a 16-bit boundary.
576  **********************************************************************************************************************/
R_SCI_UART_Write(uart_ctrl_t * const p_api_ctrl,uint8_t const * const p_src,uint32_t const bytes)577 fsp_err_t R_SCI_UART_Write (uart_ctrl_t * const p_api_ctrl, uint8_t const * const p_src, uint32_t const bytes)
578 {
579 #if (SCI_UART_CFG_TX_ENABLE)
580     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
581  #if SCI_UART_CFG_PARAM_CHECKING_ENABLE || SCI_UART_CFG_DTC_SUPPORTED
582     fsp_err_t err = FSP_SUCCESS;
583  #endif
584 
585  #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
586     err = r_sci_read_write_param_check(p_ctrl, p_src, bytes);
587     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
588     FSP_ERROR_RETURN(0U == p_ctrl->tx_src_bytes, FSP_ERR_IN_USE);
589  #endif
590 
591  #if (SCI_UART_CFG_RS485_SUPPORT)
592     sci_uart_extended_cfg_t * p_extend = (sci_uart_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
593 
594     /* If RS-485 is enabled, then assert the driver enable pin at the start of a write transfer. */
595     if (p_extend->rs485_setting.enable)
596     {
597         R_BSP_PinAccessEnable();
598 
599         bsp_io_level_t level = SCI_UART_RS485_DE_POLARITY_HIGH ==
600                                p_extend->rs485_setting.polarity ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
601         R_BSP_PinWrite(p_extend->rs485_setting.de_control_pin, level);
602 
603         R_BSP_PinAccessDisable();
604     }
605  #endif
606 
607     /* Transmit interrupts must be disabled to start with. */
608     p_ctrl->p_reg->SCR &= (uint8_t) ~(SCI_SCR_TIE_MASK | SCI_SCR_TEIE_MASK);
609 
610     /* If the fifo is not used the first write will be done from this function. Subsequent writes will be done
611      * from txi_isr. */
612  #if SCI_UART_CFG_FIFO_SUPPORT
613     if (p_ctrl->fifo_depth > 0U)
614     {
615         p_ctrl->tx_src_bytes = bytes;
616         p_ctrl->p_tx_src     = p_src;
617     }
618     else
619  #endif
620     {
621         p_ctrl->tx_src_bytes = bytes - p_ctrl->data_bytes;
622         p_ctrl->p_tx_src     = p_src + p_ctrl->data_bytes;
623     }
624 
625  #if SCI_UART_CFG_DTC_SUPPORTED
626 
627     /* If a transfer instance is used for transmission, reset the transfer instance to transmit the requested
628      * data. */
629     if ((NULL != p_ctrl->p_cfg->p_transfer_tx) && p_ctrl->tx_src_bytes)
630     {
631         uint32_t data_bytes    = p_ctrl->data_bytes;
632         uint32_t num_transfers = p_ctrl->tx_src_bytes >> (data_bytes - 1);
633         p_ctrl->tx_src_bytes = 0U;
634   #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
635 
636         /* Check that the number of transfers is within the 16-bit limit. */
637         FSP_ASSERT(num_transfers <= SCI_UART_DTC_MAX_TRANSFER);
638   #endif
639 
640         err = p_ctrl->p_cfg->p_transfer_tx->p_api->reset(p_ctrl->p_cfg->p_transfer_tx->p_ctrl,
641                                                          (void const *) p_ctrl->p_tx_src,
642                                                          NULL,
643                                                          (uint16_t) num_transfers);
644         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
645     }
646  #endif
647 
648     /* Trigger a TXI interrupt. This triggers the transfer instance or a TXI interrupt if the transfer instance is
649      * not used. */
650     p_ctrl->p_reg->SCR |= SCI_SCR_TIE_MASK;
651  #if SCI_UART_CFG_FIFO_SUPPORT
652     if (p_ctrl->fifo_depth == 0U)
653  #endif
654     {
655         /* On channels with no FIFO, the first byte is sent from this function to trigger the first TXI event.  This
656          * method is used instead of setting TE and TIE at the same time as recommended in the hardware manual to avoid
657          * the one frame delay that occurs when the TE bit is set. */
658         if (2U == p_ctrl->data_bytes)
659         {
660             p_ctrl->p_reg->FTDRHL = *((uint16_t *) (p_src)) | (uint16_t) ~(SCI_UART_FIFO_DAT_MASK);
661         }
662         else
663         {
664             p_ctrl->p_reg->TDR = *(p_src);
665         }
666     }
667 
668     return FSP_SUCCESS;
669 #else
670     FSP_PARAMETER_NOT_USED(p_api_ctrl);
671     FSP_PARAMETER_NOT_USED(p_src);
672     FSP_PARAMETER_NOT_USED(bytes);
673 
674     return FSP_ERR_UNSUPPORTED;
675 #endif
676 }
677 
678 /*******************************************************************************************************************//**
679  * Updates the user callback and has option of providing memory for callback structure.
680  * Implements uart_api_t::callbackSet
681  *
682  * @retval  FSP_SUCCESS                  Callback updated successfully.
683  * @retval  FSP_ERR_ASSERTION            A required pointer is NULL.
684  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
685  * @retval  FSP_ERR_NO_CALLBACK_MEMORY   p_callback is non-secure and p_callback_memory is either secure or NULL.
686  **********************************************************************************************************************/
R_SCI_UART_CallbackSet(uart_ctrl_t * const p_api_ctrl,void (* p_callback)(uart_callback_args_t *),void const * const p_context,uart_callback_args_t * const p_callback_memory)687 fsp_err_t R_SCI_UART_CallbackSet (uart_ctrl_t * const          p_api_ctrl,
688                                   void (                     * p_callback)(uart_callback_args_t *),
689                                   void const * const           p_context,
690                                   uart_callback_args_t * const p_callback_memory)
691 {
692     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
693 
694 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
695     FSP_ASSERT(p_ctrl);
696     FSP_ASSERT(p_callback);
697     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
698 #endif
699 
700 #if BSP_TZ_SECURE_BUILD
701 
702     /* Get security state of p_callback */
703     bool callback_is_secure =
704         (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
705 
706  #if SCI_UART_CFG_PARAM_CHECKING_ENABLE
707 
708     /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
709     uart_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
710                                                                                        CMSE_AU_NONSECURE);
711     FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
712  #endif
713 #endif
714 
715     /* Store callback and context */
716 #if BSP_TZ_SECURE_BUILD
717     p_ctrl->p_callback = callback_is_secure ? p_callback :
718                          (void (*)(uart_callback_args_t *))cmse_nsfptr_create(p_callback);
719 #else
720     p_ctrl->p_callback = p_callback;
721 #endif
722     p_ctrl->p_context         = p_context;
723     p_ctrl->p_callback_memory = p_callback_memory;
724 
725     return FSP_SUCCESS;
726 }
727 
728 /*******************************************************************************************************************//**
729  * Updates the baud rate using the clock selected in Open. p_baud_setting is a pointer to a baud_setting_t structure.
730  * Implements @ref uart_api_t::baudSet
731  *
732  * @warning This terminates any in-progress transmission.
733  *
734  * @retval  FSP_SUCCESS                  Baud rate was successfully changed.
735  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL or the UART is not configured to use the
736  *                                       internal clock.
737  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened
738  **********************************************************************************************************************/
R_SCI_UART_BaudSet(uart_ctrl_t * const p_api_ctrl,void const * const p_baud_setting)739 fsp_err_t R_SCI_UART_BaudSet (uart_ctrl_t * const p_api_ctrl, void const * const p_baud_setting)
740 {
741     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
742 
743 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
744     FSP_ASSERT(p_ctrl);
745     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
746 
747     /* Verify that the On-Chip baud rate generator is currently selected. */
748     FSP_ASSERT((p_ctrl->p_reg->SCR_b.CKE & 0x2) == 0U);
749 #endif
750 
751     /* Save SCR configurations except transmit interrupts. Resuming transmission after reconfiguring baud settings is
752      * not supported. */
753     uint8_t preserved_scr = p_ctrl->p_reg->SCR & (uint8_t) ~(SCI_SCR_TIE_MASK | SCI_SCR_TEIE_MASK);
754 
755     /* Disables transmitter and receiver. This terminates any in-progress transmission. */
756     p_ctrl->p_reg->SCR = preserved_scr & (uint8_t) ~(SCI_SCR_TE_MASK | SCI_SCR_RE_MASK | SCI_SCR_RIE_MASK);
757     p_ctrl->p_tx_src   = NULL;
758 
759     /* Apply new baud rate register settings. */
760     r_sci_uart_baud_set(p_ctrl->p_reg, p_baud_setting);
761 
762     /* Restore all settings except transmit interrupts. */
763     p_ctrl->p_reg->SCR = preserved_scr;
764 
765     return FSP_SUCCESS;
766 }
767 
768 /*******************************************************************************************************************//**
769  * Provides the driver information, including the maximum number of bytes that can be received or transmitted at a time.
770  * Implements @ref uart_api_t::infoGet
771  *
772  * @retval  FSP_SUCCESS                  Information stored in provided p_info.
773  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL.
774  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened
775  **********************************************************************************************************************/
R_SCI_UART_InfoGet(uart_ctrl_t * const p_api_ctrl,uart_info_t * const p_info)776 fsp_err_t R_SCI_UART_InfoGet (uart_ctrl_t * const p_api_ctrl, uart_info_t * const p_info)
777 {
778 #if SCI_UART_CFG_PARAM_CHECKING_ENABLE || SCI_UART_CFG_DTC_SUPPORTED
779     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
780 #else
781     FSP_PARAMETER_NOT_USED(p_api_ctrl);
782 #endif
783 
784 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
785     FSP_ASSERT(p_ctrl);
786     FSP_ASSERT(p_info);
787     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
788 #endif
789 
790     p_info->read_bytes_max  = SCI_UART_MAX_READ_WRITE_NO_DTC;
791     p_info->write_bytes_max = SCI_UART_MAX_READ_WRITE_NO_DTC;
792 
793 #if (SCI_UART_CFG_RX_ENABLE)
794 
795     /* Store number of bytes that can be read at a time. */
796  #if SCI_UART_CFG_DTC_SUPPORTED
797     if (NULL != p_ctrl->p_cfg->p_transfer_rx)
798     {
799         p_info->read_bytes_max = SCI_UART_DTC_MAX_TRANSFER;
800     }
801  #endif
802 #endif
803 
804 #if (SCI_UART_CFG_TX_ENABLE)
805 
806     /* Store number of bytes that can be written at a time. */
807  #if SCI_UART_CFG_DTC_SUPPORTED
808     if (NULL != p_ctrl->p_cfg->p_transfer_tx)
809     {
810         p_info->write_bytes_max = SCI_UART_DTC_MAX_TRANSFER;
811     }
812  #endif
813 #endif
814 
815     return FSP_SUCCESS;
816 }
817 
818 /*******************************************************************************************************************//**
819  * Provides API to abort ongoing transfer. Transmission is aborted after the current character is transmitted.
820  * Reception is still enabled after abort(). Any characters received after abort() and before the transfer
821  * is reset in the next call to read(), will arrive via the callback function with event UART_EVENT_RX_CHAR.
822  * Implements @ref uart_api_t::communicationAbort
823  *
824  * @retval  FSP_SUCCESS                  UART transaction aborted successfully.
825  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL.
826  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
827  * @retval  FSP_ERR_UNSUPPORTED          The requested Abort direction is unsupported.
828  *
829  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
830  *                               return codes. This function calls:
831  *                                   * @ref transfer_api_t::disable
832  **********************************************************************************************************************/
R_SCI_UART_Abort(uart_ctrl_t * const p_api_ctrl,uart_dir_t communication_to_abort)833 fsp_err_t R_SCI_UART_Abort (uart_ctrl_t * const p_api_ctrl, uart_dir_t communication_to_abort)
834 {
835     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
836     fsp_err_t err = FSP_ERR_UNSUPPORTED;
837 
838 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
839     FSP_ASSERT(p_ctrl);
840     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
841 #endif
842 
843 #if (SCI_UART_CFG_TX_ENABLE)
844     if (UART_DIR_TX & communication_to_abort)
845     {
846         err                 = FSP_SUCCESS;
847         p_ctrl->p_reg->SCR &= (uint8_t) ~(SCI_SCR_TIE_MASK | SCI_SCR_TEIE_MASK);
848  #if SCI_UART_CFG_DTC_SUPPORTED
849         if (NULL != p_ctrl->p_cfg->p_transfer_tx)
850         {
851             err = p_ctrl->p_cfg->p_transfer_tx->p_api->disable(p_ctrl->p_cfg->p_transfer_tx->p_ctrl);
852         }
853  #endif
854 
855  #if SCI_UART_CFG_FIFO_SUPPORT
856         if (0U != p_ctrl->fifo_depth)
857         {
858             /* Reset the transmit fifo */
859             p_ctrl->p_reg->FCR_b.TFRST = 1U;
860 
861             /* Wait until TFRST cleared after 1 PCLK according to section 34.2.26 "FIFO Control Register (FCR) in the
862              * RA6M3 manual R01UH0886EJ0100 or the relevant section for the MCU being used.*/
863             FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->FCR_b.TFRST, 0U);
864         }
865  #endif
866         p_ctrl->tx_src_bytes = 0U;
867 
868         /* Negate driver enable if RS-485 mode is enabled. */
869         r_sci_negate_de_pin(p_ctrl);
870 
871         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
872     }
873 #endif
874 #if (SCI_UART_CFG_RX_ENABLE)
875     if (UART_DIR_RX & communication_to_abort)
876     {
877         err = FSP_SUCCESS;
878 
879         p_ctrl->rx_dest_bytes = 0U;
880  #if SCI_UART_CFG_DTC_SUPPORTED
881         if (NULL != p_ctrl->p_cfg->p_transfer_rx)
882         {
883             err = p_ctrl->p_cfg->p_transfer_rx->p_api->disable(p_ctrl->p_cfg->p_transfer_rx->p_ctrl);
884         }
885  #endif
886  #if SCI_UART_CFG_FIFO_SUPPORT
887         if (0U != p_ctrl->fifo_depth)
888         {
889             /* Reset the receive fifo */
890             p_ctrl->p_reg->FCR_b.RFRST = 1U;
891 
892             /* Wait until RFRST cleared after 1 PCLK according to section 34.2.26 "FIFO Control Register (FCR) in the
893              * RA6M3 manual R01UH0886EJ0100 or the relevant section for the MCU being used.*/
894             FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->FCR_b.RFRST, 0U);
895         }
896  #endif
897     }
898 #endif
899 
900     return err;
901 }
902 
903 /*******************************************************************************************************************//**
904  * Provides API to abort ongoing read. Reception is still enabled after abort(). Any characters received after abort()
905  * and before the transfer is reset in the next call to read(), will arrive via the callback function with event
906  * UART_EVENT_RX_CHAR.
907  * Implements @ref uart_api_t::readStop
908  *
909  * @retval  FSP_SUCCESS                  UART transaction aborted successfully.
910  * @retval  FSP_ERR_ASSERTION            Pointer to UART control block is NULL.
911  * @retval  FSP_ERR_NOT_OPEN             The control block has not been opened.
912  * @retval  FSP_ERR_UNSUPPORTED          The requested Abort direction is unsupported.
913  *
914  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
915  *                               return codes. This function calls:
916  *                                   * @ref transfer_api_t::disable
917  **********************************************************************************************************************/
R_SCI_UART_ReadStop(uart_ctrl_t * const p_api_ctrl,uint32_t * remaining_bytes)918 fsp_err_t R_SCI_UART_ReadStop (uart_ctrl_t * const p_api_ctrl, uint32_t * remaining_bytes)
919 {
920     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
921 
922 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
923     FSP_ASSERT(p_ctrl);
924     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
925 #endif
926 
927 #if (SCI_UART_CFG_RX_ENABLE)
928     *remaining_bytes      = p_ctrl->rx_dest_bytes;
929     p_ctrl->rx_dest_bytes = 0U;
930  #if SCI_UART_CFG_DTC_SUPPORTED
931     if (NULL != p_ctrl->p_cfg->p_transfer_rx)
932     {
933         fsp_err_t err = p_ctrl->p_cfg->p_transfer_rx->p_api->disable(p_ctrl->p_cfg->p_transfer_rx->p_ctrl);
934         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
935 
936         transfer_properties_t transfer_info;
937         err = p_ctrl->p_cfg->p_transfer_rx->p_api->infoGet(p_ctrl->p_cfg->p_transfer_rx->p_ctrl, &transfer_info);
938         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
939         *remaining_bytes = transfer_info.transfer_length_remaining;
940     }
941  #endif
942 #else
943 
944     return FSP_ERR_UNSUPPORTED;
945 #endif
946 
947     return FSP_SUCCESS;
948 }
949 
950 /*******************************************************************************************************************//**
951  * Calculates baud rate register settings. Evaluates and determines the best possible settings set to the baud rate
952  * related registers.
953  *
954  * @param[in]  baudrate                  Baud rate [bps]. For example, 19200, 57600, 115200, etc.
955  * @param[in]  bitrate_modulation        Enable bitrate modulation
956  * @param[in]  baud_rate_error_x_1000    Max baud rate error. At most &lt;baud_rate_percent_error&gt; x 1000 required
957  *                                       for module to function. Absolute max baud_rate_error is 15000 (15%).
958  * @param[out] p_baud_setting            Baud setting information stored here if successful
959  *
960  * @retval     FSP_SUCCESS               Baud rate is set successfully
961  * @retval     FSP_ERR_ASSERTION         Null pointer
962  * @retval     FSP_ERR_INVALID_ARGUMENT  Baud rate is '0', error in calculated baud rate is larger than requested
963  *                                       max error, or requested max error in baud rate is larger than 15%.
964  **********************************************************************************************************************/
R_SCI_UART_BaudCalculate(uint32_t baudrate,bool bitrate_modulation,uint32_t baud_rate_error_x_1000,baud_setting_t * const p_baud_setting)965 fsp_err_t R_SCI_UART_BaudCalculate (uint32_t               baudrate,
966                                     bool                   bitrate_modulation,
967                                     uint32_t               baud_rate_error_x_1000,
968                                     baud_setting_t * const p_baud_setting)
969 {
970 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
971     FSP_ASSERT(p_baud_setting);
972     FSP_ERROR_RETURN(SCI_UART_MAX_BAUD_RATE_ERROR_X_1000 >= baud_rate_error_x_1000, FSP_ERR_INVALID_ARGUMENT);
973     FSP_ERROR_RETURN((0U != baudrate), FSP_ERR_INVALID_ARGUMENT);
974 #endif
975 
976     p_baud_setting->brr = SCI_UART_BRR_MAX;
977     p_baud_setting->semr_baudrate_bits_b.brme = 0U;
978     p_baud_setting->mddr = SCI_UART_MDDR_MIN;
979 
980     /* Find the best BRR (bit rate register) value.
981      *  In table g_async_baud, divisor values are stored for BGDM, ABCS, ABCSE and N values.  Each set of divisors
982      *  is tried, and the settings with the lowest bit rate error are stored. The formula to calculate BRR is as
983      *  follows and it must be 255 or less:
984      *  BRR = (PCLK / (div_coefficient * baud)) - 1
985      */
986     int32_t  hit_bit_err = SCI_UART_100_PERCENT_X_1000;
987     uint8_t  hit_mddr    = 0U;
988     uint32_t divisor     = 0U;
989 
990     uint32_t freq_hz = R_FSP_SystemClockHzGet(BSP_FEATURE_SCI_CLOCK);
991 
992     for (uint32_t select_16_base_clk_cycles = 0U;
993          select_16_base_clk_cycles <= 1U && (hit_bit_err > ((int32_t) baud_rate_error_x_1000));
994          select_16_base_clk_cycles++)
995     {
996         for (uint32_t i = 0U; i < SCI_UART_NUM_DIVISORS_ASYNC; i++)
997         {
998             /* if select_16_base_clk_cycles == true:  Skip this calculation for divisors that are not acheivable with 16 base clk cycles per bit.
999              *  if select_16_base_clk_cycles == false: Skip this calculation for divisors that are only acheivable without 16 base clk cycles per bit.
1000              */
1001             if (((uint8_t) select_16_base_clk_cycles) ^ (g_async_baud[i].abcs | g_async_baud[i].abcse))
1002             {
1003                 continue;
1004             }
1005 
1006             divisor = (uint32_t) g_div_coefficient[i] * baudrate;
1007             uint32_t temp_brr = freq_hz / divisor;
1008 
1009             if (temp_brr <= (SCI_UART_BRR_MAX + 1U))
1010             {
1011                 while (temp_brr > 0U)
1012                 {
1013                     temp_brr -= 1U;
1014 
1015                     /* Calculate the bit rate error. The formula is as follows:
1016                      *  bit rate error[%] = {(PCLK / (baud * div_coefficient * (BRR + 1)) - 1} x 100
1017                      *  calculates bit rate error[%] to three decimal places
1018                      */
1019                     int32_t err_divisor = (int32_t) (divisor * (temp_brr + 1U));
1020 
1021                     /* Promoting to 64 bits for calculation, but the final value can never be more than 32 bits, as
1022                      * described below, so this cast is safe.
1023                      *    1. (temp_brr + 1) can be off by an upper limit of 1 due to rounding from the calculation:
1024                      *       freq_hz / divisor, or:
1025                      *       freq_hz / divisor <= (temp_brr + 1) < (freq_hz / divisor) + 1
1026                      *    2. Solving for err_divisor:
1027                      *       freq_hz <= err_divisor < freq_hz + divisor
1028                      *    3. Solving for bit_err:
1029                      *       0 >= bit_err >= (freq_hz * 100000 / (freq_hz + divisor)) - 100000
1030                      *    4. freq_hz >= divisor (or temp_brr would be -1 and we would never enter this while loop), so:
1031                      *       0 >= bit_err >= 100000 / freq_hz - 100000
1032                      *    5. Larger frequencies yield larger bit errors (absolute value).  As the frequency grows,
1033                      *       the bit_err approaches -100000, so:
1034                      *       0 >= bit_err >= -100000
1035                      *    6. bit_err is between -100000 and 0.  This entire range fits in an int32_t type, so the cast
1036                      *       to (int32_t) is safe.
1037                      */
1038                     int32_t bit_err = (int32_t) (((((int64_t) freq_hz) * SCI_UART_100_PERCENT_X_1000) /
1039                                                   err_divisor) - SCI_UART_100_PERCENT_X_1000);
1040 
1041                     uint8_t mddr = 0U;
1042                     if (bitrate_modulation)
1043                     {
1044                         /* Calculate the MDDR (M) value if bit rate modulation is enabled,
1045                          * The formula to calculate MBBR (from the M and N relationship given in the hardware manual) is as follows
1046                          * and it must be between 128 and 255.
1047                          * MDDR = ((div_coefficient * baud * 256) * (BRR + 1)) / PCLK */
1048                         mddr = (uint8_t) ((uint32_t) err_divisor / (freq_hz / SCI_UART_MDDR_MAX));
1049 
1050                         /* MDDR value must be greater than or equal to SCI_UART_MDDR_MIN. */
1051                         if (mddr < SCI_UART_MDDR_MIN)
1052                         {
1053                             break;
1054                         }
1055 
1056                         /* Adjust bit rate error for bit rate modulation. The following formula is used:
1057                          *  bit rate error [%] = ((bit rate error [%, no modulation] + 100) * MDDR / 256) - 100
1058                          */
1059                         bit_err = (((bit_err + SCI_UART_100_PERCENT_X_1000) * (int32_t) mddr) /
1060                                    SCI_UART_MDDR_DIVISOR) - SCI_UART_100_PERCENT_X_1000;
1061                     }
1062 
1063                     /* Take the absolute value of the bit rate error. */
1064                     if (bit_err < 0)
1065                     {
1066                         bit_err = -bit_err;
1067                     }
1068 
1069                     /* If the absolute value of the bit rate error is less than the previous lowest absolute value of
1070                      *  bit rate error, then store these settings as the best value.
1071                      */
1072                     if (bit_err < hit_bit_err)
1073                     {
1074                         p_baud_setting->semr_baudrate_bits_b.bgdm  = g_async_baud[i].bgdm;
1075                         p_baud_setting->semr_baudrate_bits_b.abcs  = g_async_baud[i].abcs;
1076                         p_baud_setting->semr_baudrate_bits_b.abcse = g_async_baud[i].abcse;
1077                         p_baud_setting->cks = g_async_baud[i].cks;
1078                         p_baud_setting->brr = (uint8_t) temp_brr;
1079                         hit_bit_err         = bit_err;
1080                         hit_mddr            = mddr;
1081                     }
1082 
1083                     if (bitrate_modulation)
1084                     {
1085                         p_baud_setting->semr_baudrate_bits_b.brme = 1U;
1086                         p_baud_setting->mddr = hit_mddr;
1087                     }
1088                     else
1089                     {
1090                         break;
1091                     }
1092                 }
1093             }
1094         }
1095     }
1096 
1097     /* Return an error if the percent error is larger than the maximum percent error allowed for this instance */
1098     FSP_ERROR_RETURN((hit_bit_err <= (int32_t) baud_rate_error_x_1000), FSP_ERR_INVALID_ARGUMENT);
1099 
1100     return FSP_SUCCESS;
1101 }
1102 
1103 /*******************************************************************************************************************//**
1104  * @} (end addtogroup SCI_UART)
1105  **********************************************************************************************************************/
1106 
1107 /***********************************************************************************************************************
1108  * Private Functions
1109  **********************************************************************************************************************/
1110 
1111 /*******************************************************************************************************************//**
1112  * Negate the DE pin if it is enabled.
1113  *
1114  * @param[in] p_ctrl Pointer to the control block for the channel.
1115  **********************************************************************************************************************/
r_sci_negate_de_pin(sci_uart_instance_ctrl_t const * const p_ctrl)1116 static void r_sci_negate_de_pin (sci_uart_instance_ctrl_t const * const p_ctrl)
1117 {
1118 #if (SCI_UART_CFG_RS485_SUPPORT)
1119     sci_uart_extended_cfg_t * p_extend = (sci_uart_extended_cfg_t *) p_ctrl->p_cfg->p_extend;
1120 
1121     /* If RS-485 is enabled, then negate the driver enable pin at the end of a write transfer. */
1122     if (p_extend->rs485_setting.enable)
1123     {
1124         R_BSP_PinAccessEnable();
1125 
1126         bsp_io_level_t level = SCI_UART_RS485_DE_POLARITY_HIGH ==
1127                                p_extend->rs485_setting.polarity ? BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH;
1128         R_BSP_PinWrite(p_extend->rs485_setting.de_control_pin, level);
1129 
1130         R_BSP_PinAccessDisable();
1131     }
1132 
1133 #else
1134     FSP_PARAMETER_NOT_USED(p_ctrl);
1135 #endif
1136 }
1137 
1138 #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
1139 
1140 /*******************************************************************************************************************//**
1141  * Parameter error check function for read/write.
1142  *
1143  * @param[in] p_ctrl Pointer to the control block for the channel
1144  * @param[in] addr   Pointer to the buffer
1145  * @param[in] bytes  Number of bytes to read or write
1146  *
1147  * @retval  FSP_SUCCESS              No parameter error found
1148  * @retval  FSP_ERR_NOT_OPEN         The control block has not been opened
1149  * @retval  FSP_ERR_ASSERTION        Pointer to UART control block or configuration structure is NULL
1150  * @retval  FSP_ERR_INVALID_ARGUMENT Address is not aligned to 2-byte boundary or size is the odd number when the data
1151  *                                   length is 9-bit
1152  **********************************************************************************************************************/
r_sci_read_write_param_check(sci_uart_instance_ctrl_t const * const p_ctrl,uint8_t const * const addr,uint32_t const bytes)1153 static fsp_err_t r_sci_read_write_param_check (sci_uart_instance_ctrl_t const * const p_ctrl,
1154                                                uint8_t const * const                  addr,
1155                                                uint32_t const                         bytes)
1156 {
1157     FSP_ASSERT(p_ctrl);
1158     FSP_ASSERT(addr);
1159     FSP_ASSERT(0U != bytes);
1160     FSP_ERROR_RETURN(SCI_UART_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
1161 
1162     if (2U == p_ctrl->data_bytes)
1163     {
1164         /* Do not allow odd buffer address if data length is 9 bits. */
1165         FSP_ERROR_RETURN((0U == ((uint32_t) addr & SCI_UART_ALIGN_2_BYTES)), FSP_ERR_INVALID_ARGUMENT);
1166 
1167         /* Do not allow odd number of data bytes if data length is 9 bits. */
1168         FSP_ERROR_RETURN(0U == (bytes % 2U), FSP_ERR_INVALID_ARGUMENT);
1169     }
1170 
1171     return FSP_SUCCESS;
1172 }
1173 
1174 #endif
1175 #if SCI_UART_CFG_DTC_SUPPORTED
1176 
1177 /*******************************************************************************************************************//**
1178  * Subroutine to apply common UART transfer settings.
1179  *
1180  * @param[in]  p_cfg              Pointer to UART specific configuration structure
1181  * @param[in]  p_transfer         Pointer to transfer instance to configure
1182  *
1183  * @retval     FSP_SUCCESS        UART transfer drivers successfully configured
1184  * @retval     FSP_ERR_ASSERTION  Invalid pointer
1185  **********************************************************************************************************************/
r_sci_uart_transfer_configure(sci_uart_instance_ctrl_t * const p_ctrl,transfer_instance_t const * p_transfer,uint32_t * p_transfer_reg,uint32_t sci_buffer_address)1186 static fsp_err_t r_sci_uart_transfer_configure (sci_uart_instance_ctrl_t * const p_ctrl,
1187                                                 transfer_instance_t const      * p_transfer,
1188                                                 uint32_t                       * p_transfer_reg,
1189                                                 uint32_t                         sci_buffer_address)
1190 {
1191     /* Configure the transfer instance, if enabled. */
1192  #if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
1193     FSP_ASSERT(NULL != p_transfer->p_api);
1194     FSP_ASSERT(NULL != p_transfer->p_ctrl);
1195     FSP_ASSERT(NULL != p_transfer->p_cfg);
1196     FSP_ASSERT(NULL != p_transfer->p_cfg->p_info);
1197     FSP_ASSERT(NULL != p_transfer->p_cfg->p_extend);
1198  #endif
1199     transfer_info_t * p_info = p_transfer->p_cfg->p_info;
1200 
1201     /* Casting for compatibility with 7 or 8 bit mode. */
1202     *p_transfer_reg = sci_buffer_address;
1203 
1204  #if SCI_UART_CFG_FIFO_SUPPORT
1205     if (p_ctrl->fifo_depth > 0U)
1206     {
1207         /* Casting for compatibility with 7 or 8 bit mode. */
1208         *p_transfer_reg = sci_buffer_address + SCI_UART_FIFO_TRANSFER_BUFFER_OFFSET;
1209     }
1210  #endif
1211 
1212     if (UART_DATA_BITS_9 == p_ctrl->p_cfg->data_bits)
1213     {
1214         p_info->transfer_settings_word_b.size = TRANSFER_SIZE_2_BYTE;
1215 
1216         /* Casting for compatibility with 7 or 8 bit mode. */
1217         *p_transfer_reg = sci_buffer_address + SCI_UART_9BIT_TRANSFER_BUFFER_OFFSET;
1218     }
1219 
1220     fsp_err_t err = p_transfer->p_api->open(p_transfer->p_ctrl, p_transfer->p_cfg);
1221     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1222 
1223     return FSP_SUCCESS;
1224 }
1225 
1226 #endif
1227 
1228 #if SCI_UART_CFG_DTC_SUPPORTED
1229 
1230 /*******************************************************************************************************************//**
1231  * Configures UART related transfer drivers (if enabled).
1232  *
1233  * @param[in]     p_ctrl  Pointer to UART control structure
1234  * @param[in]     p_cfg   Pointer to UART specific configuration structure
1235  *
1236  * @retval        FSP_SUCCESS        UART transfer drivers successfully configured
1237  * @retval        FSP_ERR_ASSERTION  Invalid pointer or required interrupt not enabled in vector table
1238  *
1239  * @return                       See @ref RENESAS_ERROR_CODES or functions called by this function for other possible
1240  *                               return codes. This function calls:
1241  *                                   * @ref transfer_api_t::open
1242  **********************************************************************************************************************/
r_sci_uart_transfer_open(sci_uart_instance_ctrl_t * const p_ctrl,uart_cfg_t const * const p_cfg)1243 static fsp_err_t r_sci_uart_transfer_open (sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg)
1244 {
1245     fsp_err_t err = FSP_SUCCESS;
1246 
1247  #if (SCI_UART_CFG_RX_ENABLE)
1248 
1249     /* If a transfer instance is used for reception, apply UART specific settings and open the transfer instance. */
1250     if (NULL != p_cfg->p_transfer_rx)
1251     {
1252         transfer_info_t * p_info = p_cfg->p_transfer_rx->p_cfg->p_info;
1253 
1254         err =
1255             r_sci_uart_transfer_configure(p_ctrl, p_cfg->p_transfer_rx, (uint32_t *) &p_info->p_src,
1256                                           (uint32_t) &(p_ctrl->p_reg->RDR));
1257         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1258     }
1259  #endif
1260  #if (SCI_UART_CFG_TX_ENABLE)
1261 
1262     /* If a transfer instance is used for transmission, apply UART specific settings and open the transfer instance. */
1263     if (NULL != p_cfg->p_transfer_tx)
1264     {
1265         transfer_info_t * p_info = p_cfg->p_transfer_tx->p_cfg->p_info;
1266 
1267         err = r_sci_uart_transfer_configure(p_ctrl,
1268                                             p_cfg->p_transfer_tx,
1269                                             (uint32_t *) &p_info->p_dest,
1270                                             (uint32_t) &p_ctrl->p_reg->TDR);
1271 
1272   #if (SCI_UART_CFG_RX_ENABLE)
1273         if ((err != FSP_SUCCESS) && (NULL != p_cfg->p_transfer_rx))
1274         {
1275             p_cfg->p_transfer_rx->p_api->close(p_cfg->p_transfer_rx->p_ctrl);
1276         }
1277   #endif
1278         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
1279     }
1280  #endif
1281 
1282     return err;
1283 }
1284 
1285 #endif
1286 
1287 /*******************************************************************************************************************//**
1288  * Configures UART related registers based on user configurations.
1289  *
1290  * @param[in]     p_ctrl  Pointer to UART control structure
1291  * @param[in]     p_cfg   Pointer to UART specific configuration structure
1292  **********************************************************************************************************************/
r_sci_uart_config_set(sci_uart_instance_ctrl_t * const p_ctrl,uart_cfg_t const * const p_cfg)1293 static void r_sci_uart_config_set (sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg)
1294 {
1295 #if SCI_UART_CFG_FIFO_SUPPORT
1296 
1297     /* Configure FIFO related registers. */
1298     r_sci_uart_fifo_cfg(p_ctrl);
1299 #else
1300 
1301     /* If fifo support is disabled and the current channel supports fifo make sure it's disabled. */
1302     if (BSP_FEATURE_SCI_UART_FIFO_CHANNELS & (1U << p_cfg->channel))
1303     {
1304         p_ctrl->p_reg->FCR = SCI_UART_FCR_DEFAULT_VALUE;
1305     }
1306 #endif
1307 
1308     /* Configure parity and stop bits. */
1309     uint32_t smr  = (((uint32_t) p_cfg->parity << 4U) | ((uint32_t) p_cfg->stop_bits << 3U));
1310     uint32_t scmr = SCI_UART_SCMR_DEFAULT_VALUE;
1311 
1312     /* Configure data size. */
1313     if (UART_DATA_BITS_7 == p_cfg->data_bits)
1314     {
1315         /* Set the SMR.CHR bit & SCMR.CHR1 bit as selected (Character Length)
1316          *  Character Length
1317          *  (CHR1,CHR)
1318          *  (1, 1) Transmit/receive in 7-bit data length*3
1319          */
1320         smr |= (1U << 6);
1321     }
1322     else if (UART_DATA_BITS_9 == p_cfg->data_bits)
1323     {
1324         /* Set the SMR.CHR bit & SCMR.CHR1 bit as selected (Character Length)
1325          *  Character Length
1326          *  (CHR1,CHR)
1327          *  (0, 0) Transmit/receive in 9-bit data length
1328          */
1329         scmr &= ~(1U << 4);
1330     }
1331     else
1332     {
1333         /* Do nothing.  Default is 8-bit mode. */
1334     }
1335 
1336     /* Write to the SMR register. */
1337     p_ctrl->p_reg->SMR = (uint8_t) smr;
1338 
1339     /* Write to the SCMR register. */
1340     p_ctrl->p_reg->SCMR = (uint8_t) scmr;
1341 
1342     sci_uart_extended_cfg_t * p_extend = (sci_uart_extended_cfg_t *) p_cfg->p_extend;
1343 
1344     /* Configure flow control if CTS/RTS flow control is enabled. */
1345 #if BSP_FEATURE_SCI_UART_CSTPEN_CHANNELS
1346     if (p_extend->flow_control == SCI_UART_FLOW_CONTROL_HARDWARE_CTSRTS)
1347     {
1348         p_ctrl->p_reg->SPMR = R_SCI0_SPMR_CSTPEN_Msk | R_SCI0_SPMR_CTSE_Msk;
1349     }
1350     else
1351 #endif
1352     {
1353         p_ctrl->p_reg->SPMR = ((uint8_t) (p_extend->flow_control << R_SCI0_SPMR_CTSE_Pos) & R_SCI0_SPMR_CTSE_Msk);
1354     }
1355 
1356     uint32_t semr = 0;
1357 
1358     /* Starts reception on falling edge of RXD if enabled in extension (otherwise reception starts at low level
1359      * of RXD). */
1360     semr |= (p_extend->rx_edge_start & 1U) << 7;
1361 
1362     /* Enables the noise cancellation, fixed to the minimum level, if enabled in the extension. */
1363     semr |= (p_extend->noise_cancel & 1U) << 5;
1364 
1365     p_ctrl->p_reg->SNFR = NOISE_CANCEL_LVL1;
1366 
1367     if ((SCI_UART_CLOCK_EXT8X == p_extend->clock) || (SCI_UART_CLOCK_EXT16X == p_extend->clock))
1368     {
1369         /* Use external clock for baud rate */
1370         p_ctrl->p_reg->BRR = SCI_UART_BRR_DEFAULT_VALUE;
1371 
1372         if (SCI_UART_CLOCK_EXT8X == p_extend->clock)
1373         {
1374             /* Set baud rate as (external clock / 8) */
1375             semr |= 1U << SCI_UART_SEMR_ABCS_OFFSET;
1376         }
1377 
1378         p_ctrl->p_reg->SEMR = (uint8_t) semr;
1379     }
1380     else
1381     {
1382         p_ctrl->p_reg->SEMR = (uint8_t) semr;
1383 
1384         /* Set the baud rate settings for the internal baud rate generator. */
1385         r_sci_uart_baud_set(p_ctrl->p_reg, p_extend->p_baud_setting);
1386     }
1387 }
1388 
1389 #if SCI_UART_CFG_FIFO_SUPPORT
1390 
1391 /*******************************************************************************************************************//**
1392  * Resets FIFO related registers.
1393  *
1394  * @param[in] p_ctrl  Pointer to UART instance control
1395  * @param[in] p_cfg   Pointer to UART configuration structure
1396  **********************************************************************************************************************/
r_sci_uart_fifo_cfg(sci_uart_instance_ctrl_t * const p_ctrl)1397 static void r_sci_uart_fifo_cfg (sci_uart_instance_ctrl_t * const p_ctrl)
1398 {
1399     if (0U != p_ctrl->fifo_depth)
1400     {
1401         /* Enable the fifo and set the tx and rx reset bits */
1402         uint32_t fcr = 1U;
1403 
1404  #if (SCI_UART_CFG_RX_ENABLE)
1405   #if SCI_UART_CFG_DTC_SUPPORTED
1406 
1407         /* If DTC is used keep the receive trigger at the default level of 0. */
1408         if (NULL == p_ctrl->p_cfg->p_transfer_rx)
1409   #endif
1410         {
1411             /* Otherwise, set receive trigger number as configured by the user. */
1412             sci_uart_extended_cfg_t const * p_extend = p_ctrl->p_cfg->p_extend;
1413 
1414             /* RTRG(Receive FIFO Data Trigger Number) controls when the RXI interrupt will be generated. If data is
1415              * received but the trigger number is not met the RXI interrupt will be generated after 15 ETUs from
1416              * the last stop bit in asynchronous mode. For more information see the FIFO Selected section of "Serial
1417              * Data Reception in Asynchronous Mode" in the RA6M3 manual R01UH0886EJ0100 or the relevant section for
1418              * the MCU being used. */
1419             fcr |= (((p_ctrl->fifo_depth - 1U) & p_extend->rx_fifo_trigger) & SCI_UART_FCR_TRIGGER_MASK) <<
1420                    SCI_UART_FCR_RTRG_OFFSET;
1421         }
1422 
1423         /* RTS asserts when the amount of received data stored in the fifo is equal or less than this value. */
1424         fcr |= ((p_ctrl->fifo_depth - 1U) & SCI_UART_FCR_TRIGGER_MASK) << SCI_UART_FCR_RSTRG_OFFSET;
1425  #endif
1426 
1427         /* Set the FCR and reset the fifos. */
1428         p_ctrl->p_reg->FCR = (uint16_t) (fcr | SCI_UART_FCR_RESET_TX_RX);
1429 
1430         /* Wait for the fifo reset to complete after 1 PCLK according to section 34.2.26 "FIFO Control Register (FCR)
1431          * in the RA6M3 manual R01UH0886EJ0100 or the relevant section for the MCU being used.*/
1432         FSP_HARDWARE_REGISTER_WAIT(p_ctrl->p_reg->FCR, fcr);
1433     }
1434 }
1435 
1436 #endif
1437 
1438 /*******************************************************************************************************************//**
1439  * Sets interrupt priority and initializes vector info.
1440  *
1441  * @param[in]  p_ctrl                    Pointer to driver control block
1442  * @param[in]  ipl                       Interrupt priority level
1443  * @param[in]  irq                       IRQ number for this interrupt
1444  **********************************************************************************************************************/
r_sci_irq_cfg(sci_uart_instance_ctrl_t * const p_ctrl,uint8_t const ipl,IRQn_Type const irq)1445 static void r_sci_irq_cfg (sci_uart_instance_ctrl_t * const p_ctrl, uint8_t const ipl, IRQn_Type const irq)
1446 {
1447     /* Disable interrupts, set priority, and store control block in the vector information so it can be accessed
1448      * from the callback. */
1449     R_BSP_IrqDisable(irq);
1450     R_BSP_IrqStatusClear(irq);
1451     R_BSP_IrqCfg(irq, ipl, p_ctrl);
1452 }
1453 
1454 /*******************************************************************************************************************//**
1455  * Sets interrupt priority and initializes vector info for all interrupts.
1456  *
1457  * @param[in]  p_ctrl                    Pointer to UART instance control block
1458  * @param[in]  p_cfg                     Pointer to UART specific configuration structure
1459  **********************************************************************************************************************/
r_sci_irqs_cfg(sci_uart_instance_ctrl_t * const p_ctrl,uart_cfg_t const * const p_cfg)1460 static void r_sci_irqs_cfg (sci_uart_instance_ctrl_t * const p_ctrl, uart_cfg_t const * const p_cfg)
1461 {
1462 #if (SCI_UART_CFG_RX_ENABLE)
1463 
1464     /* ERI is optional. */
1465     r_sci_irq_cfg(p_ctrl, p_cfg->eri_ipl, p_cfg->eri_irq);
1466     r_sci_irq_cfg(p_ctrl, p_cfg->rxi_ipl, p_cfg->rxi_irq);
1467 #endif
1468 #if (SCI_UART_CFG_TX_ENABLE)
1469     r_sci_irq_cfg(p_ctrl, p_cfg->txi_ipl, p_cfg->txi_irq);
1470 
1471     r_sci_irq_cfg(p_ctrl, p_cfg->tei_ipl, p_cfg->tei_irq);
1472 #endif
1473 }
1474 
1475 #if SCI_UART_CFG_DTC_SUPPORTED
1476 
1477 /*******************************************************************************************************************//**
1478  * Closes transfer interfaces.
1479  *
1480  * @param[in]     p_ctrl     Pointer to UART instance control block
1481  **********************************************************************************************************************/
r_sci_uart_transfer_close(sci_uart_instance_ctrl_t * p_ctrl)1482 static void r_sci_uart_transfer_close (sci_uart_instance_ctrl_t * p_ctrl)
1483 {
1484  #if (SCI_UART_CFG_RX_ENABLE)
1485     if (NULL != p_ctrl->p_cfg->p_transfer_rx)
1486     {
1487         p_ctrl->p_cfg->p_transfer_rx->p_api->close(p_ctrl->p_cfg->p_transfer_rx->p_ctrl);
1488     }
1489  #endif
1490  #if (SCI_UART_CFG_TX_ENABLE)
1491     if (NULL != p_ctrl->p_cfg->p_transfer_tx)
1492     {
1493         p_ctrl->p_cfg->p_transfer_tx->p_api->close(p_ctrl->p_cfg->p_transfer_tx->p_ctrl);
1494     }
1495  #endif
1496 }
1497 
1498 #endif
1499 
1500 /*******************************************************************************************************************//**
1501  * Changes baud rate based on predetermined register settings.
1502  *
1503  * @param[in]  p_sci_reg       Base pointer for SCI registers
1504  * @param[in]  p_baud_setting  Pointer to other divisor related settings
1505  *
1506  * @note       The transmitter and receiver (TE and RE bits in SCR) must be disabled prior to calling this function.
1507  **********************************************************************************************************************/
r_sci_uart_baud_set(R_SCI0_Type * p_sci_reg,baud_setting_t const * const p_baud_setting)1508 static void r_sci_uart_baud_set (R_SCI0_Type * p_sci_reg, baud_setting_t const * const p_baud_setting)
1509 {
1510     /* Set BRR register value. */
1511     p_sci_reg->BRR = p_baud_setting->brr;
1512 
1513     /* Set clock source for the on-chip baud rate generator. */
1514     p_sci_reg->SMR_b.CKS = (uint8_t) (SCI_SMR_CKS_VALUE_MASK & p_baud_setting->cks);
1515 
1516     /* Set MDDR register value. */
1517     p_sci_reg->MDDR = p_baud_setting->mddr;
1518 
1519     /* Set clock divisor settings. */
1520     p_sci_reg->SEMR = (uint8_t) ((p_sci_reg->SEMR & ~(SCI_UART_SEMR_BAUD_SETTING_MASK)) |
1521                                  (p_baud_setting->semr_baudrate_bits & SCI_UART_SEMR_BAUD_SETTING_MASK));
1522 }
1523 
1524 /*******************************************************************************************************************//**
1525  * Calls user callback.
1526  *
1527  * @param[in]     p_ctrl     Pointer to UART instance control block
1528  * @param[in]     data       See uart_callback_args_t in r_uart_api.h
1529  * @param[in]     event      Event code
1530  **********************************************************************************************************************/
r_sci_uart_call_callback(sci_uart_instance_ctrl_t * p_ctrl,uint32_t data,uart_event_t event)1531 static void r_sci_uart_call_callback (sci_uart_instance_ctrl_t * p_ctrl, uint32_t data, uart_event_t event)
1532 {
1533     uart_callback_args_t args;
1534 
1535     /* Store callback arguments in memory provided by user if available.  This allows callback arguments to be
1536      * stored in non-secure memory so they can be accessed by a non-secure callback function. */
1537     uart_callback_args_t * p_args = p_ctrl->p_callback_memory;
1538     if (NULL == p_args)
1539     {
1540         /* Store on stack */
1541         p_args = &args;
1542     }
1543     else
1544     {
1545         /* Save current arguments on the stack in case this is a nested interrupt. */
1546         args = *p_args;
1547     }
1548 
1549     p_args->channel   = p_ctrl->p_cfg->channel;
1550     p_args->data      = data;
1551     p_args->event     = event;
1552     p_args->p_context = p_ctrl->p_context;
1553 
1554 #if BSP_TZ_SECURE_BUILD
1555 
1556     /* p_callback can point to a secure function or a non-secure function. */
1557     if (!cmse_is_nsfptr(p_ctrl->p_callback))
1558     {
1559         /* If p_callback is secure, then the project does not need to change security state. */
1560         p_ctrl->p_callback(p_args);
1561     }
1562     else
1563     {
1564         /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
1565         sci_uart_prv_ns_callback p_callback = (sci_uart_prv_ns_callback) (p_ctrl->p_callback);
1566         p_callback(p_args);
1567     }
1568 
1569 #else
1570 
1571     /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
1572     p_ctrl->p_callback(p_args);
1573 #endif
1574     if (NULL != p_ctrl->p_callback_memory)
1575     {
1576         /* Restore callback memory in case this is a nested interrupt. */
1577         *p_ctrl->p_callback_memory = args;
1578     }
1579 }
1580 
1581 #if (SCI_UART_CFG_TX_ENABLE)
1582 
1583 /*******************************************************************************************************************//**
1584  * TXI interrupt processing for UART mode. TXI interrupt fires when the data in the data register or FIFO register has
1585  * been transferred to the data shift register, and the next data can be written.  This interrupt writes the next data.
1586  * After the last data byte is written, this interrupt disables the TXI interrupt and enables the TEI (transmit end)
1587  * interrupt.
1588  **********************************************************************************************************************/
sci_uart_txi_isr(void)1589 void sci_uart_txi_isr (void)
1590 {
1591     /* Save context if RTOS is used */
1592     FSP_CONTEXT_SAVE
1593 
1594     IRQn_Type irq = R_FSP_CurrentIrqGet();
1595 
1596     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1597     R_BSP_IrqStatusClear(irq);
1598 
1599     /* Recover ISR context saved in open. */
1600     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1601 
1602     if ((NULL == p_ctrl->p_cfg->p_transfer_tx) && (0U != p_ctrl->tx_src_bytes))
1603     {
1604         /* Write the data to the FIFO if the channel has a FIFO.  Otherwise write data based on size to the transmit
1605          * register.  Write to 16-bit TDRHL for 9-bit data, or 8-bit TDR otherwise. */
1606  #if SCI_UART_CFG_FIFO_SUPPORT
1607         if (0U != p_ctrl->fifo_depth)
1608         {
1609             uint32_t fifo_count = (uint32_t) p_ctrl->p_reg->FDR_b.T;
1610             for (uint32_t cnt = fifo_count; (cnt < p_ctrl->fifo_depth) && p_ctrl->tx_src_bytes; cnt++)
1611             {
1612                 if (2U == p_ctrl->data_bytes)
1613                 {
1614                     p_ctrl->p_reg->FTDRHL =
1615                         (uint16_t) (*((uint16_t *) p_ctrl->p_tx_src) | (uint16_t) ~(SCI_UART_FIFO_DAT_MASK));
1616                 }
1617                 else
1618                 {
1619                     p_ctrl->p_reg->FTDRL = *p_ctrl->p_tx_src;
1620                 }
1621 
1622                 p_ctrl->tx_src_bytes -= p_ctrl->data_bytes;
1623                 p_ctrl->p_tx_src     += p_ctrl->data_bytes;
1624             }
1625 
1626             /* Clear TDFE flag */
1627             /* Don't acess the flag via bit fields because bit 1 is reserved. It must be written as '1' and has an */
1628             /* undefined read value. Bit fields will attempt to do a read-modify-write which could have unintended */
1629             /* side effects provided the undefined read behavior. */
1630             uint8_t ssr_fifo =
1631                 (uint8_t) ((p_ctrl->p_reg->SSR_FIFO | SCI_SSR_FIFO_RESERVED_MASK) & ~R_SCI0_SSR_FIFO_TDFE_Msk);
1632             p_ctrl->p_reg->SSR_FIFO = ssr_fifo;
1633         }
1634         else
1635  #endif
1636         {
1637             if ((2U == p_ctrl->data_bytes))
1638             {
1639                 /* Write 16-bit data to TDRHL register */
1640                 p_ctrl->p_reg->TDRHL = *((uint16_t *) (p_ctrl->p_tx_src)) | (uint16_t) ~(SCI_UART_FIFO_DAT_MASK);
1641             }
1642             else
1643             {
1644                 /* Write 1byte (uint8_t) data to (uint8_t) data register */
1645                 p_ctrl->p_reg->TDR = *(p_ctrl->p_tx_src);
1646             }
1647 
1648             /* Update pointer to the next data and number of remaining bytes in the control block. */
1649             p_ctrl->tx_src_bytes -= p_ctrl->data_bytes;
1650             p_ctrl->p_tx_src     += p_ctrl->data_bytes;
1651         }
1652     }
1653 
1654     if (0U == p_ctrl->tx_src_bytes)
1655     {
1656         /* After all data has been transmitted, disable transmit interrupts and enable the transmit end interrupt. */
1657         uint8_t scr_temp = p_ctrl->p_reg->SCR;
1658         scr_temp          |= SCI_SCR_TEIE_MASK;
1659         scr_temp          &= (uint8_t) ~SCI_SCR_TIE_MASK;
1660         p_ctrl->p_reg->SCR = scr_temp;
1661 
1662         p_ctrl->p_tx_src = NULL;
1663 
1664         /* If a callback was provided, call it with the argument */
1665         if (NULL != p_ctrl->p_callback)
1666         {
1667             r_sci_uart_call_callback(p_ctrl, 0U, UART_EVENT_TX_DATA_EMPTY);
1668         }
1669     }
1670 
1671     /* Restore context if RTOS is used */
1672     FSP_CONTEXT_RESTORE
1673 }
1674 
1675 #endif
1676 
1677 #if (SCI_UART_CFG_RX_ENABLE)
1678 
1679 /*******************************************************************************************************************//**
1680  * RXI interrupt processing for UART mode. RXI interrupt happens when data arrives to the data register or the FIFO
1681  * register.  This function calls callback function when it meets conditions below.
1682  *  - UART_EVENT_RX_COMPLETE: The number of data which has been read reaches to the number specified in R_SCI_UART_Read()
1683  *    if a transfer instance is used for reception.
1684  *  - UART_EVENT_RX_CHAR: Data is received asynchronously (read has not been called)
1685  *
1686  * This interrupt also calls the callback function for RTS pin control if it is registered in R_SCI_UART_Open(). This is
1687  * special functionality to expand SCI hardware capability and make RTS/CTS hardware flow control possible. If macro
1688  * 'SCI_UART_CFG_FLOW_CONTROL_SUPPORT' is set, it is called at the beginning in this function to set the RTS pin high,
1689  * then it is called again just before leaving this function to set the RTS pin low.
1690  * @retval    none
1691  **********************************************************************************************************************/
sci_uart_rxi_isr(void)1692 void sci_uart_rxi_isr (void)
1693 {
1694     /* Save context if RTOS is used */
1695     FSP_CONTEXT_SAVE
1696 
1697     IRQn_Type irq = R_FSP_CurrentIrqGet();
1698 
1699     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1700     R_BSP_IrqStatusClear(irq);
1701 
1702     /* Recover ISR context saved in open. */
1703     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1704 
1705  #if SCI_UART_CFG_DTC_SUPPORTED
1706     if ((p_ctrl->p_cfg->p_transfer_rx == NULL) || (0 == p_ctrl->rx_dest_bytes))
1707  #endif
1708     {
1709  #if (SCI_UART_CFG_FLOW_CONTROL_SUPPORT)
1710         if (p_ctrl->flow_pin != SCI_UART_INVALID_16BIT_PARAM)
1711         {
1712             R_BSP_PinAccessEnable();
1713 
1714             /* Pause the transmission of data from the other device. */
1715             R_BSP_PinWrite(p_ctrl->flow_pin, SCI_UART_FLOW_CONTROL_ACTIVE);
1716         }
1717  #endif
1718 
1719         uint32_t data;
1720  #if SCI_UART_CFG_FIFO_SUPPORT
1721         do
1722         {
1723             if ((p_ctrl->fifo_depth > 0U))
1724             {
1725                 if (p_ctrl->p_reg->FDR_b.R > 0U)
1726                 {
1727                     data = p_ctrl->p_reg->FRDRHL & FRDR_TDAT_MASK_9BITS;
1728                 }
1729                 else
1730                 {
1731                     break;
1732                 }
1733             }
1734             else if (2U == p_ctrl->data_bytes)
1735  #else
1736         {
1737             if (2U == p_ctrl->data_bytes)
1738  #endif
1739             {
1740                 data = p_ctrl->p_reg->RDRHL & FRDR_TDAT_MASK_9BITS;
1741             }
1742             else
1743             {
1744                 data = p_ctrl->p_reg->RDR;
1745             }
1746 
1747             if (0 == p_ctrl->rx_dest_bytes)
1748             {
1749                 /* If a callback was provided, call it with the argument */
1750                 if (NULL != p_ctrl->p_callback)
1751                 {
1752                     /* Call user callback with the data. */
1753                     r_sci_uart_call_callback(p_ctrl, data, UART_EVENT_RX_CHAR);
1754                 }
1755             }
1756             else
1757             {
1758                 memcpy((void *) p_ctrl->p_rx_dest, &data, p_ctrl->data_bytes);
1759                 p_ctrl->p_rx_dest     += p_ctrl->data_bytes;
1760                 p_ctrl->rx_dest_bytes -= p_ctrl->data_bytes;
1761 
1762                 if (0 == p_ctrl->rx_dest_bytes)
1763                 {
1764                     /* If a callback was provided, call it with the argument */
1765                     if (NULL != p_ctrl->p_callback)
1766                     {
1767                         r_sci_uart_call_callback(p_ctrl, 0U, UART_EVENT_RX_COMPLETE);
1768                     }
1769                 }
1770             }
1771 
1772  #if SCI_UART_CFG_FIFO_SUPPORT
1773         } while ((p_ctrl->fifo_depth > 0U) && ((p_ctrl->p_reg->FDR_b.R) > 0U));
1774 
1775         if (p_ctrl->fifo_depth > 0U)
1776         {
1777             p_ctrl->p_reg->SSR_FIFO = (uint8_t) ~(SCI_UART_SSR_FIFO_DR_RDF);
1778         }
1779 
1780  #else
1781         }
1782  #endif
1783  #if (SCI_UART_CFG_FLOW_CONTROL_SUPPORT)
1784         if (p_ctrl->flow_pin != SCI_UART_INVALID_16BIT_PARAM)
1785         {
1786             /* Resume the transmission of data from the other device. */
1787             R_BSP_PinWrite(p_ctrl->flow_pin, SCI_UART_FLOW_CONTROL_INACTIVE);
1788             R_BSP_PinAccessDisable();
1789         }
1790  #endif
1791     }
1792 
1793  #if SCI_UART_CFG_DTC_SUPPORTED
1794     else
1795     {
1796         p_ctrl->rx_dest_bytes = 0;
1797 
1798         p_ctrl->p_rx_dest = NULL;
1799 
1800         /* If a callback was provided, call it with the argument */
1801         if (NULL != p_ctrl->p_callback)
1802         {
1803             /* Call callback */
1804             r_sci_uart_call_callback(p_ctrl, 0U, UART_EVENT_RX_COMPLETE);
1805         }
1806     }
1807  #endif
1808 
1809     /* Restore context if RTOS is used */
1810     FSP_CONTEXT_RESTORE
1811 }
1812 
1813 #endif
1814 
1815 #if (SCI_UART_CFG_TX_ENABLE)
1816 
1817 /*******************************************************************************************************************//**
1818  * TEI interrupt processing for UART mode. The TEI interrupt fires after the last byte is transmitted on the TX pin.
1819  * The user callback function is called with the UART_EVENT_TX_COMPLETE event code (if it is registered in
1820  * R_SCI_UART_Open()).
1821  **********************************************************************************************************************/
sci_uart_tei_isr(void)1822 void sci_uart_tei_isr (void)
1823 {
1824     /* Save context if RTOS is used */
1825     FSP_CONTEXT_SAVE
1826 
1827     IRQn_Type irq = R_FSP_CurrentIrqGet();
1828 
1829     /* Recover ISR context saved in open. */
1830     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1831 
1832     /* Receiving TEI(transmit end interrupt) means the completion of transmission, so call callback function here. */
1833     p_ctrl->p_reg->SCR &= (uint8_t) ~(SCI_SCR_TIE_MASK | SCI_SCR_TEIE_MASK);
1834 
1835     /* Negate driver enable if RS-485 mode is enabled. */
1836     r_sci_negate_de_pin(p_ctrl);
1837 
1838     /* If a callback was provided, call it with the argument */
1839     if (NULL != p_ctrl->p_callback)
1840     {
1841         r_sci_uart_call_callback(p_ctrl, 0U, UART_EVENT_TX_COMPLETE);
1842     }
1843 
1844     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1845     R_BSP_IrqStatusClear(irq);
1846 
1847     /* Restore context if RTOS is used */
1848     FSP_CONTEXT_RESTORE
1849 }
1850 
1851 #endif
1852 
1853 #if (SCI_UART_CFG_RX_ENABLE)
1854 
1855 /*******************************************************************************************************************//**
1856  * ERI interrupt processing for UART mode. When an ERI interrupt fires, the user callback function is called if it is
1857  * registered in R_SCI_UART_Open() with the event code that triggered the interrupt.
1858  **********************************************************************************************************************/
sci_uart_eri_isr(void)1859 void sci_uart_eri_isr (void)
1860 {
1861     /* Save context if RTOS is used */
1862     FSP_CONTEXT_SAVE;
1863 
1864     IRQn_Type irq = R_FSP_CurrentIrqGet();
1865 
1866     /* Recover ISR context saved in open. */
1867     sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1868 
1869     uint32_t     data = 0U;
1870     uart_event_t event;
1871 
1872     /* Read data. */
1873     if (
1874  #if SCI_UART_CFG_FIFO_SUPPORT
1875         (p_ctrl->fifo_depth > 0U) ||
1876  #endif
1877         (2U == p_ctrl->data_bytes))
1878     {
1879         {
1880             data = p_ctrl->p_reg->RDRHL & SCI_UART_FIFO_DAT_MASK;
1881         }
1882     }
1883     else
1884     {
1885         data = p_ctrl->p_reg->RDR;
1886     }
1887 
1888     /* Determine cause of error. */
1889     event = (uart_event_t) (p_ctrl->p_reg->SSR & SCI_RCVR_ERR_MASK);
1890 
1891     /* Check if there is a break detected. */
1892     if ((UART_EVENT_ERR_FRAMING == (event & UART_EVENT_ERR_FRAMING)) && (0U == p_ctrl->p_reg->SPTR_b.RXDMON))
1893     {
1894         event |= UART_EVENT_BREAK_DETECT;
1895     }
1896 
1897     /* Clear error condition. */
1898     p_ctrl->p_reg->SSR &= (uint8_t) (~SCI_RCVR_ERR_MASK);
1899 
1900     /* Negate driver enable if RS-485 mode is enabled. */
1901     r_sci_negate_de_pin(p_ctrl);
1902 
1903     /* If a callback was provided, call it with the argument */
1904     if (NULL != p_ctrl->p_callback)
1905     {
1906         /* Call callback. */
1907         r_sci_uart_call_callback(p_ctrl, data, event);
1908     }
1909 
1910     /* Clear pending IRQ to make sure it doesn't fire again after exiting */
1911     R_BSP_IrqStatusClear(irq);
1912 
1913     /* Restore context if RTOS is used */
1914     FSP_CONTEXT_RESTORE;
1915 }
1916 
1917 #endif
1918