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
35
37
/* minimal BRR: INT=1, FRAC=0 (0x10) */
36
38
#define UART_BRR_MIN 0x10U
37
39
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
+
38
47
struct uart_sf32lb_config {
39
48
uintptr_t base ;
40
49
const struct pinctrl_dev_config * pcfg ;
41
50
struct sf32lb_clock_dt_spec clock ;
42
51
struct uart_config uart_cfg ;
52
+ #if CONFIG_UART_INTERRUPT_DRIVEN
53
+ void (* irq_config_func )(const struct device * dev );
54
+ #endif
43
55
};
44
56
45
57
static int uart_sf32lb_configure (const struct device * dev , const struct uart_config * cfg )
@@ -177,9 +189,143 @@ static void uart_sf32lb_poll_out(const struct device *dev, uint8_t c)
177
189
}
178
190
}
179
191
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
+ const struct uart_sf32lb_config * config = dev -> config ;
196
+ int i ;
197
+
198
+ for (i = 0 ; i < len ; i ++ ) {
199
+ if ((sys_read32 (config -> base + UART_ISR ) & USART_ISR_TXE ) == 0U ) {
200
+ break ;
201
+ }
202
+ sys_write8 (tx_data [i ], config -> base + UART_TDR );
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
+ const struct uart_sf32lb_config * config = dev -> config ;
211
+ int i ;
212
+
213
+ for (i = 0 ; i < size ; i ++ ) {
214
+ if ((sys_read32 (config -> base + UART_ISR ) & USART_ISR_RXNE ) == 0U ) {
215
+ break ;
216
+ }
217
+ rx_data [i ] = sys_read32 (config -> base + UART_RDR ) & 0xFF ;
218
+ }
219
+
220
+ return i ;
221
+ }
222
+
223
+ static void uart_sf32lb_irq_tx_enable (const struct device * dev )
224
+ {
225
+ const struct uart_sf32lb_config * config = dev -> config ;
226
+
227
+ sys_set_bit (config -> base + UART_CR1 , USART_CR1_TE_Pos );
228
+ }
229
+
230
+ static void uart_sf32lb_irq_tx_disable (const struct device * dev )
231
+ {
232
+ const struct uart_sf32lb_config * config = dev -> config ;
233
+
234
+ sys_clear_bit (config -> base + UART_CR1 , USART_CR1_TE_Pos );
235
+ }
236
+
237
+ static int uart_sf32lb_irq_tx_ready (const struct device * dev )
238
+ {
239
+ const struct uart_sf32lb_config * config = dev -> config ;
240
+
241
+ return ((sys_read32 (config -> base + UART_ISR ) & USART_ISR_TXE ) == USART_ISR_TXE );
242
+ }
243
+
244
+ static int uart_sf32lb_irq_tx_complete (const struct device * dev )
245
+ {
246
+ const struct uart_sf32lb_config * config = dev -> config ;
247
+
248
+ return ((sys_read32 (config -> base + UART_ISR ) & USART_ISR_TC ) == USART_ISR_TC );
249
+ }
250
+
251
+ static int uart_sf32lb_irq_rx_ready (const struct device * dev )
252
+ {
253
+ const struct uart_sf32lb_config * config = dev -> config ;
254
+
255
+ return ((sys_read32 (config -> base + UART_ISR ) & USART_ISR_RXNE ) == USART_ISR_RXNE );
256
+ }
257
+
258
+ static void uart_sf32lb_irq_err_enable (const struct device * dev )
259
+ {
260
+ const struct uart_sf32lb_config * config = dev -> config ;
261
+
262
+ sys_set_bit (config -> base + UART_CR1 , USART_CR1_PEIE_Pos );
263
+ sys_set_bit (config -> base + UART_CR3 , USART_CR3_EIE_Pos );
264
+ }
265
+
266
+ static void uart_sf32lb_irq_err_disable (const struct device * dev )
267
+ {
268
+ const struct uart_sf32lb_config * config = dev -> config ;
269
+
270
+ sys_clear_bit (config -> base + UART_CR1 , USART_CR1_PEIE_Pos );
271
+ sys_clear_bit (config -> base + UART_CR3 , USART_CR3_EIE_Pos );
272
+ }
273
+
274
+ static int uart_sf32lb_irq_is_pending (const struct device * dev )
275
+ {
276
+ const struct uart_sf32lb_config * config = dev -> config ;
277
+
278
+ return sys_read32 (config -> base + UART_ISR );
279
+ }
280
+
281
+ static int uart_sf32lb_irq_update (const struct device * dev )
282
+ {
283
+ return 1 ;
284
+ }
285
+
286
+ static void uart_sf32lb_irq_callback_set (const struct device * dev , uart_irq_callback_user_data_t cb ,
287
+ void * user_data )
288
+ {
289
+ struct uart_sf32lb_data * data = dev -> data ;
290
+
291
+ data -> irq_callback = cb ;
292
+ data -> cb_data = user_data ;
293
+ }
294
+
295
+ static void uart_sf32lb_irq_rx_enable (const struct device * dev )
296
+ {
297
+ const struct uart_sf32lb_config * config = dev -> config ;
298
+
299
+ sys_set_bit (config -> base + UART_CR3 , USART_ISR_RXNE );
300
+ }
301
+
302
+ static void uart_sf32lb_irq_rx_disable (const struct device * dev )
303
+ {
304
+ const struct uart_sf32lb_config * config = dev -> config ;
305
+
306
+ sys_clear_bit (config -> base + UART_CR3 , USART_ISR_RXNE );
307
+ }
308
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
309
+
180
310
static const struct uart_driver_api uart_sf32lb_api = {
181
311
.poll_in = uart_sf32lb_poll_in ,
182
312
.poll_out = uart_sf32lb_poll_out ,
313
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
314
+ .fifo_fill = uart_sf32lb_fifo_fill ,
315
+ .fifo_read = uart_sf32lb_fifo_read ,
316
+ .irq_tx_enable = uart_sf32lb_irq_tx_enable ,
317
+ .irq_tx_disable = uart_sf32lb_irq_tx_disable ,
318
+ .irq_tx_complete = uart_sf32lb_irq_tx_complete ,
319
+ .irq_tx_ready = uart_sf32lb_irq_tx_ready ,
320
+ .irq_rx_enable = uart_sf32lb_irq_rx_enable ,
321
+ .irq_rx_disable = uart_sf32lb_irq_rx_disable ,
322
+ .irq_rx_ready = uart_sf32lb_irq_rx_ready ,
323
+ .irq_err_enable = uart_sf32lb_irq_err_enable ,
324
+ .irq_err_disable = uart_sf32lb_irq_err_disable ,
325
+ .irq_is_pending = uart_sf32lb_irq_is_pending ,
326
+ .irq_update = uart_sf32lb_irq_update ,
327
+ .irq_callback_set = uart_sf32lb_irq_callback_set ,
328
+ #endif
183
329
};
184
330
185
331
static int uart_sf32lb_init (const struct device * dev )
@@ -208,10 +354,45 @@ static int uart_sf32lb_init(const struct device *dev)
208
354
return ret ;
209
355
}
210
356
357
+ #if CONFIG_UART_INTERRUPT_DRIVEN
358
+ config -> irq_config_func (dev );
359
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
360
+
211
361
return 0 ;
212
362
}
213
363
364
+ #if defined(CONFIG_UART_INTERRUPT_DRIVEN )
365
+ static void uart_sf32lb_isr (const struct device * dev )
366
+ {
367
+ struct uart_sf32lb_data * data = dev -> data ;
368
+
369
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
370
+ if (data -> irq_callback ) {
371
+ data -> irq_callback (dev , data -> cb_data );
372
+ }
373
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
374
+ }
375
+
376
+ #define SF32LB_UART_IRQ_HANDLER_DECL (index ) \
377
+ static void uart_sf32lb_irq_config_func_##index(const struct device *dev);
378
+
379
+ #define SF32LB_UART_IRQ_HANDLER (index ) \
380
+ static void uart_sf32lb_irq_config_func_##index(const struct device *dev) \
381
+ { \
382
+ IRQ_CONNECT(DT_INST_IRQN(index), DT_INST_IRQ(index, priority), uart_sf32lb_isr, \
383
+ DEVICE_DT_INST_GET(index), 0); \
384
+ irq_enable(DT_INST_IRQN(index)); \
385
+ }
386
+
387
+ #define SF32LB_UART_IRQ_HANDLER_FUNC (index ) .irq_config_func = uart_sf32lb_irq_config_func_##index,
388
+ #else
389
+ #define SF32LB_UART_IRQ_HANDLER_DECL (index )
390
+ #define SF32LB_UART_IRQ_HANDLER (index )
391
+ #define SF32LB_UART_IRQ_HANDLER_FUNC (index )
392
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
393
+
214
394
#define SF32LB_UART_DEFINE (index ) \
395
+ SF32LB_UART_IRQ_HANDLER_DECL(index) \
215
396
PINCTRL_DT_INST_DEFINE(index); \
216
397
\
217
398
static const struct uart_sf32lb_config uart_sf32lb_cfg_##index = { \
@@ -231,9 +412,15 @@ static int uart_sf32lb_init(const struct device *dev)
231
412
? UART_CFG_FLOW_CTRL_RTS_CTS \
232
413
: UART_CFG_FLOW_CTRL_NONE, \
233
414
}, \
415
+ SF32LB_UART_IRQ_HANDLER_FUNC(index) \
234
416
}; \
235
417
\
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);
418
+ static struct uart_sf32lb_data uart_sf32lb_data_##index; \
419
+ \
420
+ DEVICE_DT_INST_DEFINE(index, uart_sf32lb_init, NULL, \
421
+ &uart_sf32lb_data_##index, &uart_sf32lb_cfg_##index, PRE_KERNEL_1, \
422
+ CONFIG_SERIAL_INIT_PRIORITY, &uart_sf32lb_api); \
423
+ \
424
+ SF32LB_UART_IRQ_HANDLER(index)
238
425
239
426
DT_INST_FOREACH_STATUS_OKAY (SF32LB_UART_DEFINE )
0 commit comments