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