1 /*
2 * Copyright (c) 2016 Piotr Mienkowski
3 * Copyright (c) 2018 Justin Watson
4 * Copyright (c) 2023 Gerson Fernando Budke
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT atmel_sam_usart
9
10 /** @file
11 * @brief USART driver for Atmel SAM MCU family.
12 */
13
14 #include <errno.h>
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/device.h>
17 #include <zephyr/init.h>
18 #include <soc.h>
19 #include <zephyr/drivers/uart.h>
20 #include <zephyr/drivers/pinctrl.h>
21 #include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
22 #include <zephyr/irq.h>
23
24 /* Device constant configuration parameters */
25 struct usart_sam_dev_cfg {
26 Usart *regs;
27 const struct atmel_sam_pmc_config clock_cfg;
28 const struct pinctrl_dev_config *pcfg;
29 bool hw_flow_control;
30
31 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
32 uart_irq_config_func_t irq_config_func;
33 #endif
34 };
35
36 /* Device run time data */
37 struct usart_sam_dev_data {
38 uint32_t baud_rate;
39
40 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
41 uart_irq_callback_user_data_t irq_cb; /* Interrupt Callback */
42 void *cb_data; /* Interrupt Callback Arg */
43 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
44 };
45
usart_sam_poll_in(const struct device * dev,unsigned char * c)46 static int usart_sam_poll_in(const struct device *dev, unsigned char *c)
47 {
48 const struct usart_sam_dev_cfg *config = dev->config;
49
50 Usart * const usart = config->regs;
51
52 if (!(usart->US_CSR & US_CSR_RXRDY)) {
53 return -1;
54 }
55
56 /* got a character */
57 *c = (unsigned char)usart->US_RHR;
58
59 return 0;
60 }
61
usart_sam_poll_out(const struct device * dev,unsigned char c)62 static void usart_sam_poll_out(const struct device *dev, unsigned char c)
63 {
64 const struct usart_sam_dev_cfg *config = dev->config;
65
66 Usart * const usart = config->regs;
67
68 /* Wait for transmitter to be ready */
69 while (!(usart->US_CSR & US_CSR_TXRDY)) {
70 }
71
72 /* send a character */
73 usart->US_THR = (uint32_t)c;
74 }
75
usart_sam_err_check(const struct device * dev)76 static int usart_sam_err_check(const struct device *dev)
77 {
78 const struct usart_sam_dev_cfg *config = dev->config;
79
80 volatile Usart * const usart = config->regs;
81 int errors = 0;
82
83 if (usart->US_CSR & US_CSR_OVRE) {
84 errors |= UART_ERROR_OVERRUN;
85 }
86
87 if (usart->US_CSR & US_CSR_PARE) {
88 errors |= UART_ERROR_PARITY;
89 }
90
91 if (usart->US_CSR & US_CSR_FRAME) {
92 errors |= UART_ERROR_FRAMING;
93 }
94
95 return errors;
96 }
97
usart_sam_baudrate_set(const struct device * dev,uint32_t baudrate)98 static int usart_sam_baudrate_set(const struct device *dev, uint32_t baudrate)
99 {
100 struct usart_sam_dev_data *const dev_data = dev->data;
101
102 const struct usart_sam_dev_cfg *const config = dev->config;
103
104 volatile Usart * const usart = config->regs;
105
106 uint32_t divisor;
107
108 __ASSERT(baudrate,
109 "baud rate has to be bigger than 0");
110 __ASSERT(SOC_ATMEL_SAM_MCK_FREQ_HZ/16U >= baudrate,
111 "MCK frequency is too small to set required baud rate");
112
113 divisor = SOC_ATMEL_SAM_MCK_FREQ_HZ / 16U / baudrate;
114
115 if (divisor > 0xFFFF) {
116 return -EINVAL;
117 }
118
119 usart->US_BRGR = US_BRGR_CD(divisor);
120 dev_data->baud_rate = baudrate;
121
122 return 0;
123 }
124
usart_sam_cfg2sam_parity(uint8_t parity)125 static uint32_t usart_sam_cfg2sam_parity(uint8_t parity)
126 {
127 switch (parity) {
128 case UART_CFG_PARITY_EVEN:
129 return US_MR_PAR_EVEN;
130 case UART_CFG_PARITY_ODD:
131 return US_MR_PAR_ODD;
132 case UART_CFG_PARITY_SPACE:
133 return US_MR_PAR_SPACE;
134 case UART_CFG_PARITY_MARK:
135 return US_MR_PAR_MARK;
136 case UART_CFG_PARITY_NONE:
137 default:
138 return US_MR_PAR_NO;
139 }
140 }
141
usart_sam_get_parity(const struct device * dev)142 static uint8_t usart_sam_get_parity(const struct device *dev)
143 {
144 const struct usart_sam_dev_cfg *const config = dev->config;
145
146 volatile Usart * const usart = config->regs;
147
148 switch (usart->US_MR & US_MR_PAR_Msk) {
149 case US_MR_PAR_EVEN:
150 return UART_CFG_PARITY_EVEN;
151 case US_MR_PAR_ODD:
152 return UART_CFG_PARITY_ODD;
153 case US_MR_PAR_SPACE:
154 return UART_CFG_PARITY_SPACE;
155 case US_MR_PAR_MARK:
156 return UART_CFG_PARITY_MARK;
157 case US_MR_PAR_NO:
158 default:
159 return UART_CFG_PARITY_NONE;
160 }
161 }
162
usart_sam_cfg2sam_stop_bits(uint8_t stop_bits)163 static uint32_t usart_sam_cfg2sam_stop_bits(uint8_t stop_bits)
164 {
165 switch (stop_bits) {
166 case UART_CFG_STOP_BITS_1_5:
167 return US_MR_NBSTOP_1_5_BIT;
168 case UART_CFG_STOP_BITS_2:
169 return US_MR_NBSTOP_2_BIT;
170 case UART_CFG_STOP_BITS_1:
171 default:
172 return US_MR_NBSTOP_1_BIT;
173 }
174 }
175
usart_sam_get_stop_bits(const struct device * dev)176 static uint8_t usart_sam_get_stop_bits(const struct device *dev)
177 {
178 const struct usart_sam_dev_cfg *const config = dev->config;
179
180 volatile Usart * const usart = config->regs;
181
182 switch (usart->US_MR & US_MR_NBSTOP_Msk) {
183 case US_MR_NBSTOP_1_5_BIT:
184 return UART_CFG_STOP_BITS_1_5;
185 case US_MR_NBSTOP_2_BIT:
186 return UART_CFG_STOP_BITS_2;
187 case US_MR_NBSTOP_1_BIT:
188 default:
189 return UART_CFG_STOP_BITS_1;
190 }
191 }
192
usart_sam_cfg2sam_data_bits(uint8_t data_bits)193 static uint32_t usart_sam_cfg2sam_data_bits(uint8_t data_bits)
194 {
195 switch (data_bits) {
196 case UART_CFG_DATA_BITS_5:
197 return US_MR_CHRL_5_BIT;
198 case UART_CFG_DATA_BITS_6:
199 return US_MR_CHRL_6_BIT;
200 case UART_CFG_DATA_BITS_7:
201 return US_MR_CHRL_7_BIT;
202 case UART_CFG_DATA_BITS_8:
203 default:
204 return US_MR_CHRL_8_BIT;
205 }
206 }
207
usart_sam_get_data_bits(const struct device * dev)208 static uint8_t usart_sam_get_data_bits(const struct device *dev)
209 {
210 const struct usart_sam_dev_cfg *const config = dev->config;
211
212 volatile Usart * const usart = config->regs;
213
214 switch (usart->US_MR & US_MR_CHRL_Msk) {
215 case US_MR_CHRL_5_BIT:
216 return UART_CFG_DATA_BITS_5;
217 case US_MR_CHRL_6_BIT:
218 return UART_CFG_DATA_BITS_6;
219 case US_MR_CHRL_7_BIT:
220 return UART_CFG_DATA_BITS_7;
221 case US_MR_CHRL_8_BIT:
222 default:
223 return UART_CFG_DATA_BITS_8;
224 }
225 }
226
usart_sam_cfg2sam_flow_ctrl(uint8_t flow_ctrl)227 static uint32_t usart_sam_cfg2sam_flow_ctrl(uint8_t flow_ctrl)
228 {
229 switch (flow_ctrl) {
230 case UART_CFG_FLOW_CTRL_RTS_CTS:
231 return US_MR_USART_MODE_HW_HANDSHAKING;
232 case UART_CFG_FLOW_CTRL_NONE:
233 default:
234 return US_MR_USART_MODE_NORMAL;
235 }
236 }
237
usart_sam_get_flow_ctrl(const struct device * dev)238 static uint8_t usart_sam_get_flow_ctrl(const struct device *dev)
239 {
240 const struct usart_sam_dev_cfg *const config = dev->config;
241
242 volatile Usart * const usart = config->regs;
243
244 switch (usart->US_MR & US_MR_USART_MODE_Msk) {
245 case US_MR_USART_MODE_HW_HANDSHAKING:
246 return UART_CFG_FLOW_CTRL_RTS_CTS;
247 case US_MR_USART_MODE_NORMAL:
248 default:
249 return UART_CFG_FLOW_CTRL_NONE;
250 }
251 }
252
usart_sam_configure(const struct device * dev,const struct uart_config * cfg)253 static int usart_sam_configure(const struct device *dev,
254 const struct uart_config *cfg)
255 {
256 int retval;
257
258 const struct usart_sam_dev_cfg *const config = dev->config;
259
260 volatile Usart * const usart = config->regs;
261
262 /* Driver doesn't support 9 data bits, 0.5 stop bits, or DTR DSR flow control */
263 if (cfg->data_bits == UART_CFG_DATA_BITS_9 ||
264 cfg->stop_bits == UART_CFG_STOP_BITS_0_5 ||
265 cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR) {
266 return -ENOTSUP;
267 }
268
269 /* Reset and disable USART */
270 usart->US_CR = US_CR_RSTRX | US_CR_RSTTX
271 | US_CR_RXDIS | US_CR_TXDIS
272 | US_CR_RSTSTA;
273
274 /* normal UART mode, baud rate driven by peripheral clock, all
275 * other values chosen by config
276 */
277 usart->US_MR = US_MR_CHMODE_NORMAL
278 | US_MR_USCLKS_MCK
279 | usart_sam_cfg2sam_parity(cfg->parity)
280 | usart_sam_cfg2sam_stop_bits(cfg->stop_bits)
281 | usart_sam_cfg2sam_data_bits(cfg->data_bits)
282 | usart_sam_cfg2sam_flow_ctrl(cfg->flow_ctrl);
283
284 /* Set baud rate */
285 retval = usart_sam_baudrate_set(dev, cfg->baudrate);
286 if (retval != 0) {
287 return retval;
288 }
289
290 /* Enable receiver and transmitter */
291 usart->US_CR = US_CR_RXEN | US_CR_TXEN;
292
293 return 0;
294 }
295
usart_sam_config_get(const struct device * dev,struct uart_config * cfg)296 static int usart_sam_config_get(const struct device *dev,
297 struct uart_config *cfg)
298 {
299 struct usart_sam_dev_data *const dev_data = dev->data;
300
301 cfg->baudrate = dev_data->baud_rate;
302 cfg->parity = usart_sam_get_parity(dev);
303 cfg->stop_bits = usart_sam_get_stop_bits(dev);
304 cfg->data_bits = usart_sam_get_data_bits(dev);
305 cfg->flow_ctrl = usart_sam_get_flow_ctrl(dev);
306
307 return 0;
308 }
309
310 #if CONFIG_UART_INTERRUPT_DRIVEN
311
usart_sam_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)312 static int usart_sam_fifo_fill(const struct device *dev,
313 const uint8_t *tx_data,
314 int size)
315 {
316 const struct usart_sam_dev_cfg *config = dev->config;
317
318 volatile Usart * const usart = config->regs;
319
320 /* Wait for transmitter to be ready. */
321 while ((usart->US_CSR & US_CSR_TXRDY) == 0) {
322 }
323
324 usart->US_THR = *tx_data;
325
326 return 1;
327 }
328
usart_sam_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)329 static int usart_sam_fifo_read(const struct device *dev, uint8_t *rx_data,
330 const int size)
331 {
332 const struct usart_sam_dev_cfg *config = dev->config;
333
334 volatile Usart * const usart = config->regs;
335 int bytes_read;
336
337 bytes_read = 0;
338
339 while (bytes_read < size) {
340 if (usart->US_CSR & US_CSR_RXRDY) {
341 rx_data[bytes_read] = usart->US_RHR;
342 bytes_read++;
343 } else {
344 break;
345 }
346 }
347
348 return bytes_read;
349 }
350
usart_sam_irq_tx_enable(const struct device * dev)351 static void usart_sam_irq_tx_enable(const struct device *dev)
352 {
353 const struct usart_sam_dev_cfg *config = dev->config;
354
355 volatile Usart * const usart = config->regs;
356
357 usart->US_IER = US_IER_TXRDY;
358 }
359
usart_sam_irq_tx_disable(const struct device * dev)360 static void usart_sam_irq_tx_disable(const struct device *dev)
361 {
362 const struct usart_sam_dev_cfg *config = dev->config;
363
364 volatile Usart * const usart = config->regs;
365
366 usart->US_IDR = US_IDR_TXRDY;
367 }
368
usart_sam_irq_tx_ready(const struct device * dev)369 static int usart_sam_irq_tx_ready(const struct device *dev)
370 {
371 const struct usart_sam_dev_cfg *config = dev->config;
372
373 volatile Usart * const usart = config->regs;
374
375 /* Check that the transmitter is ready but only
376 * return true if the interrupt is also enabled
377 */
378 return (usart->US_CSR & US_CSR_TXRDY &&
379 usart->US_IMR & US_IMR_TXRDY);
380 }
381
usart_sam_irq_rx_enable(const struct device * dev)382 static void usart_sam_irq_rx_enable(const struct device *dev)
383 {
384 const struct usart_sam_dev_cfg *config = dev->config;
385
386 volatile Usart * const usart = config->regs;
387
388 usart->US_IER = US_IER_RXRDY;
389 }
390
usart_sam_irq_rx_disable(const struct device * dev)391 static void usart_sam_irq_rx_disable(const struct device *dev)
392 {
393 const struct usart_sam_dev_cfg *config = dev->config;
394
395 volatile Usart * const usart = config->regs;
396
397 usart->US_IDR = US_IDR_RXRDY;
398 }
399
usart_sam_irq_tx_complete(const struct device * dev)400 static int usart_sam_irq_tx_complete(const struct device *dev)
401 {
402 const struct usart_sam_dev_cfg *config = dev->config;
403
404 volatile Usart * const usart = config->regs;
405
406 return (usart->US_CSR & US_CSR_TXRDY &&
407 usart->US_CSR & US_CSR_TXEMPTY);
408 }
409
usart_sam_irq_rx_ready(const struct device * dev)410 static int usart_sam_irq_rx_ready(const struct device *dev)
411 {
412 const struct usart_sam_dev_cfg *config = dev->config;
413
414 volatile Usart * const usart = config->regs;
415
416 return (usart->US_CSR & US_CSR_RXRDY);
417 }
418
usart_sam_irq_err_enable(const struct device * dev)419 static void usart_sam_irq_err_enable(const struct device *dev)
420 {
421 const struct usart_sam_dev_cfg *config = dev->config;
422
423 volatile Usart * const usart = config->regs;
424
425 usart->US_IER = US_IER_OVRE | US_IER_FRAME | US_IER_PARE;
426 }
427
usart_sam_irq_err_disable(const struct device * dev)428 static void usart_sam_irq_err_disable(const struct device *dev)
429 {
430 const struct usart_sam_dev_cfg *config = dev->config;
431
432 volatile Usart * const usart = config->regs;
433
434 usart->US_IDR = US_IDR_OVRE | US_IDR_FRAME | US_IDR_PARE;
435 }
436
usart_sam_irq_is_pending(const struct device * dev)437 static int usart_sam_irq_is_pending(const struct device *dev)
438 {
439 const struct usart_sam_dev_cfg *config = dev->config;
440
441 volatile Usart * const usart = config->regs;
442
443 return (usart->US_IMR & (US_IMR_TXRDY | US_IMR_RXRDY)) &
444 (usart->US_CSR & (US_CSR_TXRDY | US_CSR_RXRDY));
445 }
446
usart_sam_irq_update(const struct device * dev)447 static int usart_sam_irq_update(const struct device *dev)
448 {
449 ARG_UNUSED(dev);
450
451 return 1;
452 }
453
usart_sam_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)454 static void usart_sam_irq_callback_set(const struct device *dev,
455 uart_irq_callback_user_data_t cb,
456 void *cb_data)
457 {
458 struct usart_sam_dev_data *const dev_data = dev->data;
459
460 dev_data->irq_cb = cb;
461 dev_data->cb_data = cb_data;
462 }
463
usart_sam_isr(const struct device * dev)464 static void usart_sam_isr(const struct device *dev)
465 {
466 struct usart_sam_dev_data *const dev_data = dev->data;
467
468 if (dev_data->irq_cb) {
469 dev_data->irq_cb(dev, dev_data->cb_data);
470 }
471 }
472
473 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
474
usart_sam_init(const struct device * dev)475 static int usart_sam_init(const struct device *dev)
476 {
477 int retval;
478
479 const struct usart_sam_dev_cfg *const cfg = dev->config;
480
481 struct usart_sam_dev_data *const dev_data = dev->data;
482
483 Usart * const usart = cfg->regs;
484
485 /* Enable USART clock in PMC */
486 (void)clock_control_on(SAM_DT_PMC_CONTROLLER,
487 (clock_control_subsys_t)&cfg->clock_cfg);
488
489 /* Connect pins to the peripheral */
490 retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
491 if (retval < 0) {
492 return retval;
493 }
494
495 /* Disable Interrupts */
496 usart->US_IDR = 0xFFFFFFFF;
497
498 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
499 cfg->irq_config_func(dev);
500 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
501
502 struct uart_config uart_config = {
503 .baudrate = dev_data->baud_rate,
504 .parity = UART_CFG_PARITY_NONE,
505 .stop_bits = UART_CFG_STOP_BITS_1,
506 .data_bits = UART_CFG_DATA_BITS_8,
507 .flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
508 };
509 if (cfg->hw_flow_control) {
510 uart_config.flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS;
511 }
512 return usart_sam_configure(dev, &uart_config);
513 }
514
515 static DEVICE_API(uart, usart_sam_driver_api) = {
516 .poll_in = usart_sam_poll_in,
517 .poll_out = usart_sam_poll_out,
518 .err_check = usart_sam_err_check,
519 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
520 .configure = usart_sam_configure,
521 .config_get = usart_sam_config_get,
522 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
523 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
524 .fifo_fill = usart_sam_fifo_fill,
525 .fifo_read = usart_sam_fifo_read,
526 .irq_tx_enable = usart_sam_irq_tx_enable,
527 .irq_tx_disable = usart_sam_irq_tx_disable,
528 .irq_tx_ready = usart_sam_irq_tx_ready,
529 .irq_rx_enable = usart_sam_irq_rx_enable,
530 .irq_rx_disable = usart_sam_irq_rx_disable,
531 .irq_tx_complete = usart_sam_irq_tx_complete,
532 .irq_rx_ready = usart_sam_irq_rx_ready,
533 .irq_err_enable = usart_sam_irq_err_enable,
534 .irq_err_disable = usart_sam_irq_err_disable,
535 .irq_is_pending = usart_sam_irq_is_pending,
536 .irq_update = usart_sam_irq_update,
537 .irq_callback_set = usart_sam_irq_callback_set,
538 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
539 };
540
541 #define USART_SAM_DECLARE_CFG(n, IRQ_FUNC_INIT) \
542 static const struct usart_sam_dev_cfg usart##n##_sam_config = { \
543 .regs = (Usart *)DT_INST_REG_ADDR(n), \
544 .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n), \
545 .hw_flow_control = DT_INST_PROP(n, hw_flow_control), \
546 \
547 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
548 \
549 IRQ_FUNC_INIT \
550 }
551
552 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
553 #define USART_SAM_CONFIG_FUNC(n) \
554 static void usart##n##_sam_irq_config_func(const struct device *port) \
555 { \
556 IRQ_CONNECT(DT_INST_IRQN(n), \
557 DT_INST_IRQ(n, priority), \
558 usart_sam_isr, \
559 DEVICE_DT_INST_GET(n), 0); \
560 irq_enable(DT_INST_IRQN(n)); \
561 }
562 #define USART_SAM_IRQ_CFG_FUNC_INIT(n) \
563 .irq_config_func = usart##n##_sam_irq_config_func
564 #define USART_SAM_INIT_CFG(n) \
565 USART_SAM_DECLARE_CFG(n, USART_SAM_IRQ_CFG_FUNC_INIT(n))
566 #else
567 #define USART_SAM_CONFIG_FUNC(n)
568 #define USART_SAM_IRQ_CFG_FUNC_INIT
569 #define USART_SAM_INIT_CFG(n) \
570 USART_SAM_DECLARE_CFG(n, USART_SAM_IRQ_CFG_FUNC_INIT)
571 #endif
572
573 #define USART_SAM_INIT(n) \
574 PINCTRL_DT_INST_DEFINE(n); \
575 static struct usart_sam_dev_data usart##n##_sam_data = { \
576 .baud_rate = DT_INST_PROP(n, current_speed), \
577 }; \
578 \
579 static const struct usart_sam_dev_cfg usart##n##_sam_config; \
580 \
581 DEVICE_DT_INST_DEFINE(n, \
582 usart_sam_init, NULL, \
583 &usart##n##_sam_data, \
584 &usart##n##_sam_config, PRE_KERNEL_1, \
585 CONFIG_SERIAL_INIT_PRIORITY, \
586 &usart_sam_driver_api); \
587 \
588 USART_SAM_CONFIG_FUNC(n) \
589 \
590 USART_SAM_INIT_CFG(n);
591
592 DT_INST_FOREACH_STATUS_OKAY(USART_SAM_INIT)
593