[PATCH 1/2] bsp/atsam: Merge USART and UART driver

Christian Mauderer christian.mauderer at embedded-brains.de
Thu Jan 13 07:38:06 UTC 2022


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
---
 bsps/arm/atsam/console/console.c | 286 +++++++------------------------
 1 file changed, 60 insertions(+), 226 deletions(-)

diff --git a/bsps/arm/atsam/console/console.c b/bsps/arm/atsam/console/console.c
index 5e3b36b812..b98beef5fc 100644
--- a/bsps/arm/atsam/console/console.c
+++ b/bsps/arm/atsam/console/console.c
@@ -25,273 +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;
-  }
-
-  while (ctx->transmitting && (csr & US_CSR_TXRDY) != 0) {
-    rtems_termios_dequeue_characters(tty, 1);
-    csr = regs->US_CSR;
-  }
-}
-#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_TXRDY;
-  } else {
-    ctx->transmitting = false;
-    regs->US_IDR = US_IDR_TXRDY;
-  }
-#else
-  size_t i;
-
-  for (i = 0; i < len; ++i) {
-    while ((regs->US_CSR & US_CSR_TXRDY) == 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
 };
@@ -338,10 +143,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) {
@@ -354,8 +180,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;
@@ -388,7 +222,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
@@ -492,7 +326,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
     );
-- 
2.31.1



More information about the devel mailing list