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