Skip to content

Commit 64a9d9c

Browse files
committed
drivers: serial: Add support for group interrupt in the serial driver
Apply the grp irq support in serial driver for MCB-RX26T Signed-off-by: Quy Tran <[email protected]>
1 parent 07c0928 commit 64a9d9c

File tree

4 files changed

+257
-19
lines changed

4 files changed

+257
-19
lines changed

boards/renesas/mcb_rx26t/mcb_rx26t_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CONFIG_GPIO=y
66

77
# Enable UART driver
88
CONFIG_SERIAL=y
9-
CONFIG_UART_INTERRUPT_DRIVEN=n
9+
CONFIG_UART_INTERRUPT_DRIVEN=y
1010

1111
# Enable console
1212
CONFIG_CONSOLE=y

drivers/serial/uart_renesas_rx_sci.c

Lines changed: 218 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include <zephyr/irq.h>
1414
#include <zephyr/spinlock.h>
1515

16+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
17+
#include <zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h>
18+
#endif
19+
1620
#include "r_sci_rx_if.h"
1721
#include "iodefine_sci.h"
1822

@@ -33,6 +37,13 @@ LOG_MODULE_REGISTER(rx_uart_sci, CONFIG_UART_LOG_LEVEL);
3337
#define DEV_CFG(dev) ((const struct uart_rx_sci_config *const)(dev)->config)
3438
#define DEV_BASE(dev) (DEV_CFG(dev)->regs)
3539

40+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
41+
#define _SCI_INT_TEI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_TEI##chan
42+
#define SCI_INT_TEI_SRC(chan) _SCI_INT_TEI_SRC(chan)
43+
#define _SCI_INT_ERI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_ERI##chan
44+
#define SCI_INT_ERI_SRC(chan) _SCI_INT_ERI_SRC(chan)
45+
#endif
46+
3647
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
3748
static void uart_rx_sci_txi_isr(const struct device *dev);
3849
#endif
@@ -64,13 +75,117 @@ struct uart_rx_sci_data {
6475
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
6576
uint8_t rxi_irq;
6677
uint8_t txi_irq;
78+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
79+
bsp_int_src_t tei_src;
80+
bsp_int_src_t eri_src;
81+
/* Group interrupt controller for the transmit end interrupt (TEI) */
82+
const struct device *tei_ctrl;
83+
/* Group interrupt number for the transmit end interrupt (TEI) */
84+
uint8_t tei_num;
85+
/* Group interrupt controller for the error interrupt (ERI) */
86+
const struct device *eri_ctrl;
87+
/* Group interrupt number for the error interrupt (ERI) */
88+
uint8_t eri_num;
89+
#else
6790
uint8_t tei_irq;
6891
uint8_t eri_irq;
92+
#endif
6993
uart_irq_callback_user_data_t user_cb;
7094
void *user_cb_data;
7195
#endif
7296
};
7397

