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