1
1
/*
2
2
* Copyright (c) Core Devices LLC
3
+ * Copyright (c) Qingsong Gou <gouqs@hotmail.com>
3
4
* SPDX-License-Identifier: Apache-2.0
4
5
*/
5
6
11
12
#include <zephyr/drivers/clock_control/sf32lb.h>
12
13
#include <zephyr/drivers/pinctrl.h>
13
14
#include <zephyr/drivers/uart.h>
15
+ #include <zephyr/irq.h>
14
16
15
17
#include <register.h>
16
18
32
34
#define UART_CR2_STOP_1B FIELD_PREP(USART_CR2_STOP_Msk, 0U)
33
35
#define UART_CR2_STOP_2B FIELD_PREP(USART_CR2_STOP_Msk, 1U)
34
36
37
+ #define UART_FLAG_IS_SET (reg , flag ) \
38
+ sys_test_bit(reg, flag)
39
+
40
+ #define UART_FLAG_CLEAR (reg , flag ) \
41
+ sys_clear_bit(reg, flag)
42
+
35
43
/* minimal BRR: INT=1, FRAC=0 (0x10) */
36
44
#define UART_BRR_MIN 0x10U
37
45
46
+ struct uart_sf32lb_data {
47
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
48
+ uart_irq_callback_user_data_t irq_callback ;
49
+ void * cb_data ;
50
+ #endif
51
+ };
52
+
38
53
struct uart_sf32lb_config {
39
54
uintptr_t base ;
40
55
const struct pinctrl_dev_config * pcfg ;
41
56
struct sf32lb_clock_dt_spec clock ;
42
57
struct uart_config uart_cfg ;
58
+ #if CONFIG_UART_INTERRUPT_DRIVEN
59
+ void (* irq_config_func )(const struct device * dev );
60
+ #endif
43
61
};
44
62
63
+ #if defined(CONFIG_UART_INTERRUPT_DRIVEN )
64
+ static void uart_sf32lb_isr (const struct device * dev )
65
+ {
66
+ const struct uart_sf32lb_config * config = dev -> config ;
67
+ struct uart_sf32lb_data * data = dev -> data ;
68
+
69
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
70
+ if (data -> irq_callback ) {
71
+ data -> irq_callback (dev , data -> cb_data );
72
+ }
73
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
74
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_ORE_Pos )) {
75
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ICR_ORECF_Pos );
76
+ }
77
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_NF_Pos )) {
78
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ICR_NCF_Pos );
79
+ }
80
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_FE_Pos )) {
81
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ICR_FECF_Pos );
82
+ }
83
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_PE_Pos )) {
84
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ICR_PECF_Pos );
85
+ }
86
+
87
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_CTS_Pos )) {
88
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ISR_CTS_Pos );
89
+ }
90
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_TXE_Pos )) {
91
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ISR_TXE_Pos );
92
+ }
93
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_TC_Pos )) {
94
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ISR_TC_Pos );
95
+ }
96
+ if (UART_FLAG_IS_SET (config -> base + UART_ISR , USART_ISR_RXNE_Pos )) {
97
+ UART_FLAG_CLEAR (config -> base + UART_ICR , USART_ISR_RXNE_Pos );
98
+ }
99
+ }
100
+ #endif
101
+
45
102
static int uart_sf32lb_configure (const struct device * dev , const struct uart_config * cfg )
46
103
{
47
104
const struct uart_sf32lb_config * config = dev -> config ;
@@ -177,9 +234,144 @@ static void uart_sf32lb_poll_out(const struct device *dev, uint8_t c)
177
234
}
178
235
}
179
236
237
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
238
+ static int uart_sf32lb_fifo_fill (const struct device * dev , const uint8_t * tx_data , int len )
239
+ {
240
+ const struct uart_sf32lb_config * config = dev -> config ;
241
+ int i ;
242
+
243
+ for (i = 0 ; i < len ; i ++ ) {
244
+ if (!sys_test_bit (config -> base + UART_ISR , USART_ISR_TXE_Pos )) {
245
+ break ;
246
+ }
247
+ sys_write8 (tx_data [i ], config -> base + UART_TDR );
248
+ }
249
+
250
+ return i ;
251
+ }
252
+
253
+ static int uart_sf32lb_fifo_read (const struct device * dev , uint8_t * rx_data , const int size )
254
+ {
255
+ const struct uart_sf32lb_config * config = dev -> config ;
256
+ int i ;
257
+
258
+ for (i = 0 ; i < size ; i ++ ) {
259
+ if (!sys_test_bit (config -> base + UART_ISR , USART_ISR_RXNE_Pos )) {
260
+ break ;
261
+ }
262
+ rx_data [i ] = sys_read8 (config -> base + UART_RDR );
263
+ }
264
+
265
+ return i ;
266
+ }
267
+
268
+ static void uart_sf32lb_irq_tx_enable (const struct device * dev )
269
+ {
270
+ const struct uart_sf32lb_config * config = dev -> config ;
271
+
272
+ sys_set_bit (config -> base + UART_CR1 , USART_CR1_TE_Pos );
273
+ }
274
+
275
+ static void uart_sf32lb_irq_tx_disable (const struct device * dev )
276
+ {
277
+ const struct uart_sf32lb_config * config = dev -> config ;
278
+
279
+ sys_clear_bit (config -> base + UART_CR1 , USART_CR1_TE_Pos );
280
+ }
281
+
282
+ static int uart_sf32lb_irq_tx_ready (const struct device * dev )
283
+ {
284
+ const struct uart_sf32lb_config * config = dev -> config ;
285
+
286
+ return sys_test_bit (config -> base + UART_ISR , USART_ISR_TXE_Pos );
287
+ }
288
+
289
+ static int uart_sf32lb_irq_tx_complete (const struct device * dev )
290
+ {
291
+ const struct uart_sf32lb_config * config = dev -> config ;
292
+
293
+ return sys_test_bit (config -> base + UART_ISR , USART_ISR_TC_Pos );
294
+ }
295
+
296
+ static int uart_sf32lb_irq_rx_ready (const struct device * dev )
297
+ {
298
+ const struct uart_sf32lb_config * config = dev -> config ;
299
+
300
+ return sys_test_bit (config -> base + UART_ISR , USART_ISR_RXNE_Pos );
301
+ }
302
+
303
+ static void uart_sf32lb_irq_err_enable (const struct device * dev )
304
+ {
305
+ const struct uart_sf32lb_config * config = dev -> config ;
306
+
307
+ sys_set_bit (config -> base + UART_CR1 , USART_CR1_PEIE_Pos );
308
+ sys_set_bit (config -> base + UART_CR3 , USART_CR3_EIE_Pos );
309
+ }
310
+
311
+ static void uart_sf32lb_irq_err_disable (const struct device * dev )
312
+ {
313
+ const struct uart_sf32lb_config * config = dev -> config ;
314
+
315
+ sys_clear_bit (config -> base + UART_CR1 , USART_CR1_PEIE_Pos );
316
+ sys_clear_bit (config -> base + UART_CR3 , USART_CR3_EIE_Pos );
317
+ }
318
+
319
+ static int uart_sf32lb_irq_is_pending (const struct device * dev )
320
+ {
321
+ const struct uart_sf32lb_config * config = dev -> config ;
322
+
323
+ return sys_read32 (config -> base + UART_ISR ) == 0U ? 0 : 1 ;
324
+ }
325
+
326
+ static int uart_sf32lb_irq_update (const struct device * dev )
327
+ {
328
+ ARG_UNUSED (dev );
329
+ return 1 ;
330
+ }
331
+
332
+ static void uart_sf32lb_irq_callback_set (const struct device * dev , uart_irq_callback_user_data_t cb ,
333
+ void * user_data )
334
+ {
335
+ struct uart_sf32lb_data * data = dev -> data ;
336
+
337
+ data -> irq_callback = cb ;
338
+ data -> cb_data = user_data ;
339
+ }
340
+
341
+ static void uart_sf32lb_irq_rx_enable (const struct device * dev )
342
+ {
343
+ const struct uart_sf32lb_config * config = dev -> config ;
344
+
345
+ sys_set_bit (config -> base + UART_CR3 , USART_ISR_RXNE );
346
+ }
347
+
348
+ static void uart_sf32lb_irq_rx_disable (const struct device * dev )
349
+ {
350
+ const struct uart_sf32lb_config * config = dev -> config ;
351
+
352
+ sys_clear_bit (config -> base + UART_CR3 , USART_ISR_RXNE );
353
+ }
354
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
355
+
180
356
static const struct uart_driver_api uart_sf32lb_api = {
181
357
.poll_in = uart_sf32lb_poll_in ,
182
358
.poll_out = uart_sf32lb_poll_out ,
359
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
360
+ .fifo_fill = uart_sf32lb_fifo_fill ,
361
+ .fifo_read = uart_sf32lb_fifo_read ,
362
+ .irq_tx_enable = uart_sf32lb_irq_tx_enable ,
363
+ .irq_tx_disable = uart_sf32lb_irq_tx_disable ,
364
+ .irq_tx_complete = uart_sf32lb_irq_tx_complete ,
365
+ .irq_tx_ready = uart_sf32lb_irq_tx_ready ,
366
+ .irq_rx_enable = uart_sf32lb_irq_rx_enable ,
367
+ .irq_rx_disable = uart_sf32lb_irq_rx_disable ,
368
+ .irq_rx_ready = uart_sf32lb_irq_rx_ready ,
369
+ .irq_err_enable = uart_sf32lb_irq_err_enable ,
370
+ .irq_err_disable = uart_sf32lb_irq_err_disable ,
371
+ .irq_is_pending = uart_sf32lb_irq_is_pending ,
372
+ .irq_update = uart_sf32lb_irq_update ,
373
+ .irq_callback_set = uart_sf32lb_irq_callback_set ,
374
+ #endif
183
375
};
184
376
185
377
static int uart_sf32lb_init (const struct device * dev )
@@ -208,11 +400,22 @@ static int uart_sf32lb_init(const struct device *dev)
208
400
return ret ;
209
401
}
210
402
403
+ #if CONFIG_UART_INTERRUPT_DRIVEN
404
+ config -> irq_config_func (dev );
405
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
406
+
211
407
return 0 ;
212
408
}
213
409
214
410
#define SF32LB_UART_DEFINE (index ) \
215
411
PINCTRL_DT_INST_DEFINE(index); \
412
+ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
413
+ (static void uart_sf32lb_irq_config_func_##index(const struct device *dev) \
414
+ { \
415
+ IRQ_CONNECT(DT_INST_IRQN(index), DT_INST_IRQ(index, priority), uart_sf32lb_isr, \
416
+ DEVICE_DT_INST_GET(index), 0); \
417
+ irq_enable(DT_INST_IRQN(index)); \
418
+ })); \
216
419
\
217
420
static const struct uart_sf32lb_config uart_sf32lb_cfg_##index = { \
218
421
.base = DT_INST_REG_ADDR(index), \
@@ -231,9 +434,14 @@ static int uart_sf32lb_init(const struct device *dev)
231
434
? UART_CFG_FLOW_CTRL_RTS_CTS \
232
435
: UART_CFG_FLOW_CTRL_NONE, \
233
436
}, \
437
+ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
438
+ (.irq_config_func = uart_sf32lb_irq_config_func_##index,)) \
234
439
}; \
235
440
\
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);
441
+ static struct uart_sf32lb_data uart_sf32lb_data_##index; \
442
+ \
443
+ DEVICE_DT_INST_DEFINE(index, uart_sf32lb_init, NULL, \
444
+ &uart_sf32lb_data_##index, &uart_sf32lb_cfg_##index, PRE_KERNEL_1, \
445
+ CONFIG_SERIAL_INIT_PRIORITY, &uart_sf32lb_api);
238
446
239
447
DT_INST_FOREACH_STATUS_OKAY (SF32LB_UART_DEFINE )
0 commit comments