1 /**
2  * \file
3  *
4  * \brief SAM UART Driver for SAMB11
5  *
6  * Copyright (C) 2015-2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #include "uart.h"
47 
48 /**
49  * \internal
50  * Internal driver device instance struct.
51  */
52 struct uart_module *_uart_instances[UART_INST_NUM];
53 
54 /**
55  * \internal
56  * Writes a character from the TX buffer to the Data register.
57  *
58  * \param[in,out]  module  Pointer to UART software instance struct
59  */
_uart_write(struct uart_module * const module)60 static void _uart_write(struct uart_module *const module)
61 {
62 	/* Pointer to the hardware module instance */
63 	Uart *const uart_hw = module->hw;
64 
65 	/* Write value will be at least 8-bits long */
66 	uint8_t data_to_send = *(module->tx_buffer_ptr);
67 	/* Increment 8-bit pointer */
68 	(module->tx_buffer_ptr)++;
69 
70 	/* Write the data to send*/
71 	uart_hw->TRANSMIT_DATA.reg = data_to_send & UART_TRANSMIT_DATA_MASK;
72 
73 	/* Decrement remaining buffer length */
74 	(module->remaining_tx_buffer_length)--;
75 }
76 
77 /**
78  * \internal
79  * Reads a character from the Data register to the RX buffer.
80  *
81  * \param[in,out]  module  Pointer to UART software instance struct
82  */
_uart_read(struct uart_module * const module)83 static void _uart_read(
84 		struct uart_module *const module)
85 {
86 	/* Pointer to the hardware module instance */
87 	Uart *const uart_hw = module->hw;
88 
89 	uint16_t received_data = (uart_hw->RECEIVE_DATA.reg & UART_RECEIVE_DATA_MASK);
90 
91 	/* Read value will be at least 8-bits long */
92 	*(module->rx_buffer_ptr) = received_data;
93 	/* Increment 8-bit pointer */
94 	module->rx_buffer_ptr += 1;
95 
96 	/* Decrement length of the remaining buffer */
97 	module->remaining_rx_buffer_length--;
98 }
99 
uart_rx0_isr_handler(void)100 static void uart_rx0_isr_handler(void)
101 {
102 	struct uart_module *module = _uart_instances[0];
103 	/* get interrupt flags and mask out enabled callbacks */
104 	uint32_t flags = module->hw->RECEIVE_STATUS.reg;
105 	if (flags & UART_RECEIVE_STATUS_FIFO_OVERRUN) {
106 		/* Store the error code */
107 		module->status = STATUS_ERR_OVERFLOW;
108 		/* Disable interrupt */
109 		module->hw->RX_INTERRUPT_MASK.reg &=
110 			~(UART_RX_INTERRUPT_MASK_FIFO_OVERRUN_MASK |
111 			SPI_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK);
112 		if ((module->callback_enable_mask & (1 << UART_RX_FIFO_OVERRUN)) &&
113 			(module->callback_reg_mask & (1 << UART_RX_FIFO_OVERRUN))) {
114 			(module->callback[UART_RX_FIFO_OVERRUN])(module);
115 		}
116 		/* Flush */
117 		uint8_t flush = module->hw->RECEIVE_DATA.reg;
118 		UNUSED(flush);
119 	}
120 	if (flags & UART_RECEIVE_STATUS_RX_FIFO_NOT_EMPTY) {
121 		_uart_read(module);
122 		if (module->remaining_rx_buffer_length == 0) {
123 			if ((module->callback_enable_mask & (1 << UART_RX_COMPLETE)) &&
124 				(module->callback_reg_mask & (1 << UART_RX_COMPLETE))) {
125 				module->status = STATUS_OK;
126 				module->hw->RX_INTERRUPT_MASK.reg &=
127 					~(UART_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK);
128 				(module->callback[UART_RX_COMPLETE])(module);
129 			}
130 		}
131 	}
132 }
133 
uart_tx0_isr_handler(void)134 static void uart_tx0_isr_handler(void)
135 {
136 	struct uart_module *module = _uart_instances[0];
137 	/* get interrupt flags and mask out enabled callbacks */
138 	uint32_t flags = module->hw->TRANSMIT_STATUS.reg;
139 	if (flags & UART_TRANSMIT_STATUS_TX_FIFO_NOT_FULL) {
140 		_uart_write(module);
141 		if (module->remaining_tx_buffer_length == 0) {
142 			module->hw->TX_INTERRUPT_MASK.reg &=
143 					~UART_TX_INTERRUPT_MASK_TX_FIFO_NOT_FULL_MASK;
144 			module->hw->TX_INTERRUPT_MASK.reg |=
145 					UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
146 		}
147 	}
148 	if (flags & UART_TRANSMIT_STATUS_TX_FIFO_EMPTY) {
149 		if ((module->callback_enable_mask & (1 << UART_TX_COMPLETE)) &&
150 			(module->callback_reg_mask & (1 << UART_TX_COMPLETE))) {
151 			module->status = STATUS_OK;
152 			/* Disable interrupt */
153 			module->hw->TX_INTERRUPT_MASK.reg &=
154 				~UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
155 			(module->callback[UART_TX_COMPLETE])(module);
156 		}
157 
158 	}
159 	if (flags & UART_TRANSMIT_STATUS_CTS_ACTIVE) {
160 		if ((module->callback_enable_mask & (1 << UART_CTS_ACTIVE)) &&
161 			(module->callback_reg_mask & (1 << UART_CTS_ACTIVE))) {
162 			(module->callback[UART_CTS_ACTIVE])(module);
163 		}
164 
165 	}
166 }
167 
uart_rx1_isr_handler(void)168 static void uart_rx1_isr_handler(void)
169 {
170 	struct uart_module *module = _uart_instances[1];
171 	/* get interrupt flags and mask out enabled callbacks */
172 	uint32_t flags = module->hw->RECEIVE_STATUS.reg;
173 	if (flags & UART_RECEIVE_STATUS_FIFO_OVERRUN) {
174 		/* Store the error code */
175 		module->status = STATUS_ERR_OVERFLOW;
176 		/* Disable interrupt */
177 		module->hw->RX_INTERRUPT_MASK.reg &=
178 			~(UART_RX_INTERRUPT_MASK_FIFO_OVERRUN_MASK |
179 			SPI_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK);
180 		if ((module->callback_enable_mask & (1 << UART_RX_FIFO_OVERRUN)) &&
181 			(module->callback_reg_mask & (1 << UART_RX_FIFO_OVERRUN))) {
182 			(module->callback[UART_RX_FIFO_OVERRUN])(module);
183 		}
184 		/* Flush */
185 		uint8_t flush = module->hw->RECEIVE_DATA.reg;
186 		UNUSED(flush);
187 	}
188 	if (flags & UART_RECEIVE_STATUS_RX_FIFO_NOT_EMPTY) {
189 		_uart_read(module);
190 		if (module->remaining_rx_buffer_length == 0) {
191 			if ((module->callback_enable_mask & (1 << UART_RX_COMPLETE)) &&
192 				(module->callback_reg_mask & (1 << UART_RX_COMPLETE))) {
193 				module->status = STATUS_OK;
194 				module->hw->RX_INTERRUPT_MASK.reg &=
195 					~(UART_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK);
196 				(module->callback[UART_RX_COMPLETE])(module);
197 			}
198 		}
199 	}
200 }
201 
uart_tx1_isr_handler(void)202 static void uart_tx1_isr_handler(void)
203 {
204 	struct uart_module *module = _uart_instances[1];
205 	/* get interrupt flags and mask out enabled callbacks */
206 	uint32_t flags = module->hw->TRANSMIT_STATUS.reg;
207 	if (flags & UART_TRANSMIT_STATUS_TX_FIFO_NOT_FULL) {
208 		_uart_write(module);
209 		if (module->remaining_tx_buffer_length == 0) {
210 			module->hw->TX_INTERRUPT_MASK.reg &=
211 					~UART_TX_INTERRUPT_MASK_TX_FIFO_NOT_FULL_MASK;
212 			module->hw->TX_INTERRUPT_MASK.reg |=
213 					UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
214 		}
215 	}
216 	if (flags & UART_TRANSMIT_STATUS_TX_FIFO_EMPTY) {
217 		if ((module->callback_enable_mask & (1 << UART_TX_COMPLETE)) &&
218 			(module->callback_reg_mask & (1 << UART_TX_COMPLETE))) {
219 			module->status = STATUS_OK;
220 			/* Disable interrupt */
221 			module->hw->TX_INTERRUPT_MASK.reg &=
222 				~UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
223 			(module->callback[UART_TX_COMPLETE])(module);
224 		}
225 
226 	}
227 	if (flags & UART_TRANSMIT_STATUS_CTS_ACTIVE) {
228 		if ((module->callback_enable_mask & (1 << UART_CTS_ACTIVE)) &&
229 			(module->callback_reg_mask & (1 << UART_CTS_ACTIVE))) {
230 			(module->callback[UART_CTS_ACTIVE])(module);
231 		}
232 
233 	}
234 }
235 
uart_set_baudrate(struct uart_module * const module,const uint32_t baud_rate)236 static void uart_set_baudrate(struct uart_module *const module,
237 		const uint32_t baud_rate)
238 {
239 	uint32_t clock;
240 	uint16_t integerpart = 0;
241 	uint8_t fractionalpart = 0;
242 	uint32_t diff;
243 	uint8_t i = 0;
244 
245 	clock = system_clock_get_value();
246 	integerpart = clock / baud_rate;
247 	diff = clock - (baud_rate * integerpart);
248 	i = 0;
249 	while(diff > (baud_rate / 16)) {
250 		i++;
251 		diff -= (baud_rate / 16);
252 	}
253 	fractionalpart = (i + 1) / 2;
254 
255 	module->hw->UART_CLOCK_SOURCE.reg = UART_CLOCK_SOURCE_CLOCK_SELECT_0;
256 	module->hw->UART_BAUD_RATE.reg =
257 		UART_BAUD_RATE_INTEGER_DIVISION(integerpart) |
258 		UART_BAUD_RATE_FRACTIONAL_DIVISION(fractionalpart);
259 }
260 
261 /**
262  * \brief Gets the UART default configurations
263  *
264  * Use to initialize the configuration structure to known default values.
265  *
266  * The default configuration is as follows:
267  * - Baudrate 115200
268  * - parity   UART_NO_PARITY
269  * - flow_control 0 - No Flow control
270  * - stop_bits 1 - 1 stop bit
271  * - pinmux_pad[] - Pinmux default are UART0.
272  *
273  * \param[out] config  Pointer to configuration structure to be initiated
274  */
uart_get_config_defaults(struct uart_config * const config)275 void uart_get_config_defaults(
276 		struct uart_config *const config)
277 {
278 	config->baud_rate = 115200;
279 	config->data_bits = UART_8_BITS;
280 	config->stop_bits = UART_1_STOP_BIT;
281 	config->parity = UART_NO_PARITY;
282 	config->flow_control = false;
283 
284 	config->pin_number_pad[0] = PIN_LP_GPIO_2;
285 	config->pin_number_pad[1] = PIN_LP_GPIO_3;
286 	config->pin_number_pad[2] = PIN_LP_GPIO_4;
287 	config->pin_number_pad[3] = PIN_LP_GPIO_5;
288 
289 	config->pinmux_sel_pad[0] = MUX_LP_GPIO_2_UART0_RXD;
290 	config->pinmux_sel_pad[1] = MUX_LP_GPIO_3_UART0_TXD;
291 	config->pinmux_sel_pad[2] = MUX_LP_GPIO_4_UART0_CTS;
292 	config->pinmux_sel_pad[3] = MUX_LP_GPIO_5_UART0_RTS;
293 }
294 
295 /**
296  * \brief Initializes the device
297  *
298  * Initializes the UART device based on the setting specified in the
299  * configuration struct.
300  *
301  * \param[in]  module  enumeration UART hw module
302  * \param[in]  hw      Pointer to USART hardware instance
303  * \param[in]  config  Pointer to configuration struct
304  *
305  * \return Status of the initialization.
306  *
307  * \retval STATUS_OK                       The initialization was successful
308  */
uart_init(struct uart_module * const module,Uart * const hw,const struct uart_config * const config)309 enum status_code uart_init(struct uart_module *const module, Uart * const hw,
310 		const struct uart_config *const config)
311 {
312 	/* Sanity check arguments */
313 	Assert(module);
314 	Assert(hw);
315 	Assert(config);
316 
317 	uint8_t config_temp = 0;
318 	uint8_t i,index;
319 
320 	/* Assign module pointer to software instance struct */
321 	module->hw = hw;
322 
323 	for (i = 0; i < UART_CALLBACK_N; i++) {
324 		module->callback[i] = NULL;
325 	}
326 	module->rx_buffer_ptr = NULL;
327 	module->tx_buffer_ptr = NULL;
328 	module->remaining_rx_buffer_length = 0;
329 	module->remaining_tx_buffer_length = 0;
330 	module->callback_reg_mask = 0;
331 	module->callback_enable_mask = 0;
332 	module->status = STATUS_OK;
333 
334 	if (hw == UART0) {
335 		system_peripheral_reset(PERIPHERAL_UART0_CORE);
336 		system_peripheral_reset(PERIPHERAL_UART0_IF);
337 		system_clock_peripheral_enable(PERIPHERAL_UART0_CORE);
338 		system_clock_peripheral_enable(PERIPHERAL_UART0_IF);
339 		_uart_instances[0] = module;
340 		system_register_isr(RAM_ISR_TABLE_UARTRX0_INDEX, (uint32_t)uart_rx0_isr_handler);
341 		system_register_isr(RAM_ISR_TABLE_UARTTX0_INDEX, (uint32_t)uart_tx0_isr_handler);
342 		NVIC_EnableIRQ(UART0_RX_IRQn);
343 		NVIC_EnableIRQ(UART0_TX_IRQn);
344 	} else if (hw == UART1) {
345 		system_peripheral_reset(PERIPHERAL_UART1_CORE);
346 		system_peripheral_reset(PERIPHERAL_UART1_IF);
347 		system_clock_peripheral_enable(PERIPHERAL_UART1_CORE);
348 		system_clock_peripheral_enable(PERIPHERAL_UART1_IF);
349 		_uart_instances[1] = module;
350 		system_register_isr(RAM_ISR_TABLE_UARTRX1_INDEX, (uint32_t)uart_rx1_isr_handler);
351 		system_register_isr(RAM_ISR_TABLE_UARTTX1_INDEX, (uint32_t)uart_tx1_isr_handler);
352 		NVIC_EnableIRQ(UART1_RX_IRQn);
353 		NVIC_EnableIRQ(UART1_TX_IRQn);
354 	}
355 
356 	/* Set the pinmux for this UART module. */
357 	if(config->flow_control) {
358 		index = 4;
359 	} else {
360 		index = 2;
361 	}
362 
363 #if (BTLC1000)
364     index = 2;  /* BTLC1000 has no flow control function. */
365 #endif
366 
367 	for(i = 0; i < index; i++) {
368 		gpio_pinmux_cofiguration(config->pin_number_pad[i], \
369 								(uint16_t)(config->pinmux_sel_pad[i]));
370 	}
371 
372 	/* empty UART FIFO */
373 	while (module->hw->RECEIVE_STATUS.reg & UART_RECEIVE_STATUS_RX_FIFO_NOT_EMPTY) {
374 		i = module->hw->RECEIVE_DATA.reg;
375 	}
376 
377 	/* reset configuration register */
378 	module->hw->UART_CONFIGURATION.reg = 0;
379 
380 	/* program the uart configuration. */
381 	if(config->flow_control) {
382 		config_temp |= UART_CONFIGURATION_CTS_ENABLE_1;
383 	}
384 	config_temp |= config->data_bits;
385 	config_temp |= config->stop_bits;
386 	switch(config->parity) {
387 		case UART_NO_PARITY:
388 			config_temp |= UART_CONFIGURATION_PARITY_ENABLE_0;
389 			break;
390 
391 		case UART_EVEN_PARITY:
392 			config_temp |= UART_CONFIGURATION_PARITY_ENABLE_1;
393 			config_temp |= UART_CONFIGURATION_PARITY_MODE_0;
394 			break;
395 
396 		case UART_ODD_PARITY:
397 			config_temp |= UART_CONFIGURATION_PARITY_ENABLE_1;
398 			config_temp |= UART_CONFIGURATION_PARITY_MODE_1;
399 			break;
400 
401 		case UART_SPACE_PARITY:
402 			config_temp |= UART_CONFIGURATION_PARITY_ENABLE_1;
403 			config_temp |= UART_CONFIGURATION_PARITY_MODE_2;
404 			break;
405 
406 		case UART_MARK_PARITY:
407 			config_temp |= UART_CONFIGURATION_PARITY_ENABLE_1;
408 			config_temp |= UART_CONFIGURATION_PARITY_MODE_3;
409 			break;
410 
411 		default:
412 			break;
413 	}
414 	module->hw->UART_CONFIGURATION.reg = config_temp;
415 
416 	/* Calculate the baud rate. */
417 	uart_set_baudrate(module, config->baud_rate);
418 
419 	module->hw->RX_INTERRUPT_MASK.reg = 0;	// disable int at initialization, enable it at read time
420 	module->hw->TX_INTERRUPT_MASK.reg = 0;	// disable int at initialization, enable it at write time
421 
422 	return STATUS_OK;
423 }
424 
425 /**
426 * \brief Transmit a character via the UART
427 *
428 * This blocking function will transmit a single character via the
429 * UART.
430 *
431 * \param[in]  module  enumeration UART hw module
432 * \param[in]  tx_data  Data to transfer
433 *
434 * \return Status of the operation.
435 * \retval STATUS_OK         If the operation was completed
436 */
uart_write_wait(struct uart_module * const module,const uint8_t tx_data)437 enum status_code uart_write_wait(struct uart_module *const module,
438 		const uint8_t tx_data)
439 {
440 	while (!(module->hw->TRANSMIT_STATUS.reg & UART_TRANSMIT_STATUS_TX_FIFO_NOT_FULL));
441 
442 	module->hw->TRANSMIT_DATA.reg = tx_data;
443 
444 	return STATUS_OK;
445 }
446 
447 /**
448 * \brief Receive a character via the UART
449 *
450 * This blocking function will receive a character via the UART.
451 *
452 * \param[in]   module  enumeration UART hw module
453 * \param[out]  rx_data  Pointer to received data
454 *
455 * \return Status of the operation.
456 * \retval STATUS_OK                If the operation was completed
457 */
uart_read_wait(struct uart_module * const module,uint8_t * const rx_data)458 enum status_code uart_read_wait(struct uart_module *const module,
459 		uint8_t *const rx_data)
460 {
461 	while (!(module->hw->RECEIVE_STATUS.reg & UART_RECEIVE_STATUS_RX_FIFO_NOT_EMPTY));
462 
463 	*rx_data = module->hw->RECEIVE_DATA.reg;
464 
465 	return STATUS_OK;
466 }
467 
468 /**
469 * \brief Transmit a buffer of characters via the UART
470 *
471 * This blocking function will transmit a block of \c length characters
472 * via the UART.
473 *
474 * \note Using this function in combination with the interrupt (\c _job) functions is
475 *       not recommended as it has no functionality to check if there is an
476 *       ongoing interrupt driven operation running or not.
477 *
478 * \param[in]  module  enumeration UART hw module
479 * \param[in]  tx_data  Pointer to data to transmit
480 * \param[in]  length   Number of characters to transmit
481 *
482 * \return Status of the operation.
483 * \retval STATUS_OK              If operation was completed
484 */
uart_write_buffer_wait(struct uart_module * const module,const uint8_t * tx_data,uint32_t length)485 enum status_code uart_write_buffer_wait(struct uart_module *const module,
486 		const uint8_t *tx_data, uint32_t length)
487 {
488 	while(length--)
489 		uart_write_wait(module, *tx_data++);
490 
491 	return STATUS_OK;
492 }
493 
494 /**
495  * \brief Receive a buffer of \c length characters via the UART
496  *
497  * This blocking function will receive a block of \c length characters
498  * via the UART.
499  *
500  * \note Using this function in combination with the interrupt (\c *_job)
501  *       functions is not recommended as it has no functionality to check if
502  *       there is an ongoing interrupt driven operation running or not.
503  *
504  * \param[in]  module  enumeration UART hw module
505  * \param[out] rx_data  Pointer to receive buffer
506  * \param[in]  length   Number of characters to receive
507  *
508  * \return Status of the operation.
509  * \retval STATUS_OK                If operation was completed
510  */
uart_read_buffer_wait(struct uart_module * const module,uint8_t * rx_data,uint16_t length)511 enum status_code uart_read_buffer_wait(struct uart_module *const module,
512 		uint8_t *rx_data, uint16_t length)
513 {
514 	while(length--)
515 		uart_read_wait(module, rx_data++);
516 
517 	return STATUS_OK;
518 }
519 
520 /**
521  * \internal
522  * Starts write of a buffer with a given length
523  *
524  * \param[in]  module   Pointer to UART software instance struct
525  * \param[in]  tx_data  Pointer to data to be transmitted
526  * \param[in]  length   Length of data buffer
527  *
528  */
_uart_write_buffer(struct uart_module * const module,uint8_t * tx_data,uint16_t length)529 static void _uart_write_buffer(
530 		struct uart_module *const module,
531 		uint8_t *tx_data,
532 		uint16_t length)
533 {
534 	Assert(module);
535 	Assert(tx_data);
536 
537 	/* Write parameters to the device instance */
538 	module->remaining_tx_buffer_length = length;
539 	module->tx_buffer_ptr = tx_data;
540 	module->status = STATUS_BUSY;
541 
542 	module->hw->TX_INTERRUPT_MASK.reg = UART_TX_INTERRUPT_MASK_TX_FIFO_NOT_FULL_MASK;
543 }
544 
545 /**
546  * \internal
547  * Setup UART to read a buffer with a given length
548  *
549  * \param[in]  module   Pointer to UART software instance struct
550  * \param[in]  rx_data  Pointer to data to be received
551  * \param[in]  length   Length of data buffer
552  *
553  */
_uart_read_buffer(struct uart_module * const module,uint8_t * rx_data,uint16_t length)554 static void _uart_read_buffer(
555 		struct uart_module *const module,
556 		uint8_t *rx_data,
557 		uint16_t length)
558 {
559 	Assert(module);
560 	Assert(rx_data);
561 
562 	/* Set length for the buffer and the pointer, and let
563 	 * the interrupt handler do the rest */
564 	module->remaining_rx_buffer_length = length;
565 	module->rx_buffer_ptr = rx_data;
566 	module->status = STATUS_BUSY;
567 
568 	module->hw->RX_INTERRUPT_MASK.reg = UART_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK;
569 }
570 
571 /**
572  * \brief Asynchronous buffer write
573  *
574  * Sets up the driver to write to the UART from a given buffer. If registered
575  * and enabled, a callback function will be called when the write is finished.
576  *
577  * \param[in]  module   Pointer to UART software instance struct
578  * \param[out] tx_data  Pointer to data buffer to receive
579  * \param[in]  length   Data buffer length
580  *
581  * \returns Status of the write request operation.
582  * \retval STATUS_OK               If the operation completed successfully
583  * \retval STATUS_ERR_BUSY         If the UART was already busy with a write
584  *                                 operation
585  * \retval STATUS_ERR_INVALID_ARG  If requested write length was zero
586  */
uart_write_buffer_job(struct uart_module * const module,uint8_t * tx_data,uint32_t length)587 enum status_code uart_write_buffer_job(struct uart_module *const module,
588 		uint8_t *tx_data, uint32_t length)
589 {
590 	Assert(module);
591 	Assert(tx_data);
592 
593 	if (length == 0) {
594 		return STATUS_ERR_INVALID_ARG;
595 	}
596 
597 	/* Check if the UART is busy transmitting or slave waiting for TXC*/
598 	if (module->status == STATUS_BUSY) {
599 		return STATUS_BUSY;
600 	}
601 
602 	/* Issue internal write */
603 	_uart_write_buffer(module, tx_data, length);
604 
605 	return STATUS_OK;
606 }
607 
608 /**
609  * \brief Asynchronous buffer read
610  *
611  * Sets up the driver to read from the UART to a given buffer. If registered
612  * and enabled, a callback function will be called when the read is finished.
613  *
614  * \note If address matching is enabled for the slave, the first character
615  *       received and placed in the RX buffer will be the address.
616  *
617  * \param[in]  module   Pointer to UART software instance struct
618  * \param[out] rx_data  Pointer to data buffer to receive
619  * \param[in]  length   Data buffer length
620  * \param[in]  dummy    Dummy character to send when reading in master mode
621  *
622  * \returns Status of the operation.
623  * \retval  STATUS_OK               If the operation completed successfully
624  * \retval  STATUS_ERR_BUSY         If the UART was already busy with a read
625  *                                  operation
626  * \retval  STATUS_ERR_DENIED       If the receiver is not enabled
627  * \retval  STATUS_ERR_INVALID_ARG  If requested read length was zero
628  */
uart_read_buffer_job(struct uart_module * const module,uint8_t * rx_data,uint16_t length)629 enum status_code uart_read_buffer_job(struct uart_module *const module,
630 		uint8_t *rx_data, uint16_t length)
631 {
632 	/* Sanity check arguments */
633 	Assert(module);
634 	Assert(rx_data);
635 
636 	if (length == 0) {
637 		return STATUS_ERR_INVALID_ARG;
638 	}
639 
640 	/* Check if the UART is busy transmitting or slave waiting for TXC*/
641 	if (module->status == STATUS_BUSY) {
642 		return STATUS_BUSY;
643 	}
644 
645 	/* Issue internal read */
646 	_uart_read_buffer(module, rx_data, length);
647 	return STATUS_OK;
648 }
649 
650 /**
651  * \brief Registers a callback
652  *
653  * Registers a callback function which is implemented by the user.
654  *
655  * \note The callback must be enabled by \ref uart_enable_callback,
656  *       in order for the interrupt handler to call it when the conditions for
657  *       the callback type are met.
658  *
659  * \param[in]  module         Pointer to UART software instance struct
660  * \param[in]  callback_func  Pointer to callback function
661  * \param[in]  callback_type  Callback type given by an enum
662  *
663  */
uart_register_callback(struct uart_module * const module,uart_callback_t callback_func,enum uart_callback callback_type)664 void uart_register_callback(struct uart_module *const module,
665 		uart_callback_t callback_func,
666 		enum uart_callback callback_type)
667 {
668 	/* Sanity check arguments */
669 	Assert(module);
670 	Assert(callback_func);
671 
672 	/* Register callback function */
673 	module->callback[callback_type] = callback_func;
674 	/* Set the bit corresponding to the callback_type */
675 	module->callback_reg_mask |= (1 << callback_type);
676 }
677 
678 /**
679  * \brief Unregisters a callback
680  *
681  * Unregisters a callback function which is implemented by the user.
682  *
683  * \param[in,out]  module         Pointer to UART software instance struct
684  * \param[in]      callback_type  Callback type given by an enum
685  *
686  */
uart_unregister_callback(struct uart_module * module,enum uart_callback callback_type)687 void uart_unregister_callback(struct uart_module *module,
688 		enum uart_callback callback_type)
689 {
690 	/* Sanity check arguments */
691 	Assert(module);
692 
693 	/* Unregister callback function */
694 	module->callback[callback_type] = NULL;
695 	/* Clear the bit corresponding to the callback_type */
696 	module->callback_reg_mask &= ~(1 << callback_type);
697 }
698 
699 /**
700  * \brief Enables callback
701  *
702  * Enables the callback function registered by the \ref usart_register_callback.
703  * The callback function will be called from the interrupt handler when the
704  * conditions for the callback type are met.
705  *
706  * \param[in]  module         Pointer to UART software instance struct
707  * \param[in]  callback_type  Callback type given by an enum
708  */
uart_enable_callback(struct uart_module * const module,enum uart_callback callback_type)709 void uart_enable_callback(struct uart_module *const module,
710 		enum uart_callback callback_type)
711 {
712 	/* Sanity check arguments */
713 	Assert(module);
714 
715 	/* Enable callback */
716 	module->callback_enable_mask |= (1 << callback_type);
717 
718 	if (callback_type == UART_CTS_ACTIVE) {
719 		module->hw->TX_INTERRUPT_MASK.reg |= UART_TX_INTERRUPT_MASK_CTS_ACTIVE_MASK;
720 	}
721 }
722 
723 /**
724  * \brief Disable callback
725  *
726  * Disables the callback function registered by the \ref usart_register_callback,
727  * and the callback will not be called from the interrupt routine.
728  *
729  * \param[in]  module         Pointer to UART software instance struct
730  * \param[in]  callback_type  Callback type given by an enum
731  */
uart_disable_callback(struct uart_module * const module,enum uart_callback callback_type)732 void uart_disable_callback(struct uart_module *const module,
733 		enum uart_callback callback_type)
734 {
735 	/* Sanity check arguments */
736 	Assert(module);
737 
738 	/* Disable callback */
739 	module->callback_enable_mask &= ~(1 << callback_type);
740 
741 	if (callback_type == UART_CTS_ACTIVE) {
742 		module->hw->TX_INTERRUPT_MASK.reg &= ~UART_TX_INTERRUPT_MASK_CTS_ACTIVE_MASK;
743 	}
744 
745 }
746 
747 /**
748  * \brief Enables UART transmit DMA
749  *
750  * \param[in]  module         Pointer to UART software instance struct
751  */
uart_enable_transmit_dma(struct uart_module * const module)752 void uart_enable_transmit_dma(struct uart_module *const module)
753 {
754 	/* Sanity check arguments */
755 	Assert(module);
756 
757 	/* DMA need the interrupt signal to trigger */
758 	module->hw->TX_INTERRUPT_MASK.reg |= UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
759 
760 	/* Disable NVIC to avoid trigger the CPU interrupt */
761 	if (module->hw == UART0) {
762 		NVIC_DisableIRQ(UART0_TX_IRQn);
763 	} else if (module->hw == UART1) {
764 		NVIC_DisableIRQ(UART1_TX_IRQn);
765 	}
766 }
767 
768 /**
769  * \brief Disables UART transmit DMA
770  *
771  * \param[in]  module         Pointer to UART software instance struct
772  */
uart_disable_transmit_dma(struct uart_module * const module)773 void uart_disable_transmit_dma(struct uart_module *const module)
774 {
775 	/* Sanity check arguments */
776 	Assert(module);
777 
778 	module->hw->TX_INTERRUPT_MASK.reg &= ~UART_TX_INTERRUPT_MASK_TX_FIFO_EMPTY_MASK;
779 
780 	/* Enable NVIC to restore the callback functions */
781 	if (module->hw == UART0) {
782 		NVIC_EnableIRQ(UART0_TX_IRQn);
783 	} else if (module->hw == UART1) {
784 		NVIC_EnableIRQ(UART1_TX_IRQn);
785 	}
786 }
787 
788 /**
789  * \brief Enables UART receive DMA
790  *
791  * \param[in]  module         Pointer to UART software instance struct
792  */
uart_enable_receive_dma(struct uart_module * const module)793 void uart_enable_receive_dma(struct uart_module *const module)
794 {
795 	/* Sanity check arguments */
796 	Assert(module);
797 
798 	/* DMA need the interrupt signal to trigger */
799 	module->hw->RX_INTERRUPT_MASK.reg |= UART_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK;
800 
801 	/* Disable NVIC to avoid trigger the CPU interrupt */
802 	if (module->hw == UART0) {
803 		NVIC_DisableIRQ(UART0_TX_IRQn);
804 	} else if (module->hw == UART1) {
805 		NVIC_DisableIRQ(UART1_TX_IRQn);
806 	}
807 }
808 
809 /**
810  * \brief Disables UART receive DMA
811  *
812  * \param[in]  module         Pointer to UART software instance struct
813  */
uart_disable_receive_dma(struct uart_module * const module)814 void uart_disable_receive_dma(struct uart_module *const module)
815 {
816 	/* Sanity check arguments */
817 	Assert(module);
818 
819 	module->hw->RX_INTERRUPT_MASK.reg &= ~UART_RX_INTERRUPT_MASK_RX_FIFO_NOT_EMPTY_MASK;
820 
821 	/* Enable NVIC to restore the callback functions */
822 	if (module->hw == UART0) {
823 		NVIC_EnableIRQ(UART0_TX_IRQn);
824 	} else if (module->hw == UART1) {
825 		NVIC_EnableIRQ(UART1_TX_IRQn);
826 	}
827 }
828 
829