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