Skip to content

Commit 9eda50d

Browse files
committed
drivers: serial: sf32lb: add uart interrupt support
add sf32lb52x uart interrupt support Signed-off-by: Qingsong Gou <gouqs@hotmail.com>
1 parent 9dfac5a commit 9eda50d

File tree

2 files changed

+193
-2
lines changed

2 files changed

+193
-2
lines changed

drivers/serial/Kconfig.sf32lb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ config UART_SF32LB
66
default y
77
depends on DT_HAS_SIFLI_SF32LB_USART_ENABLED
88
select SERIAL_HAS_DRIVER
9+
select SERIAL_SUPPORT_INTERRUPT
910
select PINCTRL
1011
select CLOCK_CONTROL
1112
help

drivers/serial/uart_sf32lb.c

Lines changed: 192 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) Core Devices LLC
3+
* Copyright (c) Qingsong Gou <gouqs@hotmail.com>
34
* SPDX-License-Identifier: Apache-2.0
45
*/
56

@@ -11,6 +12,7 @@
1112
#include <zephyr/drivers/clock_control/sf32lb.h>
1213
#include <zephyr/drivers/pinctrl.h>
1314
#include <zephyr/drivers/uart.h>
15+
#include <zephyr/irq.h>
1416

1517
#include <register.h>
1618

@@ -35,11 +37,21 @@
3537
/* minimal BRR: INT=1, FRAC=0 (0x10) */
3638
#define UART_BRR_MIN 0x10U
3739

40+
struct uart_sf32lb_data {
41+
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
42+
uart_irq_callback_user_data_t irq_callback;
43+
void *cb_data;
44+
#endif
45+
};
46+
3847
struct uart_sf32lb_config {
3948
uintptr_t base;
4049
const struct pinctrl_dev_config *pcfg;
4150
struct sf32lb_clock_dt_spec clock;
4251
struct uart_config uart_cfg;
52+
#if CONFIG_UART_INTERRUPT_DRIVEN
53+
void (*irq_config_func)(const struct device *dev);
54+
#endif
4355
};
4456

4557
static int uart_sf32lb_configure(const struct device *dev, const struct uart_config *cfg)
@@ -177,9 +189,146 @@ static void uart_sf32lb_poll_out(const struct device *dev, uint8_t c)
177189
}
178190
}
179191

192+
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
193+
static int uart_sf32lb_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
194+
{
195+
struct uart_sf32lb_data *data = dev->data;
196+
int i;
197+
198+
for (i = 0; i < len; i++) {
199+
if (__HAL_UART_GET_FLAG(&data->handle, UART_FLAG_TXE) == RESET) {
200+
break;
201+
}
202+
__HAL_UART_PUTC(&data->handle, tx_data[i]);
203+
}
204+
205+
return i;
206+
}
207+
208+
static int uart_sf32lb_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
209+
{
210+
struct uart_sf32lb_data *data = dev->data;
211+
int i;
212+
213+
for (i = 0; i < size; i++) {
214+
if (__HAL_UART_GET_FLAG(&data->handle, UART_FLAG_RXNE) == RESET) {
215+
break;
216+
}
217+
rx_data[i] = __HAL_UART_GETC(&data->handle);
218+
}
219+
220+
return i;
221+
}
222+
223+
static void uart_sf32lb_irq_tx_enable(const struct device *dev)
224+
{
225+
struct uart_sf32lb_data *data = dev->data;
226+
227+
__HAL_UART_ENABLE_IT(&data->handle, UART_IT_TXE);
228+
}
229+
230+
static void uart_sf32lb_irq_tx_disable(const struct device *dev)
231+
{
232+
struct uart_sf32lb_data *data = dev->data;
233+
234+
__HAL_UART_DISABLE_IT(&data->handle, UART_IT_TXE);
235+
}
236+
237+
static int uart_sf32lb_irq_tx_ready(const struct device *dev)
238+
{
239+
struct uart_sf32lb_data *data = dev->data;
240+
241+
return __HAL_UART_GET_FLAG(&data->handle, UART_FLAG_TXE);
242+
}
243+
244+
static int uart_sf32lb_irq_tx_complete(const struct device *dev)
245+
{
246+
struct uart_sf32lb_data *data = dev->data;
247+
248+
return __HAL_UART_GET_FLAG(&data->handle, UART_FLAG_TC);
249+
}
250+
251+
static int uart_sf32lb_irq_rx_full(const struct device *dev)
252+
{
253+
struct uart_sf32lb_data *data = dev->data;
254+
255+
return __HAL_UART_GET_FLAG(&data->handle, UART_FLAG_RXNE);
256+
}
257+
258+
static void uart_sf32lb_irq_err_enable(const struct device *dev)
259+
{
260+
struct uart_sf32lb_data *data = dev->data;
261+
262+
__HAL_UART_ENABLE_IT(&data->handle, UART_IT_PE);
263+
__HAL_UART_ENABLE_IT(&data->handle, UART_IT_ERR);
264+
}
265+
266+
static void uart_sf32lb_irq_err_disable(const struct device *dev)
267+
{
268+
struct uart_sf32lb_data *data = dev->data;
269+
270+
__HAL_UART_DISABLE_IT(&data->handle, UART_IT_PE);
271+
__HAL_UART_DISABLE_IT(&data->handle, UART_IT_ERR);
272+
}
273+
274+
static int uart_sf32lb_irq_is_pending(const struct device *dev)
275+
{
276+
struct uart_sf32lb_data *data = dev->data;
277+
278+
return ((__HAL_UART_GET_FLAG(&data->handle, UART_FLAG_RXNE) &&
279+
__HAL_UART_GET_IT_SOURCE(&data->handle, UART_IT_RXNE)) ||
280+
(__HAL_UART_GET_FLAG(&data->handle, UART_FLAG_TXE) &&
281+
__HAL_UART_GET_IT_SOURCE(&data->handle, UART_IT_TXE)));
282+
}
283+
284+
static int uart_sf32lb_irq_update(const struct device *dev)
285+
{
286+
return 1;
287+
}
288+
289+
static void uart_sf32lb_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb,
290+
void *user_data)
291+
{
292+
struct uart_sf32lb_data *data = dev->data;
293+
294+
data->irq_callback = cb;
295+
data->cb_data = user_data;
296+
}
297+
298+
static void uart_sf32lb_irq_rx_enable(const struct device *dev)
299+
{
300+
struct uart_sf32lb_data *data = dev->data;
301+
302+
__HAL_UART_ENABLE_IT(&data->handle, UART_IT_RXNE);
303+
}
304+
305+
static void uart_sf32lb_irq_rx_disable(const struct device *dev)
306+
{
307+
struct uart_sf32lb_data *data = dev->data;
308+
309+
__HAL_UART_DISABLE_IT(&data->handle, UART_IT_RXNE);
310+
}
311+
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
312+
180313
static const struct uart_driver_api uart_sf32lb_api = {
181314
.poll_in = uart_sf32lb_poll_in,
182315
.poll_out = uart_sf32lb_poll_out,
316+
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
317+
.fifo_fill = uart_sf32lb_fifo_fill,
318+
.fifo_read = uart_sf32lb_fifo_read,
319+
.irq_tx_enable = uart_sf32lb_irq_tx_enable,
320+
.irq_tx_disable = uart_sf32lb_irq_tx_disable,
321+
.irq_tx_complete = uart_sf32lb_irq_tx_complete,
322+
.irq_tx_ready = uart_sf32lb_irq_tx_ready,
323+
.irq_rx_enable = uart_sf32lb_irq_rx_enable,
324+
.irq_rx_disable = uart_sf32lb_irq_rx_disable,
325+
.irq_rx_ready = uart_sf32lb_irq_rx_full,
326+
.irq_err_enable = uart_sf32lb_irq_err_enable,
327+
.irq_err_disable = uart_sf32lb_irq_err_disable,
328+
.irq_is_pending = uart_sf32lb_irq_is_pending,
329+
.irq_update = uart_sf32lb_irq_update,
330+
.irq_callback_set = uart_sf32lb_irq_callback_set,
331+
#endif
183332
};
184333

