1 /*
2 * Copyright (c) 2017 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_uart
9
10 /** @file
11 * @brief UART 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 uart_sam_dev_cfg {
26 Uart *regs;
27 const struct atmel_sam_pmc_config clock_cfg;
28 const struct pinctrl_dev_config *pcfg;
29
30 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
31 uart_irq_config_func_t irq_config_func;
32 #endif
33 };
34
35 /* Device run time data */
36 struct uart_sam_dev_data {
37 uint32_t baud_rate;
38
39 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
40 uart_irq_callback_user_data_t irq_cb; /* Interrupt Callback */
41 void *irq_cb_data; /* Interrupt Callback Arg */
42 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
43 };
44
uart_sam_poll_in(const struct device * dev,unsigned char * c)45 static int uart_sam_poll_in(const struct device *dev, unsigned char *c)
46 {
47 const struct uart_sam_dev_cfg *const cfg = dev->config;
48
49 Uart * const uart = cfg->regs;
50
51 if (!(uart->UART_SR & UART_SR_RXRDY)) {
52 return -1;
53 }
54
55 /* got a character */
56 *c = (unsigned char)uart->UART_RHR;
57
58 return 0;
59 }
60
uart_sam_poll_out(const struct device * dev,unsigned char c)61 static void uart_sam_poll_out(const struct device *dev, unsigned char c)
62 {
63 const struct uart_sam_dev_cfg *const cfg = dev->config;
64
65 Uart * const uart = cfg->regs;
66
67 /* Wait for transmitter to be ready */
68 while (!(uart->UART_SR & UART_SR_TXRDY)) {
69 }
70
71 /* send a character */
72 uart->UART_THR = (uint32_t)c;
73 }
74
uart_sam_err_check(const struct device * dev)75 static int uart_sam_err_check(const struct device *dev)
76 {
77 const struct uart_sam_dev_cfg *const cfg = dev->config;
78
79 volatile Uart * const uart = cfg->regs;
80 int errors = 0;
81
82 if (uart->UART_SR & UART_SR_OVRE) {
83 errors |= UART_ERROR_OVERRUN;
84 }
85
86 if (uart->UART_SR & UART_SR_PARE) {
87 errors |= UART_ERROR_PARITY;
88 }
89
90 if (uart->UART_SR & UART_SR_FRAME) {
91 errors |= UART_ERROR_FRAMING;
92 }
93
94 uart->UART_CR = UART_CR_RSTSTA;
95
96 return errors;
97 }
98
uart_sam_baudrate_set(const struct device * dev,uint32_t baudrate)99 static int uart_sam_baudrate_set(const struct device *dev, uint32_t baudrate)
100 {
101 struct uart_sam_dev_data *const dev_data = dev->data;
102
103 const struct uart_sam_dev_cfg *const cfg = dev->config;
104
105 volatile Uart * const uart = cfg->regs;
106
107 uint32_t divisor;
108
109 __ASSERT(baudrate,
110 "baud rate has to be bigger than 0");
111 __ASSERT(SOC_ATMEL_SAM_MCK_FREQ_HZ/16U >= baudrate,
112 "MCK frequency is too small to set required baud rate");
113
114 divisor = SOC_ATMEL_SAM_MCK_FREQ_HZ / 16U / baudrate;
115
116 if (divisor > 0xFFFF) {
117 return -EINVAL;
118 }
119
120 uart->UART_BRGR = UART_BRGR_CD(divisor);
121 dev_data->baud_rate = baudrate;
122
123 return 0;
124 }
125
uart_sam_cfg2sam_parity(uint8_t parity)126 static uint32_t uart_sam_cfg2sam_parity(uint8_t parity)
127 {
128 switch (parity) {
129 case UART_CFG_PARITY_EVEN:
130 return UART_MR_PAR_EVEN;
131 case UART_CFG_PARITY_ODD:
132 return UART_MR_PAR_ODD;
133 case UART_CFG_PARITY_SPACE:
134 return UART_MR_PAR_SPACE;
135 case UART_CFG_PARITY_MARK:
136 return UART_MR_PAR_MARK;
137 case UART_CFG_PARITY_NONE:
138 default:
139 return UART_MR_PAR_NO;
140 }
141 }
142
uart_sam_get_parity(const struct device * dev)143 static uint8_t uart_sam_get_parity(const struct device *dev)
144 {
145 const struct uart_sam_dev_cfg *const cfg = dev->config;
146
147 volatile Uart * const uart = cfg->regs;
148
149 switch (uart->UART_MR & UART_MR_PAR_Msk) {
150 case UART_MR_PAR_EVEN:
151 return UART_CFG_PARITY_EVEN;
152 case UART_MR_PAR_ODD:
153 return UART_CFG_PARITY_ODD;
154 case UART_MR_PAR_SPACE:
155 return UART_CFG_PARITY_SPACE;
156 case UART_MR_PAR_MARK:
157 return UART_CFG_PARITY_MARK;
158 case UART_MR_PAR_NO:
159 default:
160 return UART_CFG_PARITY_NONE;
161 }
162 }
163
uart_sam_configure(const struct device * dev,const struct uart_config * cfg)164 static int uart_sam_configure(const struct device *dev,
165 const struct uart_config *cfg)
166 {
167 int retval;
168
169 const struct uart_sam_dev_cfg *const config = dev->config;
170
171 volatile Uart * const uart = config->regs;
172
173 /* Driver only supports 8 data bits, 1 stop bit, and no flow control */
174 if (cfg->stop_bits != UART_CFG_STOP_BITS_1 ||
175 cfg->data_bits != UART_CFG_DATA_BITS_8 ||
176 cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) {
177 return -ENOTSUP;
178 }
179
180 /* Reset and disable UART */
181 uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
182 | UART_CR_RXDIS | UART_CR_TXDIS
183 | UART_CR_RSTSTA;
184
185 /* baud rate driven by the peripheral clock, UART does not filter
186 * the receive line, parity chosen by config
187 */
188 uart->UART_MR = UART_MR_CHMODE_NORMAL
189 | uart_sam_cfg2sam_parity(cfg->parity);
190
191 /* Set baud rate */
192 retval = uart_sam_baudrate_set(dev, cfg->baudrate);
193 if (retval != 0) {
194 return retval;
195 }
196
197 /* Enable receiver and transmitter */
198 uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
199
200 return 0;
201 }
202
uart_sam_config_get(const struct device * dev,struct uart_config * cfg)203 static int uart_sam_config_get(const struct device *dev,
204 struct uart_config *cfg)
205 {
206 struct uart_sam_dev_data *const dev_data = dev->data;
207
208 cfg->baudrate = dev_data->baud_rate;
209 cfg->parity = uart_sam_get_parity(dev);
210 /* only supported mode for this peripheral */
211 cfg->stop_bits = UART_CFG_STOP_BITS_1;
212 cfg->data_bits = UART_CFG_DATA_BITS_8;
213 cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
214
215 return 0;
216 }
217
218 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
219
uart_sam_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)220 static int uart_sam_fifo_fill(const struct device *dev,
221 const uint8_t *tx_data,
222 int size)
223 {
224 const struct uart_sam_dev_cfg *const cfg = dev->config;
225
226 volatile Uart * const uart = cfg->regs;
227
228 /* Wait for transmitter to be ready. */
229 while ((uart->UART_SR & UART_SR_TXRDY) == 0) {
230 }
231
232 uart->UART_THR = *tx_data;
233
234 return 1;
235 }
236
uart_sam_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)237 static int uart_sam_fifo_read(const struct device *dev, uint8_t *rx_data,
238 const int size)
239 {
240 const struct uart_sam_dev_cfg *const cfg = dev->config;
241
242 volatile Uart * const uart = cfg->regs;
243 int bytes_read;
244
245 bytes_read = 0;
246
247 while (bytes_read < size) {
248 if (uart->UART_SR & UART_SR_RXRDY) {
249 rx_data[bytes_read] = uart->UART_RHR;
250 bytes_read++;
251 } else {
252 break;
253 }
254 }
255
256 return bytes_read;
257 }
258
uart_sam_irq_tx_enable(const struct device * dev)259 static void uart_sam_irq_tx_enable(const struct device *dev)
260 {
261 const struct uart_sam_dev_cfg *const cfg = dev->config;
262
263 volatile Uart * const uart = cfg->regs;
264
265 uart->UART_IER = UART_IER_TXRDY;
266 }
267
uart_sam_irq_tx_disable(const struct device * dev)268 static void uart_sam_irq_tx_disable(const struct device *dev)
269 {
270 const struct uart_sam_dev_cfg *const cfg = dev->config;
271
272 volatile Uart * const uart = cfg->regs;
273
274 uart->UART_IDR = UART_IDR_TXRDY;
275 }
276
uart_sam_irq_tx_ready(const struct device * dev)277 static int uart_sam_irq_tx_ready(const struct device *dev)
278 {
279 const struct uart_sam_dev_cfg *const cfg = dev->config;
280
281 volatile Uart * const uart = cfg->regs;
282
283 /* Check that the transmitter is ready but only
284 * return true if the interrupt is also enabled
285 */
286 return (uart->UART_SR & UART_SR_TXRDY &&
287 uart->UART_IMR & UART_IMR_TXRDY);
288 }
289
uart_sam_irq_rx_enable(const struct device * dev)290 static void uart_sam_irq_rx_enable(const struct device *dev)
291 {
292 const struct uart_sam_dev_cfg *const cfg = dev->config;
293
294 volatile Uart * const uart = cfg->regs;
295
296 uart->UART_IER = UART_IER_RXRDY;
297 }
298
uart_sam_irq_rx_disable(const struct device * dev)299 static void uart_sam_irq_rx_disable(const struct device *dev)
300 {
301 const struct uart_sam_dev_cfg *const cfg = dev->config;
302
303 volatile Uart * const uart = cfg->regs;
304
305 uart->UART_IDR = UART_IDR_RXRDY;
306 }
307
uart_sam_irq_tx_complete(const struct device * dev)308 static int uart_sam_irq_tx_complete(const struct device *dev)
309 {
310 const struct uart_sam_dev_cfg *const cfg = dev->config;
311
312 volatile Uart * const uart = cfg->regs;
313
314 return (uart->UART_SR & UART_SR_TXRDY &&
315 uart->UART_IMR & UART_IMR_TXEMPTY);
316 }
317
uart_sam_irq_rx_ready(const struct device * dev)318 static int uart_sam_irq_rx_ready(const struct device *dev)
319 {
320 const struct uart_sam_dev_cfg *const cfg = dev->config;
321
322 volatile Uart * const uart = cfg->regs;
323
324 return (uart->UART_SR & UART_SR_RXRDY);
325 }
326
uart_sam_irq_err_enable(const struct device * dev)327 static void uart_sam_irq_err_enable(const struct device *dev)
328 {
329 const struct uart_sam_dev_cfg *const cfg = dev->config;
330
331 volatile Uart * const uart = cfg->regs;
332
333 uart->UART_IER = UART_IER_OVRE | UART_IER_FRAME | UART_IER_PARE;
334 }
335
uart_sam_irq_err_disable(const struct device * dev)336 static void uart_sam_irq_err_disable(const struct device *dev)
337 {
338 const struct uart_sam_dev_cfg *const cfg = dev->config;
339
340 volatile Uart * const uart = cfg->regs;
341
342 uart->UART_IDR = UART_IDR_OVRE | UART_IDR_FRAME | UART_IDR_PARE;
343 }
344
uart_sam_irq_is_pending(const struct device * dev)345 static int uart_sam_irq_is_pending(const struct device *dev)
346 {
347 const struct uart_sam_dev_cfg *const cfg = dev->config;
348
349 volatile Uart * const uart = cfg->regs;
350
351 return (uart->UART_IMR & (UART_IMR_TXRDY | UART_IMR_RXRDY)) &
352 (uart->UART_SR & (UART_SR_TXRDY | UART_SR_RXRDY));
353 }
354
uart_sam_irq_update(const struct device * dev)355 static int uart_sam_irq_update(const struct device *dev)
356 {
357 ARG_UNUSED(dev);
358
359 return 1;
360 }
361
uart_sam_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)362 static void uart_sam_irq_callback_set(const struct device *dev,
363 uart_irq_callback_user_data_t cb,
364 void *cb_data)
365 {
366 struct uart_sam_dev_data *const dev_data = dev->data;
367
368 dev_data->irq_cb = cb;
369 dev_data->irq_cb_data = cb_data;
370 }
371
uart_sam_isr(const struct device * dev)372 static void uart_sam_isr(const struct device *dev)
373 {
374 struct uart_sam_dev_data *const dev_data = dev->data;
375
376 if (dev_data->irq_cb) {
377 dev_data->irq_cb(dev, dev_data->irq_cb_data);
378 }
379 }
380
381 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
382
uart_sam_init(const struct device * dev)383 static int uart_sam_init(const struct device *dev)
384 {
385 int retval;
386
387 const struct uart_sam_dev_cfg *const cfg = dev->config;
388
389 struct uart_sam_dev_data *const dev_data = dev->data;
390
391 Uart * const uart = cfg->regs;
392
393 /* Enable UART clock in PMC */
394 (void)clock_control_on(SAM_DT_PMC_CONTROLLER,
395 (clock_control_subsys_t)&cfg->clock_cfg);
396
397 /* Connect pins to the peripheral */
398 retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
399 if (retval < 0) {
400 return retval;
401 }
402
403 /* Disable Interrupts */
404 uart->UART_IDR = 0xFFFFFFFF;
405
406 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
407 cfg->irq_config_func(dev);
408 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
409
410 struct uart_config uart_config = {
411 .baudrate = dev_data->baud_rate,
412 .parity = UART_CFG_PARITY_NONE,
413 .stop_bits = UART_CFG_STOP_BITS_1,
414 .data_bits = UART_CFG_DATA_BITS_8,
415 .flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
416 };
417 return uart_sam_configure(dev, &uart_config);
418 }
419
420 static DEVICE_API(uart, uart_sam_driver_api) = {
421 .poll_in = uart_sam_poll_in,
422 .poll_out = uart_sam_poll_out,
423 .err_check = uart_sam_err_check,
424 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
425 .configure = uart_sam_configure,
426 .config_get = uart_sam_config_get,
427 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
428 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
429 .fifo_fill = uart_sam_fifo_fill,
430 .fifo_read = uart_sam_fifo_read,
431 .irq_tx_enable = uart_sam_irq_tx_enable,
432 .irq_tx_disable = uart_sam_irq_tx_disable,
433 .irq_tx_ready = uart_sam_irq_tx_ready,
434 .irq_rx_enable = uart_sam_irq_rx_enable,
435 .irq_rx_disable = uart_sam_irq_rx_disable,
436 .irq_tx_complete = uart_sam_irq_tx_complete,
437 .irq_rx_ready = uart_sam_irq_rx_ready,
438 .irq_err_enable = uart_sam_irq_err_enable,
439 .irq_err_disable = uart_sam_irq_err_disable,
440 .irq_is_pending = uart_sam_irq_is_pending,
441 .irq_update = uart_sam_irq_update,
442 .irq_callback_set = uart_sam_irq_callback_set,
443 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
444 };
445
446 #define UART_SAM_DECLARE_CFG(n, IRQ_FUNC_INIT) \
447 static const struct uart_sam_dev_cfg uart##n##_sam_config = { \
448 .regs = (Uart *)DT_INST_REG_ADDR(n), \
449 .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n), \
450 \
451 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
452 \
453 IRQ_FUNC_INIT \
454 }
455
456 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
457 #define UART_SAM_CONFIG_FUNC(n) \
458 static void uart##n##_sam_irq_config_func(const struct device *port) \
459 { \
460 IRQ_CONNECT(DT_INST_IRQN(n), \
461 DT_INST_IRQ(n, priority), \
462 uart_sam_isr, \
463 DEVICE_DT_INST_GET(n), 0); \
464 irq_enable(DT_INST_IRQN(n)); \
465 }
466 #define UART_SAM_IRQ_CFG_FUNC_INIT(n) \
467 .irq_config_func = uart##n##_sam_irq_config_func
468 #define UART_SAM_INIT_CFG(n) \
469 UART_SAM_DECLARE_CFG(n, UART_SAM_IRQ_CFG_FUNC_INIT(n))
470 #else
471 #define UART_SAM_CONFIG_FUNC(n)
472 #define UART_SAM_IRQ_CFG_FUNC_INIT
473 #define UART_SAM_INIT_CFG(n) \
474 UART_SAM_DECLARE_CFG(n, UART_SAM_IRQ_CFG_FUNC_INIT)
475 #endif
476
477 #define UART_SAM_INIT(n) \
478 PINCTRL_DT_INST_DEFINE(n); \
479 static struct uart_sam_dev_data uart##n##_sam_data = { \
480 .baud_rate = DT_INST_PROP(n, current_speed), \
481 }; \
482 \
483 static const struct uart_sam_dev_cfg uart##n##_sam_config; \
484 \
485 DEVICE_DT_INST_DEFINE(n, uart_sam_init, \
486 NULL, &uart##n##_sam_data, \
487 &uart##n##_sam_config, PRE_KERNEL_1, \
488 CONFIG_SERIAL_INIT_PRIORITY, \
489 &uart_sam_driver_api); \
490 \
491 UART_SAM_CONFIG_FUNC(n) \
492 \
493 UART_SAM_INIT_CFG(n);
494
495 DT_INST_FOREACH_STATUS_OKAY(UART_SAM_INIT)
496