aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
authorTheodore Ateba <tf.ateba@gmail.com>2018-02-12 20:18:31 +0000
committerTheodore Ateba <tf.ateba@gmail.com>2018-02-12 20:18:31 +0000
commit9c9e48e676864e0d7023d7efa50f5dcc9e196136 (patch)
treefc2377a50c2d71540f8808aac20cf7c2d33217e3 /os/hal/ports
parenta94b06f1663e9b980fb51739926ff36cd7ab8409 (diff)
downloadChibiOS-9c9e48e676864e0d7023d7efa50f5dcc9e196136.tar.gz
ChibiOS-9c9e48e676864e0d7023d7efa50f5dcc9e196136.tar.bz2
ChibiOS-9c9e48e676864e0d7023d7efa50f5dcc9e196136.zip
AVR: Add usart low level driver for ATXMEGA128U4A.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11491 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.c483
-rw-r--r--os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.h448
2 files changed, 931 insertions, 0 deletions
diff --git a/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.c b/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.c
new file mode 100644
index 000000000..10726fafc
--- /dev/null
+++ b/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.c
@@ -0,0 +1,483 @@
+/*
+ ChibiOS - Copyright (C) 2016..2018 Theodore Ateba
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file hal_uart_lld.c
+ * @brief AVR UART subsystem low level driver source.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
+
+/*==========================================================================*/
+/* Driver local definitions. */
+/*==========================================================================*/
+
+/*==========================================================================*/
+/* Driver exported variables. */
+/*==========================================================================*/
+
+/**
+ * @brief USART1 (USARTC0) driver identifier.
+ */
+#if (AVR_UART_USE_USART1 == TRUE) || defined(__DOXYGEN__)
+UARTDriver USART1D;
+#endif
+
+/**
+ * @brief USART2 (USARTC1) driver identifier.
+ */
+#if (AVR_UART_USE_USART2 == TRUE) || defined(__DOXYGEN__)
+UARTDriver USART2D;
+#endif
+
+/**
+ * @brief USART3 (USARTD0) driver identifier.
+ */
+#if (AVR_UART_USE_USART3 == TRUE) || defined(__DOXYGEN__)
+UARTDriver USART3D;
+#endif
+
+/**
+ * @brief USART4 (USARTD1) driver identifier.
+ */
+#if (AVR_UART_USE_USART4 == TRUE) || defined(__DOXYGEN__)
+UARTDriver USART4D;
+#endif
+
+/**
+ * @brief USARTD5 (USARTE0) driver identifier.
+ */
+#if (AVR_UART_USE_USART5 == TRUE) || defined(__DOXYGEN__)
+UARTDriver USART5D;
+#endif
+
+/*==========================================================================*/
+/* Driver local variables and types. */
+/*==========================================================================*/
+
+/*==========================================================================*/
+/* Driver local functions. */
+/*==========================================================================*/
+
+/**
+ * @brief Configure the multiprocessor communication mode.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_mpcm(UARTDriver *uartp) {
+
+ if (uartp->config->mpcm)
+ uartp->usart->CTRLB |= (USART_MPCM_bm); /* Enable the MPCM. */
+ else
+ uartp->usart->CTRLB &= ~(USART_MPCM_bm); /* Disable the MPCM. */
+}
+
+/**
+ * @brief Configure the double speed.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_clk2x(UARTDriver *uartp) {
+
+ if (uartp->config->clk2x)
+ uartp->usart->CTRLB |= (USART_CLK2X_bm); /* Enable double speed. */
+ else
+ uartp->usart->CTRLB &= ~(USART_CLK2X_bm); /* Use normal speed. */
+}
+
+/**
+ * @brief Configuration of transmission mode (8/9 bits).
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_txb8(UARTDriver *uartp) {
+
+ if (uartp->config->txb8)
+ uartp->usart->CTRLB |= (USART_TXB8_bm); /* 9 bits transmission mode. */
+ else
+ uartp->usart->CTRLB &= ~(USART_TXB8_bm); /* 8 bits transmission mode. */
+}
+
+/**
+ * @brief Configuration of communication mode.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_cmode(UARTDriver *uartp) {
+
+ if (uartp->config->cmode == USART_CMODE_MSPI) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CMODE_gm) | \
+ (USART_CMODE_MSPI_gc);
+ }
+ else if (uartp->config->cmode == USART_CMODE_IRCOM) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CMODE_gm) | \
+ (USART_CMODE_IRDA_gc);
+ }
+ else if (uartp->config->cmode == USART_CMODE_SYNCHRONOUS) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CMODE_gm) | \
+ (USART_CMODE_SYNCHRONOUS_gc);
+ }
+ else {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CMODE_gm) | \
+ (USART_CMODE_ASYNCHRONOUS_gc);
+ }
+}
+
+/**
+ * @brief Configuration of the number of stop to use during transmission.
+ * @details @true set 2 stop bit and @false set 1 stop bit.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_sbmode(UARTDriver *uartp) {
+
+ if (uartp->config->sbmode) {
+ uartp->usart->CTRLC |= USART_SBMODE_bm;
+ }
+ else {
+ uartp->usart->CTRLC &= ~USART_SBMODE_bm;
+ }
+}
+
+/**
+ * @brief Configuration of parity mode.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_pmode(UARTDriver *uartp) {
+
+ if (uartp->config->pmode == USART_PMODE_EVEN) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_PMODE_gm) | \
+ (USART_PMODE_EVEN_gc);
+ }
+ else if (uartp->config->chsize == USART_PMODE_ODD) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_PMODE_gm) | \
+ (USART_PMODE_ODD_gc);
+ }
+ else {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_PMODE_gm) | \
+ (USART_PMODE_DISABLED_gc);
+ }
+}
+
+/**
+ * @brief Configuration of caracter size.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_chsize(UARTDriver *uartp) {
+
+ if (uartp->config->chsize == USART_CHSIZE_5BIT) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CHSIZE_gm) | \
+ (USART_CHSIZE_5BIT_gc);
+ }
+ else if (uartp->config->chsize == USART_CHSIZE_6BIT) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CHSIZE_gm) | \
+ (USART_CHSIZE_6BIT_gc);
+ }
+ else if (uartp->config->chsize == USART_CHSIZE_7BIT) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CHSIZE_gm) | \
+ (USART_CHSIZE_7BIT_gc);
+ }
+ else if (uartp->config->chsize == USART_CHSIZE_8BIT) {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CHSIZE_gm) | \
+ (USART_CHSIZE_8BIT_gc);
+ }
+ else {
+ uartp->usart->CTRLC = (uartp->usart->CTRLC & ~USART_CHSIZE_gm) | \
+ (USART_CHSIZE_9BIT_gc);
+ }
+}
+
+/**
+ * @brief Configuration of the baud rate.
+ * @note BSCALE is set to 0 for the moment.
+ * @TODO Support all the BSCALE value
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_cfg_baudrate(UARTDriver *uartp) {
+
+ /* BSCALE = 0. */
+ #define BSCALE 0
+ uint16_t br = get_bsel(uartp->config->speed);
+ uartp->usart->BAUDCTRLA =(uint8_t)br;
+ uartp->usart->BAUDCTRLB =(BSCALE << USART_BSCALE0_bp) | (br >> 8);
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_stop(UARTDriver *uartp) {
+
+ /* Stops RX and TX DMA channels. */
+ /*
+ dmaStreamDisable(uartp->dmarx);
+ dmaStreamDisable(uartp->dmatx);
+ */
+
+ /* Stops USART operations. */
+ uartp->usart->CTRLB &= ~(USART_RXEN_bm); /* Disable the USART receiver. */
+ uartp->usart->CTRLB &= ~(USART_TXEN_bm); /* Disable the USART transmitter. */
+}
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_start(UARTDriver *uartp) {
+
+ /* Defensive programming, starting from a clean state. */
+ usart_stop(uartp);
+
+ /* Resetting eventual pending status flags. */
+
+ /* Starting the receiver idle loop. */
+ /*uart_enter_rx_idle_loop(uartp);*/
+
+ usart_cfg_mpcm(uartp); /* Set the multi processor communication mode. */
+ usart_cfg_clk2x(uartp); /* Set the USART speed (Normal/Double). */
+ usart_cfg_txb8(uartp); /* Set the transmission mode (8/9bits). */
+ usart_cfg_cmode(uartp); /* Set the communication mode. */
+ usart_cfg_sbmode(uartp);/* Set the stop bit mode. */
+ usart_cfg_pmode(uartp); /* Set the parity mode. */
+ usart_cfg_chsize(uartp);/* Set the character size. */
+ usart_cfg_baudrate(uartp); /* Set the baud rate. */
+ uartp->usart->CTRLB |= (USART_RXEN_bm); /* enable the USART receiver. */
+ uartp->usart->CTRLB |= (USART_TXEN_bm); /* enable the USART transmitter. */
+}
+
+/*==========================================================================*/
+/* Driver interrupt handlers. */
+/*==========================================================================*/
+
+#if AVR_UART_USE_USART1 || defined(__DOXYGEN__)
+/**
+ * @brief USART1 TX IRQ handler, transmission complete interruption.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(USARTC0_TXC_vect) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ /*serve_usart_irq(&UARTD1);*/
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief USART1 RX IRQ handler, reception complete interruption.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(USARTC0_RXC_vect) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ /*serve_usart_irq(&UARTD1);*/
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief USART1 DRE IRQ handler, data register empty interruption.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(USARTC0_DRE_vect) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ /*serve_usart_irq(&UARTD1);*/
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* AVR_UART_USE_USART1 */
+
+/*==========================================================================*/
+/* Driver exported functions. */
+/*==========================================================================*/
+
+/**
+ * @brief Low level UART driver initialization.
+ *
+ * @notapi
+ */
+void uart_lld_init(void) {
+
+#if AVR_UART_USE_USART1 == TRUE
+ /* Driver initialization. */
+ uartObjectInit(&USART1D);
+ USART1D.usart = &USARTC0;
+ /*USART1D.usart->CTRLC = 0;*/
+ /*USART1D.usart->BAUDCTRLA = 0;*/
+#endif
+
+#if AVR_UART_USE_USART2 == TRUE
+ /* Driver initialization. */
+ uartObjectInit(&USART2D);
+#endif
+
+#if AVR_UART_USE_USART3 == TRUE
+ /* Driver initialization. */
+ uartObjectInit(&USART3D);
+#endif
+
+#if AVR_UART_USE_USART4 == TRUE
+ /* Driver initialization. */
+ uartObjectInit(&USART4D);
+#endif
+
+#if AVR_UART_USE_USART5 == TRUE
+ /* Driver initialization. */
+ uartObjectInit(&USART5D);
+#endif
+}
+
+/**
+ * @brief Configures and activates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_start(UARTDriver *uartp) {
+
+ if (uartp->state == UART_STOP) {
+ /* Enables the peripheral. */
+#if AVR_UART_USE_USART1 == TRUE
+ if (&USART1D == uartp) {
+ /* TODO: Implement the DMA part here. */
+ }
+#endif
+ }
+ /* Configures the peripheral. */
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
+ usart_start(uartp);
+}
+
+/**
+ * @brief Deactivates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_stop(UARTDriver *uartp) {
+
+ if (uartp->state == UART_READY) {
+ /* Resets the peripheral. */
+ usart_stop(uartp);
+ /* Disables the peripheral. */
+#if AVR_UART_USE_USART1 == TRUE
+ if (&USART1D == uartp) {
+ /* TODO: Implement the DMA part here. */
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_send(UARTDriver *uartp, size_t n, const uint8_t *txbuf) {
+
+ /* TODO: Add support of DMA. */
+ while (n--) {
+ while (!((uartp->usart->STATUS & USART_DREIF_bm) != 0));
+ uartp->usart->DATA = *txbuf;
+ txbuf++;
+ }
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not transmitted by the
+ * stopped transmit operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_send(UARTDriver *uartp) {
+
+ (void)uartp;
+
+ return 0;
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+ (void)uartp;
+ (void)n;
+ (void)rxbuf;
+
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not received by the
+ * stopped receive operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_receive(UARTDriver *uartp) {
+
+ (void)uartp;
+
+ return 0;
+}
+
+#endif /* HAL_USE_UART == TRUE */
+
+/** @} */
diff --git a/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.h b/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.h
new file mode 100644
index 000000000..9a53a31a7
--- /dev/null
+++ b/os/hal/ports/AVR/XMEGA/LLD/USARTv1/hal_uart_lld.h
@@ -0,0 +1,448 @@
+/*
+ ChibiOS - Copyright (C) 2016..2018 Theodore Ateba
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file USARTv1/hal_uart_lld.h
+ * @brief AVR UART subsystem low level driver header.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#ifndef HAL_UART_LLD_H
+#define HAL_UART_LLD_H
+
+#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
+
+/*==========================================================================*/
+/* Driver constants. */
+/*==========================================================================*/
+
+/**
+ * @brief USART communication mode enumerations.
+ */
+typedef enum {
+ USART_CMODE_ASYNCHRONOUS = 0x00, /**< USART asynchronous mode. */
+ USART_CMODE_SYNCHRONOUS = 0x01, /**< USART synchronous mode. */
+ USART_CMODE_IRCOM = 0x10, /**< USART IRCOM mode. */
+ USART_CMODE_MSPI = 0x11, /**< USART MSPI mode. */
+} usartcmode_t;
+
+/**
+ * @brief USART parity mode enumerations.
+ */
+typedef enum {
+ USART_PMODE_DISABLE = 0x00, /**< USART use no parity. */
+ USART_PMODE_EVEN = 0x10, /**< USART use even parity. */
+ USART_PMODE_ODD = 0x11 /**< USART use odd parity. */
+} usartpmode_t;
+
+/**
+ * @brief USART stop bit mode enumerations.
+ */
+typedef enum {
+ USART_SBMODE_1BIT = FALSE, /**< USART use 1 stop bit. */
+ USART_SBMODE_2BIT = TRUE /**< USART use 2 stop bit. */
+} usartsbmode_t;
+
+/**
+ * @brief character size enumerations.
+ */
+typedef enum {
+ USART_CHSIZE_5BIT = 0x00, /**< USART use 5 bytes for data. */
+ USART_CHSIZE_6BIT = 0x01, /**< USART use 6 bytes for data. */
+ USART_CHSIZE_7BIT = 0x02, /**< USART use 7 bytes for data. */
+ USART_CHSIZE_8BIT = 0x03, /**< USART use 8 bytes for data. */
+ USART_CHSIZE_9BIT = 0x07 /**< USART use 9 bytes for data. */
+} usartchsize_t;
+
+/*==========================================================================*/
+/* Driver pre-compile time settings. */
+/*==========================================================================*/
+
+/**
+ * @name PLATFORM configuration options
+ * @{
+ */
+
+/**
+ * @brief UART driver on USART1 (USARTC0) enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(AVR_UART_USE_USART1) || defined(__DOXYGEN__)
+#define AVR_UART_USE_USART1 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART2 (USARTC1) enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(AVR_UART_USE_USART2) || defined(__DOXYGEN__)
+#define AVR_UART_USE_UART1 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART3 (USARTD0) enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(AVR_UART_USE_USART3) || defined(__DOXYGEN__)
+#define AVR_UART_USE_USART3 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART4 (USARTD1) enable switch.
+ * @details If set to @p TRUE the support for USART4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(AVR_UART_USE_USART4) || defined(__DOXYGEN__)
+#define AVR_UART_USE_USART4 FALSE
+#endif
+
+/**
+ * @brief UART driver on USARTE0 enable switch.
+ * @details If set to @p TRUE the support for USARTE0 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(AVR_UART_USE_USART5) || defined(__DOXYGEN__)
+#define AVR_UART_USE_USART5 FALSE
+#endif
+
+/**
+ * @brief USART1 (USARTC0) interrupt priority level setting.
+ */
+#if !defined(AVR_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART1_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART2 (USARTC1) interrupt priority level setting.
+ */
+#if !defined(AVR_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART2_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 (USARTD0) interrupt priority level setting.
+ */
+#if !defined(AVR_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART3_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART4 (USARTD1) interrupt priority level setting.
+ */
+#if !defined(AVR_UART_USART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART4_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART5 (USARTE0) interrupt priority level setting.
+ */
+#if !defined(AVR_UART_USART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART5_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART1 (USARTC0) DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(AVR_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART1_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART2 (USARTC1) DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(AVR_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART2_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART3 (USARTD0) DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(AVR_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART3_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART4 (USARTD1) DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(AVR_UART_USART4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART4_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART5 (USARTE0) DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(AVR_UART_USART5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define AVR_UART_USART5_DMA_PRIORITY 0
+#endif
+/** @} */
+
+/*==========================================================================*/
+/* Derived constants and error checks. */
+/*==========================================================================*/
+
+#if !AVR_UART_USE_USART1 && !AVR_UART_USE_USART2 && \
+ !AVR_UART_USE_USART3 && !AVR_UART_USE_USART4 && \
+ !AVR_UART_USE_USART5
+#error "UART driver activated but no USART peripheral assigned"
+#endif
+
+/*==========================================================================*/
+/* Driver data structures and types. */
+/*==========================================================================*/
+
+/**
+ * @brief UART driver condition flags type.
+ */
+typedef uint8_t uartflags_t;
+
+/**
+ * @brief Type of structure representing an UART driver.
+ */
+typedef struct UARTDriver UARTDriver;
+
+/**
+ * @brief Generic UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+typedef void (*uartcb_t)(UARTDriver *uartp);
+
+/**
+ * @brief Character received UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object triggering the
+ * callback
+ * @param[in] c received character
+ */
+typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
+
+/**
+ * @brief Receive error UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object triggering the
+ * callback
+ * @param[in] e receive error mask
+ */
+typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
+
+/**
+ * @brief Driver configuration structure.
+ * @note Implementations may extend this structure to contain more,
+ * architecture dependent, fields.
+ */
+typedef struct {
+ /**
+ * @brief End of transmission buffer callback.
+ */
+ uartcb_t txend1_cb;
+ /**
+ * @brief Physical end of transmission callback.
+ */
+ uartcb_t txend2_cb;
+ /**
+ * @brief Receive buffer filled callback.
+ */
+ uartcb_t rxend_cb;
+ /**
+ * @brief Character received while out if the @p UART_RECEIVE state.
+ */
+ uartccb_t rxchar_cb;
+ /**
+ * @brief Receive error callback.
+ */
+ uartecb_t rxerr_cb;
+ /* End of tihe mandatory fields. */
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t speed;
+ /**
+ * @brief Double transmission speed.
+ */
+ bool clk2x;
+ /**
+ * @brief Multiprocessor communication mode bit.
+ */
+ bool mpcm;
+ /**
+ * @brief Transmission bit 8.
+ */
+ bool txb8;
+ /**
+ * @brief Communication mode.
+ */
+ uint8_t cmode;
+ /**
+ * @brief Parity mode.
+ */
+ uint8_t pmode;
+ /**
+ * @brief Stop bit mode.
+ */
+ bool sbmode;
+ /**
+ * @brief Caractere size.
+ */
+ uint8_t chsize;
+} UARTConfig;
+
+/**
+ * @brief Structure representing an UART driver.
+ * @note Implementations may extend this structure to contain more,
+ * architecture dependent, fields.
+ */
+struct UARTDriver {
+ /**
+ * @brief Driver state.
+ */
+ uartstate_t state;
+ /**
+ * @brief Transmitter state.
+ */
+ uarttxstate_t txstate;
+ /**
+ * @brief Receiver state.
+ */
+ uartrxstate_t rxstate;
+ /**
+ * @brief Current configuration data.
+ */
+ const UARTConfig *config;
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Synchronization flag for transmit operations.
+ */
+ bool early;
+ /**
+ * @brief Waiting thread on RX.
+ */
+ thread_reference_t threadrx;
+ /**
+ * @brief Waiting thread on TX.
+ */
+ thread_reference_t threadtx;
+#endif /* UART_USE_WAIT */
+#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the peripheral.
+ */
+ mutex_t mutex;
+#endif /* UART_USE_MUTUAL_EXCLUSION */
+#if defined(UART_DRIVER_EXT_FIELDS)
+ UART_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields. */
+ /**
+ * @brief Pointer to the USART registers block.
+ */
+ USART_t *usart;
+ /**
+ * @brief Clock frequency for the associated USART/UART.
+ */
+ uint32_t clock;
+ /**
+ * @brief DMA mode bit mask.
+ */
+ uint32_t dmamode;
+ /**
+ * @brief Receive DMA channel.
+ */
+ const DMA_t *dmarx;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const DMA_t *dmatx;
+ /**
+ * @brief Default receive buffer while into @p UART_RX_IDLE state.
+ */
+ volatile uint16_t rxbuf;
+};
+
+/*==========================================================================*/
+/* Driver macros. */
+/*==========================================================================*/
+
+/**
+ * @brief This is a macro function to calcul BSEL value according to
+ * the baudrate selected by the user.
+ *
+ * @param[in] baud the baudrate to be configure
+ */
+#define get_bsel(baud) (F_CPU/(16*baud))-1
+
+/*==========================================================================*/
+/* External declarations. */
+/*==========================================================================*/
+
+#if (AVR_UART_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
+extern UARTDriver USART1D;
+#endif
+
+#if (AVR_UART_USE_USART2 == TRUE) && !defined(__DOXYGEN__)
+extern UARTDriver USART2D;
+#endif
+
+#if (AVR_UART_USE_USART3 == TRUE) && !defined(__DOXYGEN__)
+extern UARTDriver USART3D;
+#endif
+
+#if (AVR_UART_USE_USART4 == TRUE) && !defined(__DOXYGEN__)
+extern UARTDriver USART4D;
+#endif
+
+#if (AVR_UART_USE_USART5 == TRUE) && !defined(__DOXYGEN__)
+extern UARTDriver USART5D;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void uart_lld_init(void);
+ void uart_lld_start(UARTDriver *uartp);
+ void uart_lld_stop(UARTDriver *uartp);
+ void uart_lld_start_send(UARTDriver *uartp, size_t n, const uint8_t *txbuf);
+ size_t uart_lld_stop_send(UARTDriver *uartp);
+ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
+ size_t uart_lld_stop_receive(UARTDriver *uartp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_UART == TRUE */
+
+#endif /* HAL_UART_LLD_H */
+
+/** @} */