summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2022-01-11 09:20:53 +0100
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2022-01-18 08:50:04 +0100
commitd9c0dd3c32aff23e33a567378b89f89342291e15 (patch)
tree303f8b934d30695ef4adca957671ef885520564b
parentuntar: Make behavior similar to GNU or BSD tar (diff)
downloadrtems-d9c0dd3c32aff23e33a567378b89f89342291e15.tar.bz2
bsp/atsam: Merge USART and UART driver
If no extended features of the USART are used and if the comparison feature of the UART is not used, the two modules are compatible. The drivers were nearly identical except for some names of the defines. This patch merges the two drivers into one. Update #4577
-rw-r--r--bsps/arm/atsam/console/console.c285
1 files changed, 60 insertions, 225 deletions
diff --git a/bsps/arm/atsam/console/console.c b/bsps/arm/atsam/console/console.c
index d51d2ace7d..a5a981fb3e 100644
--- a/bsps/arm/atsam/console/console.c
+++ b/bsps/arm/atsam/console/console.c
@@ -25,272 +25,78 @@
typedef struct {
rtems_termios_device_context base;
- Usart *regs;
+ Uart *regs;
rtems_vector_number irq;
uint32_t id;
bool console;
+ bool is_usart;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
bool transmitting;
#endif
-} atsam_usart_context;
+} atsam_uart_context;
-static atsam_usart_context atsam_usart_instances[] = {
+static atsam_uart_context atsam_usart_instances[] = {
{
- .regs = USART0,
+ .regs = (Uart *)USART0,
.irq = USART0_IRQn,
- .id = ID_USART0
+ .id = ID_USART0,
+ .is_usart = true,
}
#ifdef USART1
, {
- .regs = USART1,
+ .regs = (Uart *)USART1,
.irq = USART1_IRQn,
- .id = ID_USART1
+ .id = ID_USART1,
+ .is_usart = true,
}
#endif
#ifdef USART2
, {
- .regs = USART2,
+ .regs = (Uart *)USART2,
.irq = USART2_IRQn,
- .id = ID_USART2
- }
-#endif
-};
-
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
-static void atsam_usart_interrupt(void *arg)
-{
- rtems_termios_tty *tty = arg;
- atsam_usart_context *ctx = rtems_termios_get_device_context(tty);
- Usart *regs = ctx->regs;
- uint32_t csr = regs->US_CSR;
-
- while ((csr & US_CSR_RXRDY) != 0) {
- char c = (char) regs->US_RHR;
-
- rtems_termios_enqueue_raw_characters(tty, &c, 1);
-
- csr = regs->US_CSR;
- }
-
- if (ctx->transmitting && (csr & US_CSR_TXEMPTY) != 0) {
- rtems_termios_dequeue_characters(tty, 1);
- }
-}
-#endif
-
-static bool atsam_usart_set_attributes(
- rtems_termios_device_context *base,
- const struct termios *term
-)
-{
- atsam_usart_context *ctx = (atsam_usart_context *) base;
- Usart *regs = ctx->regs;
- rtems_termios_baud_t baud;
- uint32_t mr;
-
- baud = rtems_termios_baud_to_number(term->c_ospeed);
- regs->US_BRGR = (BOARD_MCK / baud) / 16;
-
- if ((term->c_cflag & CREAD) != 0) {
- regs->US_CR = US_CR_RXEN | US_CR_TXEN;
- } else {
- regs->US_CR = US_CR_TXEN;
- }
-
- mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK;
-
- switch (term->c_cflag & CSIZE) {
- case CS5:
- mr |= US_MR_CHRL_5_BIT;
- break;
- case CS6:
- mr |= US_MR_CHRL_6_BIT;
- break;
- case CS7:
- mr |= US_MR_CHRL_7_BIT;
- break;
- default:
- mr |= US_MR_CHRL_8_BIT;
- break;
- }
-
- if ((term->c_cflag & PARENB) != 0) {
- if ((term->c_cflag & PARODD) != 0) {
- mr |= US_MR_PAR_ODD;
- } else {
- mr |= US_MR_PAR_EVEN;
- }
- } else {
- mr |= US_MR_PAR_NO;
- }
-
- if ((term->c_cflag & CSTOPB) != 0) {
- mr |= US_MR_NBSTOP_2_BIT;
- } else {
- mr |= US_MR_NBSTOP_1_BIT;
- }
-
- regs->US_MR = mr;
-
- return true;
-}
-
-static bool atsam_usart_first_open(
- rtems_termios_tty *tty,
- rtems_termios_device_context *base,
- struct termios *term,
- rtems_libio_open_close_args_t *args
-)
-{
- atsam_usart_context *ctx = (atsam_usart_context *) base;
- Usart *regs = ctx->regs;
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- rtems_status_code sc;
-#endif
-
- regs->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
- regs->US_IDR = 0xffffffff;
-
- PMC_EnablePeripheral(ctx->id);
-
- rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD);
- atsam_usart_set_attributes(base, term);
-
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- regs->US_IER = US_IDR_RXRDY;
- sc = rtems_interrupt_handler_install(
- ctx->irq,
- "USART",
- RTEMS_INTERRUPT_SHARED,
- atsam_usart_interrupt,
- tty
- );
- if (sc != RTEMS_SUCCESSFUL) {
- return false;
- }
-#endif
-
- return true;
-}
-
-static void atsam_usart_last_close(
- rtems_termios_tty *tty,
- rtems_termios_device_context *base,
- rtems_libio_open_close_args_t *args
-)
-{
- atsam_usart_context *ctx = (atsam_usart_context *) base;
-
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- rtems_interrupt_handler_remove(ctx->irq, atsam_usart_interrupt, tty);
-#endif
-
- if (!ctx->console) {
- PMC_DisablePeripheral(ctx->id);
- }
-}
-
-static void atsam_usart_write(
- rtems_termios_device_context *base,
- const char *buf,
- size_t len
-)
-{
- atsam_usart_context *ctx = (atsam_usart_context *) base;
- Usart *regs = ctx->regs;
-
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- if (len > 0) {
- ctx->transmitting = true;
- regs->US_THR = buf[0];
- regs->US_IER = US_IDR_TXEMPTY;
- } else {
- ctx->transmitting = false;
- regs->US_IDR = US_IDR_TXEMPTY;
- }
-#else
- size_t i;
-
- for (i = 0; i < len; ++i) {
- while ((regs->US_CSR & US_CSR_TXEMPTY) == 0) {
- /* Wait */
- }
-
- regs->US_THR = buf[i];
+ .id = ID_USART2,
+ .is_usart = true,
}
#endif
-}
-
-#ifndef ATSAM_CONSOLE_USE_INTERRUPTS
-static int atsam_usart_read(rtems_termios_device_context *base)
-{
- atsam_usart_context *ctx = (atsam_usart_context *) base;
- Usart *regs = ctx->regs;
-
- if ((regs->US_CSR & US_CSR_RXRDY) != 0) {
- return (char) regs->US_RHR;
- } else {
- return -1;
- }
-}
-#endif
-
-static const rtems_termios_device_handler atsam_usart_handler = {
- .first_open = atsam_usart_first_open,
- .last_close = atsam_usart_last_close,
- .write = atsam_usart_write,
- .set_attributes = atsam_usart_set_attributes,
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- .mode = TERMIOS_IRQ_DRIVEN
-#else
- .poll_read = atsam_usart_read,
- .mode = TERMIOS_POLLED
-#endif
};
-typedef struct {
- rtems_termios_device_context base;
- Uart *regs;
- rtems_vector_number irq;
- uint32_t id;
- bool console;
-#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
- bool transmitting;
-#endif
-} atsam_uart_context;
-
static atsam_uart_context atsam_uart_instances[] = {
{
.regs = UART0,
.irq = UART0_IRQn,
- .id = ID_UART0
+ .id = ID_UART0,
+ .is_usart = false,
}
#ifdef UART1
, {
.regs = UART1,
.irq = UART1_IRQn,
- .id = ID_UART1
+ .id = ID_UART1,
+ .is_usart = false,
}
#endif
#ifdef UART2
, {
.regs = UART2,
.irq = UART2_IRQn,
- .id = ID_UART2
+ .id = ID_UART2,
+ .is_usart = false,
}
#endif
#ifdef UART3
, {
.regs = UART3,
.irq = UART3_IRQn,
- .id = ID_UART3
+ .id = ID_UART3,
+ .is_usart = false,
}
#endif
#ifdef UART4
, {
.regs = UART4,
.irq = UART4_IRQn,
- .id = ID_UART4
+ .id = ID_UART4,
+ .is_usart = false,
}
#endif
};
@@ -336,10 +142,31 @@ static bool atsam_uart_set_attributes(
regs->UART_CR = UART_CR_TXEN;
}
- mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK;
-
- if ((term->c_cflag & CSIZE) != CS8) {
- return false;
+ if (ctx->is_usart) {
+ mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK;
+ } else {
+ mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK;
+ }
+
+ if (ctx->is_usart) {
+ switch (term->c_cflag & CSIZE) {
+ case CS5:
+ mr |= US_MR_CHRL_5_BIT;
+ break;
+ case CS6:
+ mr |= US_MR_CHRL_6_BIT;
+ break;
+ case CS7:
+ mr |= US_MR_CHRL_7_BIT;
+ break;
+ default:
+ mr |= US_MR_CHRL_8_BIT;
+ break;
+ }
+ } else {
+ if ((term->c_cflag & CSIZE) != CS8) {
+ return false;
+ }
}
if ((term->c_cflag & PARENB) != 0) {
@@ -352,8 +179,16 @@ static bool atsam_uart_set_attributes(
mr |= UART_MR_PAR_NO;
}
- if ((term->c_cflag & CSTOPB) != 0) {
- return false;
+ if (ctx->is_usart) {
+ if ((term->c_cflag & CSTOPB) != 0) {
+ mr |= US_MR_NBSTOP_2_BIT;
+ } else {
+ mr |= US_MR_NBSTOP_1_BIT;
+ }
+ } else {
+ if ((term->c_cflag & CSTOPB) != 0) {
+ return false;
+ }
}
regs->UART_MR = mr;
@@ -386,7 +221,7 @@ static bool atsam_uart_first_open(
regs->UART_IER = UART_IDR_RXRDY;
sc = rtems_interrupt_handler_install(
ctx->irq,
- "UART",
+ ctx->is_usart ? "USART" : "UART",
RTEMS_INTERRUPT_SHARED,
atsam_uart_interrupt,
tty
@@ -490,7 +325,7 @@ rtems_status_code console_initialize(
usart[sizeof(usart) - 2] = (char) ('0' + i);
rtems_termios_device_install(
&usart[0],
- &atsam_usart_handler,
+ &atsam_uart_handler,
NULL,
&atsam_usart_instances[i].base
);