185334
static int uart_sf32lb_init(const struct device *dev)
@@ -208,10 +357,45 @@ static int uart_sf32lb_init(const struct device *dev)
208357
return ret;
209358
}
210359

360+
#if CONFIG_UART_INTERRUPT_DRIVEN
361+
config->irq_config_func(dev);
362+
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
363+
211364
return 0;
212365
}
213366

367+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
368+
static void uart_sf32lb_isr(const struct device *dev)
369+
{
370+
struct uart_sf32lb_data *data = dev->data;
371+
372+
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
373+
if (data->irq_callback) {
374+
data->irq_callback(dev, data->cb_data);
375+
}
376+
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
377+
}
378+
379+
#define SF32LB_UART_IRQ_HANDLER_DECL(index) \
380+
static void uart_sf32lb_irq_config_func_##index(const struct device *dev);
381+
382+
#define SF32LB_UART_IRQ_HANDLER(index) \
383+
static void uart_sf32lb_irq_config_func_##index(const struct device *dev) \
384+
{ \
385+
IRQ_CONNECT(DT_INST_IRQN(index), DT_INST_IRQ(index, priority), uart_sf32lb_isr, \
386+
DEVICE_DT_INST_GET(index), 0); \
387+
irq_enable(DT_INST_IRQN(index)); \
388+
}
389+
390+
#define SF32LB_UART_IRQ_HANDLER_FUNC(index) .irq_config_func = uart_sf32lb_irq_config_func_##index,
391+
#else
392+
#define SF32LB_UART_IRQ_HANDLER_DECL(index)
393+
#define SF32LB_UART_IRQ_HANDLER(index)
394+
#define SF32LB_UART_IRQ_HANDLER_FUNC(index)
395+
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
396+
214397
#define SF32LB_UART_DEFINE(index) \
398+
SF32LB_UART_IRQ_HANDLER_DECL(index) \
215399
PINCTRL_DT_INST_DEFINE(index); \
216400
\
217401
static const struct uart_sf32lb_config uart_sf32lb_cfg_##index = { \
@@ -231,9 +415,15 @@ static int uart_sf32lb_init(const struct device *dev)
231415
? UART_CFG_FLOW_CTRL_RTS_CTS \
232416
: UART_CFG_FLOW_CTRL_NONE, \
233417
}, \
418+
SF32LB_UART_IRQ_HANDLER_FUNC(index) \
234419
}; \
235420
\
236-
DEVICE_DT_INST_DEFINE(index, uart_sf32lb_init, NULL, NULL, &uart_sf32lb_cfg_##index, \
237-
PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, &uart_sf32lb_api);
421+
static struct uart_sf32lb_data uart_sf32lb_data_##index; \
422+
\
423+
DEVICE_DT_INST_DEFINE(index, uart_sf32lb_init, NULL, \
424+
&uart_sf32lb_data_##index, &uart_sf32lb_cfg_##index, PRE_KERNEL_1, \
425+
CONFIG_SERIAL_INIT_PRIORITY, &uart_sf32lb_api); \
426+
\
427+
SF32LB_UART_IRQ_HANDLER(index)
238428

239429
DT_INST_FOREACH_STATUS_OKAY(SF32LB_UART_DEFINE)

0 commit comments

Comments
 (0)