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,146 @@ 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
+ 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
+
180
313
static const struct uart_driver_api uart_sf32lb_api = {
181
314
.poll_in = uart_sf32lb_poll_in ,
182
315
.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
183
332
};
184
333
185
334
static int uart_sf32lb_init (const struct device * dev )
@@ -208,10 +357,45 @@ static int uart_sf32lb_init(const struct device *dev)
208
357
return ret ;
209
358
}
210
359
360
+ #if CONFIG_UART_INTERRUPT_DRIVEN
361
+ config -> irq_config_func (dev );
362
+ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
363
+
211
364
return 0 ;
212
365
}
213
366
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
+
214
397
#define SF32LB_UART_DEFINE (index ) \
398
+ SF32LB_UART_IRQ_HANDLER_DECL(index) \
215
399
PINCTRL_DT_INST_DEFINE(index); \
216
400
\
217
401
static const struct uart_sf32lb_config uart_sf32lb_cfg_##index = { \
@@ -231,9 +415,15 @@ static int uart_sf32lb_init(const struct device *dev)
231
415
? UART_CFG_FLOW_CTRL_RTS_CTS \
232
416
: UART_CFG_FLOW_CTRL_NONE, \
233
417
}, \
418
+ SF32LB_UART_IRQ_HANDLER_FUNC(index) \
234
419
}; \
235
420
\
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)
238
428
239
429
DT_INST_FOREACH_STATUS_OKAY (SF32LB_UART_DEFINE )
0 commit comments