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