98+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API)
99+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
100+
101+
void uart_rx_sci_tei_isr(bsp_int_cb_args_t *p_args)
102+
{
103+
struct device *sci_dev = (struct device *)(p_args->p_context);
104+
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(sci_dev);
105+
106+
/* Disable SCI.SCR.TEIE */
107+
sci->SCR.BIT.TEIE = 0;
108+
109+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
110+
struct uart_rx_sci_data *data = sci_dev->data;
111+
112+
if (data->user_cb != NULL) {
113+
114+
data->user_cb(sci_dev, data->user_cb_data);
115+
}
116+
#endif
117+
}
118+
119+
void uart_rx_sci_eri_isr(bsp_int_cb_args_t *p_args)
120+
{
121+
struct device *sci_dev = (struct device *)(p_args->p_context);
122+
123+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
124+
struct uart_rx_sci_data *data = sci_dev->data;
125+
126+
if (data->user_cb != NULL) {
127+
128+
data->user_cb(sci_dev, data->user_cb_data);
129+
}
130+
#endif
131+
}
132+
133+
static inline int uart_rx_sci_tei_grp_enable(const struct device *dev)
134+
{
135+
struct uart_rx_sci_data *data = dev->data;
136+
int err;
137+
138+
err = rx_grp_intc_set_callback(data->tei_ctrl, (bsp_int_src_t)data->tei_src,
139+
(bsp_int_cb_t)uart_rx_sci_tei_isr, (void *)dev);
140+
if (err != 0) {
141+
LOG_ERR("Failed to set callback for group interrupt TEI: %d", err);
142+
return err;
143+
}
144+
145+
err = rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true);
146+
if (err != 0) {
147+
LOG_ERR("Failed to allow interrupt request for TEI: %d", err);
148+
return err;
149+
}
150+
151+
err = rx_grp_intc_set_grp_int(data->tei_ctrl, (bsp_int_src_t)data->tei_src, true);
152+
if (err != 0) {
153+
LOG_ERR("Failed to enable group interrupt for TEI: %d", err);
154+
return err;
155+
}
156+
157+
return 0;
158+
}
159+
160+
static inline int uart_rx_sci_eri_grp_enable(const struct device *dev)
161+
{
162+
struct uart_rx_sci_data *data = dev->data;
163+
int err;
164+
165+
err = rx_grp_intc_set_callback(data->eri_ctrl, (bsp_int_src_t)data->eri_src,
166+
(bsp_int_cb_t)uart_rx_sci_eri_isr, (void *)dev);
167+
if (err != 0) {
168+
LOG_ERR("Failed to set callback for group interrupt ERI: %d", err);
169+
return err;
170+
}
171+
172+
err = rx_grp_intc_set_gen(data->eri_ctrl, data->eri_num, true);
173+
if (err != 0) {
174+
LOG_ERR("Failed to allow interrupt request for ERI: %d", err);
175+
return err;
176+
}
177+
178+
err = rx_grp_intc_set_grp_int(data->eri_ctrl, (bsp_int_src_t)data->eri_src, true);
179+
if (err != 0) {
180+
LOG_ERR("Failed to enable group interrupt for ERI: %d", err);
181+
return err;
182+
}
183+
184+
return 0;
185+
}
186+
#endif
187+
#endif
188+
74189
static int uart_rx_sci_poll_in(const struct device *dev, unsigned char *c)
75190
{
76191
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
@@ -234,12 +349,24 @@ static int uart_rx_fifo_fill(const struct device *dev, const uint8_t *tx_data, i
234349
{
235350
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
236351
uint8_t num_tx = 0U;
352+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
353+
struct uart_rx_sci_data *data = dev->data;
237354

355+
/* Disable ICU.GEN and SCI.SCR.TEIE*/
356+
rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false);
357+
sci->SCR.BIT.TEIE = 0;
358+
#endif
238359
if (size > 0 && sci->SSR.BIT.TDRE) {
239360
/* Send a character (8bit , parity none) */
240361
sci->TDR = tx_data[num_tx++];
241362
}
242363

364+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
365+
/* Enable ICU.GEN and SCI.SCR.TEIE*/
366+
sci->SCR.BIT.TEIE = 1;
367+
rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true);
368+
#endif
369+
243370
return num_tx;
244371
}
245372

@@ -258,11 +385,21 @@ static int uart_rx_fifo_read(const struct device *dev, uint8_t *rx_data, const i
258385

259386
static void uart_rx_irq_tx_enable(const struct device *dev)
260387
{
261-
struct uart_rx_sci_data *data = dev->data;
262388
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
263-
264389
sci->SCR.BYTE |= (BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos));
390+
391+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
392+
/* Allows the interrupt request for the tei interrupt */
393+
int err = uart_rx_sci_tei_grp_enable(dev);
394+
395+
if (err != 0) {
396+
LOG_ERR("Failed to enable group interrupt TEI: %d", err);
397+
return;
398+
}
399+
#else
400+
struct uart_rx_sci_data *data = dev->data;
265401
irq_enable(data->tei_irq);
402+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
266403
if (sci->SSR.BIT.TDRE) {
267404
/* the callback function is usually called from an interrupt,
268405
* preventing other interrupts to be triggered during execution
@@ -278,11 +415,23 @@ static void uart_rx_irq_tx_enable(const struct device *dev)
278415

279416
static void uart_rx_irq_tx_disable(const struct device *dev)
280417
{
281-
struct uart_rx_sci_data *data = dev->data;
282418
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
283419

284420
sci->SCR.BYTE &= ~(BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos));
421+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
422+
struct uart_rx_sci_data *data = dev->data;
423+
int err = 0;
424+
425+
/* Disable the interrupt request for the tei interrupt */
426+
err = rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false);
427+
if (err != 0) {
428+
LOG_ERR("Failed to disable group interrupt TEI: %d", err);
429+
return;
430+
}
431+
#else
432+
struct uart_rx_sci_data *data = dev->data;
285433
irq_disable(data->tei_irq);
434+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
286435
}
287436

288437
static int uart_rx_irq_tx_ready(const struct device *dev)
@@ -305,6 +454,16 @@ static void uart_rx_irq_rx_enable(const struct device *dev)
305454
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
306455

307456
sci->SCR.BIT.RIE = 1U;
457+
458+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
459+
/* Allows the interrupt request for the tei interrupt */
460+
int err = uart_rx_sci_eri_grp_enable(dev);
461+
462+
if (err != 0) {
463+
LOG_ERR("Failed to enable group interrupt ERI: %d", err);
464+
return;
465+
}
466+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
308467
}
309468

310469
static void uart_rx_irq_rx_disable(const struct device *dev)
@@ -323,16 +482,39 @@ static int uart_rx_irq_rx_ready(const struct device *dev)
323482

