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 <baud_rate_percent_error> 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