88#include <zephyr/drivers/pinctrl.h>
99#include <zephyr/drivers/uart.h>
1010#include <zephyr/logging/log.h>
11+ #include <zephyr/irq.h>
1112#include "r_scif_uart.h"
1213
1314LOG_MODULE_REGISTER (rz_scif_uart );
@@ -17,12 +18,36 @@ struct uart_rz_scif_config {
1718 const uart_api_t * fsp_api ;
1819};
1920
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+
2032struct uart_rz_scif_data {
2133 struct uart_config uart_config ;
2234 uart_cfg_t * fsp_cfg ;
35+ struct uart_rz_scif_int int_data ;
2336 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
2441};
2542
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+
2651static int uart_rz_scif_poll_in (const struct device * dev , unsigned char * c )
2752{
2853 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)
4166{
4267 struct uart_rz_scif_data * data = dev -> data ;
4368 R_SCIFA0_Type * reg = data -> fsp_ctrl -> p_reg ;
69+ uint8_t key ;
70+
71+ key = irq_lock ();
4472
4573 while (!reg -> FSR_b .TDFE ) {
4674 }
@@ -49,28 +77,27 @@ static void uart_rz_scif_poll_out(const struct device *dev, unsigned char c)
4977
5078 while (!reg -> FSR_b .TEND ) {
5179 }
80+
81+ irq_unlock (key );
5282}
5383
5484static int uart_rz_scif_err_check (const struct device * dev )
5585{
5686 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 ;
5889
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 ;
6592 }
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 ;
6895 }
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 ;
7198 }
7299
73- return errors ;
100+ return err ;
74101}
75102
76103static 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
179206 return - EIO ;
180207 }
181208
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-
187209 return err ;
188210}
189211
@@ -197,6 +219,187 @@ static int uart_rz_scif_config_get(const struct device *dev, struct uart_config
197219
198220#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
199221
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+
200403static DEVICE_API (uart , uart_rz_scif_driver_api ) = {
201404 .poll_in = uart_rz_scif_poll_in ,
202405 .poll_out = uart_rz_scif_poll_out ,
@@ -205,6 +408,19 @@ static DEVICE_API(uart, uart_rz_scif_driver_api) = {
205408 .configure = uart_rz_scif_configure ,
206409 .config_get = uart_rz_scif_config_get ,
207410#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 */
208424};
209425
210426static int uart_rz_scif_init (const struct device * dev )
@@ -227,14 +443,24 @@ static int uart_rz_scif_init(const struct device *dev)
227443
228444 config -> fsp_api -> open (data -> fsp_ctrl , data -> fsp_cfg );
229445
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-
235446 return 0 ;
236447}
237448
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+
238464#define UART_RZG_INIT (n ) \
239465 static scif_uart_instance_ctrl_t g_uart##n##_ctrl; \
240466 static scif_baud_setting_t g_uart##n##_baud_setting; \
@@ -258,8 +484,6 @@ static int uart_rz_scif_init(const struct device *dev)
258484 }; \
259485 static uart_cfg_t g_uart##n##_cfg = { \
260486 .channel = DT_INST_PROP(n, channel), \
261- .p_callback = NULL, \
262- .p_context = NULL, \
263487 .p_extend = &g_uart##n##_cfg_extend, \
264488 .p_transfer_tx = NULL, \
265489 .p_transfer_rx = NULL, \
@@ -271,10 +495,14 @@ static int uart_rz_scif_init(const struct device *dev)
271495 .txi_irq = DT_INST_IRQ_BY_NAME(n, txi, irq), \
272496 .tei_irq = DT_INST_IRQ_BY_NAME(n, tei, irq), \
273497 .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),)) }; \
275501 PINCTRL_DT_INST_DEFINE(n); \
276502 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+ }; \
278506 static struct uart_rz_scif_data uart_rz_scif_data_##n = { \
279507 .uart_config = \
280508 { \
@@ -290,6 +518,8 @@ static int uart_rz_scif_init(const struct device *dev)
290518 }; \
291519 static int uart_rz_scif_init_##n(const struct device *dev) \
292520 { \
521+ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
522+ (UART_RZG_CONFIG_FUNC(n);)) \
293523 return uart_rz_scif_init(dev); \
294524 } \
295525 DEVICE_DT_INST_DEFINE(n, &uart_rz_scif_init_##n, NULL, &uart_rz_scif_data_##n, \
0 commit comments