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