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