8
8
#include <zephyr/drivers/pinctrl.h>
9
9
#include <zephyr/drivers/uart.h>
10
10
#include <zephyr/logging/log.h>
11
+ #include <zephyr/irq.h>
11
12
#include "r_scif_uart.h"
12
13
13
14
LOG_MODULE_REGISTER (rz_scif_uart );
@@ -17,12 +18,36 @@ struct uart_rz_scif_config {
17
18
const uart_api_t * fsp_api ;
18
19
};
19
20
21
+ struct uart_rz_scif_int {
22
+ bool rxi_flag ;
23
+ bool tei_flag ;
24
+ bool rx_fifo_busy ;
25
+ bool irq_rx_enable ;
26
+ bool irq_tx_enable ;
27
+ uint8_t rx_byte ;
28
+ uint8_t tx_byte ;
29
+ uart_event_t event ;
30
+ };
31
+
20
32
struct uart_rz_scif_data {
21
33
struct uart_config uart_config ;
22
34
uart_cfg_t * fsp_cfg ;
35
+ struct uart_rz_scif_int int_data ;
23
36
scif_uart_instance_ctrl_t * fsp_ctrl ;
37
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
38
+ uart_irq_callback_user_data_t callback ;
39
+ void * callback_data ;
40
+ #endif
24
41
};
25
42
43
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
44
+ void scif_uart_rxi_isr (void );
45
+ void scif_uart_txi_isr (void );
46
+ void scif_uart_tei_isr (void );
47
+ void scif_uart_eri_isr (void );
48
+ void scif_uart_bri_isr (void );
49
+ #endif
50
+
26
51
static int uart_rz_scif_poll_in (const struct device * dev , unsigned char * c )
27
52
{
28
53
struct uart_rz_scif_data * data = dev -> data ;
@@ -41,6 +66,9 @@ static void uart_rz_scif_poll_out(const struct device *dev, unsigned char c)
41
66
{
42
67
struct uart_rz_scif_data * data = dev -> data ;
43
68
R_SCIFA0_Type * reg = data -> fsp_ctrl -> p_reg ;
69
+ uint8_t key ;
70
+
71
+ key = irq_lock ();
44
72
45
73
while (!reg -> FSR_b .TDFE ) {
46
74
}
@@ -49,28 +77,27 @@ static void uart_rz_scif_poll_out(const struct device *dev, unsigned char c)
49
77
50
78
while (!reg -> FSR_b .TEND ) {
51
79
}
80
+
81
+ irq_unlock (key );
52
82
}
53
83
54
84
static int uart_rz_scif_err_check (const struct device * dev )
55
85
{
56
86
struct uart_rz_scif_data * data = dev -> data ;
57
- R_SCIFA0_Type * reg = data -> fsp_ctrl -> p_reg ;
87
+ uart_event_t event = data -> int_data .event ;
88
+ int err = 0 ;
58
89
59
- const uint32_t fsr = reg -> FSR ;
60
- const uint32_t lsr = reg -> LSR ;
61
- int errors = 0 ;
62
-
63
- if ((lsr & R_SCIFA0_LSR_ORER_Msk ) != 0 ) {
64
- errors |= UART_ERROR_OVERRUN ;
90
+ if (event & UART_EVENT_ERR_OVERFLOW ) {
91
+ err |= UART_ERROR_OVERRUN ;
65
92
}
66
- if (( fsr & R_SCIFA0_FSR_PER_Msk ) != 0 ) {
67
- errors |= UART_ERROR_PARITY ;
93
+ if (event & UART_EVENT_ERR_FRAMING ) {
94
+ err |= UART_ERROR_FRAMING ;
68
95
}
69
- if (( fsr & R_SCIFA0_FSR_FER_Pos ) != 0 ) {
70
- errors |= UART_ERROR_FRAMING ;
96
+ if (event & UART_EVENT_ERR_PARITY ) {
97
+ err |= UART_ERROR_PARITY ;
71
98
}
72
99
73
- return errors ;
100
+ return err ;
74
101
}
75
102
76
103
static int uart_rz_scif_apply_config (const struct device * dev )
@@ -179,11 +206,6 @@ static int uart_rz_scif_configure(const struct device *dev, const struct uart_co
179
206
return - EIO ;
180
207
}
181
208
182
- R_SCIFA0_Type * reg = data -> fsp_ctrl -> p_reg ;
183
- /* Temporarily disable the DRI interrupt caused by receive data ready */
184
- /* TODO: support interrupt-driven api */
185
- reg -> SCR_b .RIE = 0 ;
186
-
187
209
return err ;
188
210
}
189
211
@@ -197,6 +219,187 @@ static int uart_rz_scif_config_get(const struct device *dev, struct uart_config
197
219
198
220
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
199
221
222
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
223
+
224
+ static int uart_rz_scif_fifo_fill (const struct device * dev , const uint8_t * tx_data , int size )
225
+ {
226
+ struct uart_rz_scif_data * data = dev -> data ;
227
+ scif_uart_instance_ctrl_t * fsp_ctrl = data -> fsp_ctrl ;
228
+
229
+ fsp_ctrl -> tx_src_bytes = size ;
230
+ fsp_ctrl -> p_tx_src = tx_data ;
231
+
232
+ scif_uart_txi_isr ();
233
+
234
+ return (size - fsp_ctrl -> tx_src_bytes );
235
+ }
236
+
237
+ static int uart_rz_scif_fifo_read (const struct device * dev , uint8_t * rx_data , const int size )
238
+ {
239
+ struct uart_rz_scif_data * data = dev -> data ;
240
+
241
+ scif_uart_instance_ctrl_t * fsp_ctrl = data -> fsp_ctrl ;
242
+
243
+ fsp_ctrl -> rx_dest_bytes = size ;
244
+ fsp_ctrl -> p_rx_dest = rx_data ;
245
+
246
+ /* Read all available data in the FIFO */
247
+ /* If there are more available data than required, they will be lost */
248
+ if (data -> int_data .rxi_flag ) {
249
+ scif_uart_rxi_isr ();
250
+ } else {
251
+ scif_uart_tei_isr ();
252
+ }
253
+
254
+ data -> int_data .rx_fifo_busy = false;
255
+
256
+ return (size - fsp_ctrl -> rx_dest_bytes );
257
+ }
258
+
259
+ static void uart_rz_scif_irq_rx_enable (const struct device * dev )
260
+ {
261
+ const struct uart_rz_scif_config * config = dev -> config ;
262
+ struct uart_rz_scif_data * data = dev -> data ;
263
+
264
+ data -> int_data .irq_rx_enable = true;
265
+
266
+ /* Prepare 1-byte buffer to receive, it will be overwritten by fifo read */
267
+ config -> fsp_api -> read (data -> fsp_ctrl , & (data -> int_data .rx_byte ), 1 );
268
+ }
269
+
270
+ static void uart_rz_scif_irq_rx_disable (const struct device * dev )
271
+ {
272
+ struct uart_rz_scif_data * data = dev -> data ;
273
+
274
+ data -> int_data .irq_rx_enable = false;
275
+ data -> int_data .rx_fifo_busy = false;
276
+ }
277
+
278
+ static void uart_rz_scif_irq_tx_enable (const struct device * dev )
279
+ {
280
+ struct uart_rz_scif_data * data = dev -> data ;
281
+ const struct uart_rz_scif_config * config = dev -> config ;
282
+
283
+ data -> int_data .irq_tx_enable = true;
284
+
285
+ /* Trigger TX with a NULL frame */
286
+ /* It is expected not to be sent, and will be overwritten by the fifo fill */
287
+ data -> int_data .tx_byte = '\0' ;
288
+ config -> fsp_api -> write (data -> fsp_ctrl , & data -> int_data .tx_byte , 1 );
289
+ }
290
+
291
+ static void uart_rz_scif_irq_tx_disable (const struct device * dev )
292
+ {
293
+ struct uart_rz_scif_data * data = dev -> data ;
294
+
295
+ data -> int_data .irq_tx_enable = false;
296
+ }
297
+
298
+ static int uart_rz_scif_irq_tx_ready (const struct device * dev )
299
+ {
300
+ struct uart_rz_scif_data * data = dev -> data ;
301
+
302
+ return data -> int_data .irq_tx_enable ;
303
+ }
304
+
305
+ static int uart_rz_scif_irq_rx_ready (const struct device * dev )
306
+ {
307
+ struct uart_rz_scif_data * data = dev -> data ;
308
+
309
+ return data -> int_data .rx_fifo_busy && data -> int_data .irq_rx_enable ;
310
+ }
311
+
312
+ static int uart_rz_scif_irq_is_pending (const struct device * dev )
313
+ {
314
+ return (uart_rz_scif_irq_tx_ready (dev )) || (uart_rz_scif_irq_rx_ready (dev ));
315
+ }
316
+
317
+ static void uart_rz_scif_irq_callback_set (const struct device * dev ,
318
+ uart_irq_callback_user_data_t cb , void * cb_data )
319
+ {
320
+ struct uart_rz_scif_data * data = dev -> data ;
321
+
322
+ data -> callback = cb ;
323
+ data -> callback_data = cb_data ;
324
+ }
325
+
326
+ static int uart_rz_scif_irq_update (const struct device * dev )
327
+ {
328
+ ARG_UNUSED (dev );
329
+ return 1 ;
330
+ }
331
+
332
+ static void uart_rz_scif_rxi_isr (const struct device * dev )
333
+ {
334
+ struct uart_rz_scif_data * data = dev -> data ;
335
+
336
+ data -> int_data .rxi_flag = true;
337
+ data -> int_data .rx_fifo_busy = true;
338
+ if (data -> callback ) {
339
+ data -> callback (dev , data -> callback_data );
340
+ }
341
+ }
342
+
343
+ static void uart_rz_scif_txi_isr (const struct device * dev )
344
+ {
345
+ struct uart_rz_scif_data * data = dev -> data ;
346
+
347
+ data -> int_data .tei_flag = false;
348
+ if (data -> callback ) {
349
+ data -> callback (dev , data -> callback_data );
350
+ }
351
+ }
352
+
353
+ static void uart_rz_scif_tei_isr (const struct device * dev )
354
+ {
355
+ struct uart_rz_scif_data * data = dev -> data ;
356
+
357
+ if (data -> int_data .tei_flag ) {
358
+ scif_uart_tei_isr ();
359
+ } else {
360
+ data -> int_data .rxi_flag = false;
361
+ data -> int_data .rx_fifo_busy = true;
362
+ if (data -> callback ) {
363
+ data -> callback (dev , data -> callback_data );
364
+ }
365
+ }
366
+ }
367
+
368
+ static void uart_rz_scif_eri_isr (const struct device * dev )
369
+ {
370
+ scif_uart_eri_isr ();
371
+ }
372
+
373
+ static void uart_rz_scif_bri_isr (const struct device * dev )
374
+ {
375
+ scif_uart_bri_isr ();
376
+ }
377
+
378
+ static void uart_rz_scif_event_handler (uart_callback_args_t * p_args )
379
+ {
380
+ const struct device * dev = (const struct device * )p_args -> p_context ;
381
+ struct uart_rz_scif_data * data = dev -> data ;
382
+
383
+ data -> int_data .event = p_args -> event ;
384
+ switch (p_args -> event ) {
385
+ case UART_EVENT_RX_CHAR :
386
+ data -> int_data .rx_byte = p_args -> data ;
387
+ break ;
388
+ case UART_EVENT_RX_COMPLETE :
389
+ break ;
390
+ case UART_EVENT_TX_DATA_EMPTY :
391
+ data -> int_data .tei_flag = true;
392
+ break ;
393
+ case UART_EVENT_TX_COMPLETE :
394
+ data -> int_data .tei_flag = false;
395
+ break ;
396
+ default :
397
+ break ;
398
+ }
399
+ }
400
+
401
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
402
+
200
403
static DEVICE_API (uart , uart_rz_scif_driver_api ) = {
201
404
.poll_in = uart_rz_scif_poll_in ,
202
405
.poll_out = uart_rz_scif_poll_out ,
@@ -205,6 +408,19 @@ static DEVICE_API(uart, uart_rz_scif_driver_api) = {
205
408
.configure = uart_rz_scif_configure ,
206
409
.config_get = uart_rz_scif_config_get ,
207
410
#endif
411
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
412
+ .fifo_fill = uart_rz_scif_fifo_fill ,
413
+ .fifo_read = uart_rz_scif_fifo_read ,
414
+ .irq_rx_enable = uart_rz_scif_irq_rx_enable ,
415
+ .irq_rx_disable = uart_rz_scif_irq_rx_disable ,
416
+ .irq_tx_enable = uart_rz_scif_irq_tx_enable ,
417
+ .irq_tx_disable = uart_rz_scif_irq_tx_disable ,
418
+ .irq_tx_ready = uart_rz_scif_irq_tx_ready ,
419
+ .irq_rx_ready = uart_rz_scif_irq_rx_ready ,
420
+ .irq_is_pending = uart_rz_scif_irq_is_pending ,
421
+ .irq_callback_set = uart_rz_scif_irq_callback_set ,
422
+ .irq_update = uart_rz_scif_irq_update ,
423
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
208
424
};
209
425
210
426
static int uart_rz_scif_init (const struct device * dev )
@@ -227,14 +443,24 @@ static int uart_rz_scif_init(const struct device *dev)
227
443
228
444
config -> fsp_api -> open (data -> fsp_ctrl , data -> fsp_cfg );
229
445
230
- R_SCIFA0_Type * reg = data -> fsp_ctrl -> p_reg ;
231
- /* Temporarily disable the DRI interrupt caused by receive data ready */
232
- /* TODO: support interrupt-driven api */
233
- reg -> SCR_b .RIE = 0 ;
234
-
235
446
return 0 ;
236
447
}
237
448
449
+ #define UART_RZG_IRQ_CONNECT (n , irq_name , isr ) \
450
+ do { \
451
+ IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, irq_name, irq), \
452
+ DT_INST_IRQ_BY_NAME(n, irq_name, priority), isr, \
453
+ DEVICE_DT_INST_GET(n), 0); \
454
+ irq_enable(DT_INST_IRQ_BY_NAME(n, irq_name, irq)); \
455
+ } while (0)
456
+
457
+ #define UART_RZG_CONFIG_FUNC (n ) \
458
+ UART_RZG_IRQ_CONNECT(n, eri, uart_rz_scif_eri_isr); \
459
+ UART_RZG_IRQ_CONNECT(n, rxi, uart_rz_scif_rxi_isr); \
460
+ UART_RZG_IRQ_CONNECT(n, txi, uart_rz_scif_txi_isr); \
461
+ UART_RZG_IRQ_CONNECT(n, tei, uart_rz_scif_tei_isr); \
462
+ UART_RZG_IRQ_CONNECT(n, bri, uart_rz_scif_bri_isr);
463
+
238
464
#define UART_RZG_INIT (n ) \
239
465
static scif_uart_instance_ctrl_t g_uart##n##_ctrl; \
240
466
static scif_baud_setting_t g_uart##n##_baud_setting; \
@@ -258,8 +484,6 @@ static int uart_rz_scif_init(const struct device *dev)
258
484
}; \
259
485
static uart_cfg_t g_uart##n##_cfg = { \
260
486
.channel = DT_INST_PROP(n, channel), \
261
- .p_callback = NULL, \
262
- .p_context = NULL, \
263
487
.p_extend = &g_uart##n##_cfg_extend, \
264
488
.p_transfer_tx = NULL, \
265
489
.p_transfer_rx = NULL, \
@@ -271,10 +495,14 @@ static int uart_rz_scif_init(const struct device *dev)
271
495
.txi_irq = DT_INST_IRQ_BY_NAME(n, txi, irq), \
272
496
.tei_irq = DT_INST_IRQ_BY_NAME(n, tei, irq), \
273
497
.eri_irq = DT_INST_IRQ_BY_NAME(n, eri, irq), \
274
- }; \
498
+ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( \
499
+ .p_callback = uart_rz_scif_event_handler, \
500
+ .p_context = (void *)DEVICE_DT_INST_GET(n),)) }; \
275
501
PINCTRL_DT_INST_DEFINE(n); \
276
502
static const struct uart_rz_scif_config uart_rz_scif_config_##n = { \
277
- .pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n), .fsp_api = &g_uart_on_scif}; \
503
+ .pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
504
+ .fsp_api = &g_uart_on_scif, \
505
+ }; \
278
506
static struct uart_rz_scif_data uart_rz_scif_data_##n = { \
279
507
.uart_config = \
280
508
{ \
@@ -290,6 +518,8 @@ static int uart_rz_scif_init(const struct device *dev)
290
518
}; \
291
519
static int uart_rz_scif_init_##n(const struct device *dev) \
292
520
{ \
521
+ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
522
+ (UART_RZG_CONFIG_FUNC(n);)) \
293
523
return uart_rz_scif_init(dev); \
294
524
} \
295
525
DEVICE_DT_INST_DEFINE(n, &uart_rz_scif_init_##n, NULL, &uart_rz_scif_data_##n, \
0 commit comments