324483
static void uart_rx_irq_err_enable(const struct device *dev)
325484
{
326-
struct uart_rx_sci_data *data = dev->data;
327485

486+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
487+
struct uart_rx_sci_data *data = dev->data;
328488
irq_enable(data->eri_irq);
489+
#else
490+
/* Allows the interrupt request for the eri interrupt */
491+
int err = uart_rx_sci_eri_grp_enable(dev);
492+
493+
if (err != 0) {
494+
LOG_ERR("Failed to enable group interrupt ERI: %d", err);
495+
return;
496+
}
497+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
329498
}
330499

331500
static void uart_rx_irq_err_disable(const struct device *dev)
332501
{
333-
struct uart_rx_sci_data *data = dev->data;
334502

503+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
504+
struct uart_rx_sci_data *data = dev->data;
335505
irq_disable(data->eri_irq);
506+
507+
#else
508+
/* Disable the interrupt request for the eri interrupt */
509+
struct uart_rx_sci_data *data = dev->data;
510+
int err = 0;
511+
512+
err = rx_grp_intc_set_gen(data->eri_ctrl, data->eri_num, false);
513+
if (err != 0) {
514+
LOG_ERR("Failed to disable interrupt request for ERI: %d", err);
515+
return;
516+
}
517+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
336518
}
337519

338520
static int uart_rx_irq_is_pending(const struct device *dev)
@@ -446,7 +628,7 @@ static void uart_rx_sci_txi_isr(const struct device *dev)
446628
}
447629
#endif
448630

449-
#ifndef CONFIG_SOC_SERIES_RX26T
631+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
450632
static void uart_rx_sci_tei_isr(const struct device *dev)
451633
{
452634
struct uart_rx_sci_data *data = dev->data;
@@ -466,18 +648,8 @@ static void uart_rx_sci_eri_isr(const struct device *dev)
466648
}
467649
#endif
468650

469-
#if defined(CONFIG_SOC_SERIES_RX26T)
470-
#define UART_RX_SCI_CONFIG_INIT(index)
471-
#else
472-
#define UART_RX_SCI_CONFIG_INIT(index) \
473-
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
474-
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
475-
.tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \
476-
.eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq),
477-
#endif
478-
479651
#if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API
480-
#ifndef CONFIG_SOC_SERIES_RX26T
652+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
481653
#define UART_RX_SCI_IRQ_INIT(index) \
482654
do { \
483655
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
@@ -495,11 +667,39 @@ static void uart_rx_sci_eri_isr(const struct device *dev)
495667
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \
496668
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \
497669
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \
498-
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)); \
499670
} while (0)
671+
672+
#define UART_RX_SCI_CONFIG_INIT(index) \
673+
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
674+
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
675+
.tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \
676+
.eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq),
677+
#else
678+
#define UART_RX_SCI_IRQ_INIT(index) \
679+
do { \
680+
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
681+
DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), \
682+
uart_rx_sci_rxi_isr, DEVICE_DT_INST_GET(index), 0); \
683+
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
684+
DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), \
685+
uart_rx_sci_txi_isr, DEVICE_DT_INST_GET(index), 0); \
686+
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \
687+
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \
688+
} while (0)
689+
690+
#define UART_RX_SCI_CONFIG_INIT(index) \
691+
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
692+
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
693+
.tei_src = SCI_INT_TEI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \
694+
.eri_src = SCI_INT_ERI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \
695+
.tei_ctrl = DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(index), tei_ctrl)), \
696+
.tei_num = DT_PROP(DT_INST_PARENT(index), tei_number), \
697+
.eri_ctrl = DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(index), eri_ctrl)), \
698+
.eri_num = DT_PROP(DT_INST_PARENT(index), eri_number),
500699
#endif
501700
#else
502701
#define UART_RX_SCI_IRQ_INIT(index)
702+
#define UART_RX_SCI_CONFIG_INIT(index)
503703
#endif
504704

505705
#define UART_RX_INIT(index) \

dts/bindings/misc/renesas,rx-sci.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,25 @@ properties:
1414
channel:
1515
type: int
1616
required: true
17+
18+
tei-ctrl:
19+
type: phandle
20+
description: |
21+
Group interrupt controller for the transmit end interrupt (TEI). This only applies
22+
in cases the RX MCU supports group interrupt feature
23+
24+
tei-number:
25+
type: int
26+
description: |
27+
Number of the TEI in the interrupt group of tei-ctrl
28+
29+
eri-ctrl:
30+
type: phandle
31+
description: |
32+
Group interrupt controller for the error interrupt (ERI). This only applies
33+
in cases the RX MCU supports group interrupt feature
34+
35+
eri-number:
36+
type: int
37+
description: |
38+
Number of the ERI in the interrupt group of eri-ctrl

0 commit comments

Comments
 (0)