[rtems commit] bsp/tqm8xx: Fix polled vs. interrupt output

Sebastian Huber sebh at rtems.org
Mon Sep 17 07:00:00 UTC 2018


Module:    rtems
Branch:    master
Commit:    688e101a654f9314c09fab2319b2d0742e0e2313
Changeset: http://git.rtems.org/rtems/commit/?id=688e101a654f9314c09fab2319b2d0742e0e2313

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Sep 14 07:30:46 2018 +0200

bsp/tqm8xx: Fix polled vs. interrupt output

Update #3513.

---

 bsps/powerpc/include/mpc8xx.h         |   2 +-
 bsps/powerpc/tqm8xx/console/console.c | 136 ++++++++++++++++++++--------------
 2 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/bsps/powerpc/include/mpc8xx.h b/bsps/powerpc/include/mpc8xx.h
index f0134ed..60baf60 100644
--- a/bsps/powerpc/include/mpc8xx.h
+++ b/bsps/powerpc/include/mpc8xx.h
@@ -683,7 +683,7 @@ typedef struct m8xxSPIparms_ {
 typedef struct m8xxBufferDescriptor_ {
   volatile uint16_t          status;
   uint16_t          	   length;
-  volatile void           	   *buffer;
+  void           	   *buffer;
 } m8xxBufferDescriptor_t;
 
 /*
diff --git a/bsps/powerpc/tqm8xx/console/console.c b/bsps/powerpc/tqm8xx/console/console.c
index a4f2cfd..0746ba5 100644
--- a/bsps/powerpc/tqm8xx/console/console.c
+++ b/bsps/powerpc/tqm8xx/console/console.c
@@ -105,7 +105,7 @@
  */
 #define SCC_RXBD_CNT 4
 #define SCC_TXBD_CNT 4
-typedef volatile char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE];
+typedef char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE];
 
 /*
  * Interrupt-driven callback
@@ -417,6 +417,9 @@ sccInterruptHandler (void *arg)
 {
   rtems_termios_tty *tty = arg;
   m8xx_console_chan_desc_t *cd = rtems_termios_get_device_context(tty);
+  uint16_t status;
+  uint16_t length;
+  void *buffer;
 
   /*
    * Buffer received?
@@ -429,27 +432,30 @@ sccInterruptHandler (void *arg)
     /*
      * process event
      */
-    while ((cd->sccCurrRxBd->status & M8xx_BD_EMPTY) == 0) {
-      rtems_cache_invalidate_multiple_data_lines((void *)cd->sccCurrRxBd->buffer,
-						  cd->sccCurrRxBd->length);
-      rtems_termios_enqueue_raw_characters (tty,
-					    (char *)cd->sccCurrRxBd->buffer,
-					    cd->sccCurrRxBd->length);
+    while (true) {
+      status = cd->sccCurrRxBd->status;
+
+      if ((cd->sccCurrRxBd->status & M8xx_BD_EMPTY) != 0) {
+        break;
+      }
+
+      buffer = cd->sccCurrRxBd->buffer;
+      length = cd->sccCurrRxBd->length;
+      rtems_cache_invalidate_multiple_data_lines(buffer, length);
+      rtems_termios_enqueue_raw_characters (tty, buffer, length);
+
       /*
        * clear status
        */
-      cd->sccCurrRxBd->status =
-	(cd->sccCurrRxBd->status
-	 & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
-	| M8xx_BD_EMPTY;
+      cd->sccCurrRxBd->status = (status & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
+        | M8xx_BD_EMPTY;
       /*
        * advance to next BD
        */
-      if ((cd->sccCurrRxBd->status & M8xx_BD_WRAP) != 0) {
-	cd->sccCurrRxBd = cd->sccFrstRxBd;
-      }
-      else {
-	cd->sccCurrRxBd++;
+      if ((status & M8xx_BD_WRAP) != 0) {
+        cd->sccCurrRxBd = cd->sccFrstRxBd;
+      } else {
+        cd->sccCurrRxBd++;
       }
     }
   }
@@ -467,17 +473,24 @@ sccInterruptHandler (void *arg)
     /*
      * FIXME: multiple dequeue calls for multiple buffers
      */
-    while((cd->sccDequTxBd != cd->sccPrepTxBd) &&
-	  ((cd->sccDequTxBd->status & M8xx_BD_READY) == 0)) {
-      rtems_termios_dequeue_characters (tty, cd->sccDequTxBd->length);
+    while (cd->sccDequTxBd != cd->sccPrepTxBd) {
+      status = cd->sccDequTxBd->status;
+
+      if ((status & M8xx_BD_READY) != 0) {
+        break;
+      }
+
+      if ((status & M8xx_BD_INTERRUPT) != 0) {
+        rtems_termios_dequeue_characters (tty, cd->sccDequTxBd->length);
+      }
+
       /*
        * advance to next BD
        */
-      if ((cd->sccDequTxBd->status & M8xx_BD_WRAP) != 0) {
-	cd->sccDequTxBd = cd->sccFrstTxBd;
-      }
-      else {
-	cd->sccDequTxBd++;
+      if ((status & M8xx_BD_WRAP) != 0) {
+        cd->sccDequTxBd = cd->sccFrstTxBd;
+      } else {
+        cd->sccDequTxBd++;
       }
     }
   }
@@ -730,23 +743,25 @@ sccPollRead (rtems_termios_device_context *base)
 static void
 sccInterruptWrite (rtems_termios_device_context *base, const char *buf, size_t len)
 {
+  m8xx_console_chan_desc_t *cd = (m8xx_console_chan_desc_t *)base;
+
   if (len > 0) {
-    m8xx_console_chan_desc_t *cd = (m8xx_console_chan_desc_t *)base;
-    if ((cd->sccPrepTxBd->status & M8xx_BD_READY) == 0) {
-      cd->sccPrepTxBd->buffer = (char *)buf;
+    uint16_t status = cd->sccPrepTxBd->status;
+
+    if ((status & M8xx_BD_READY) == 0) {
+      cd->sccPrepTxBd->buffer = RTEMS_DECONST(char*, buf);
       cd->sccPrepTxBd->length = len;
-      rtems_cache_flush_multiple_data_lines((const void *)buf,len);
+      rtems_cache_flush_multiple_data_lines(buf, len);
+
       /*
        * clear status, set ready bit
        */
-      cd->sccPrepTxBd->status =
-        (cd->sccPrepTxBd->status
-         & M8xx_BD_WRAP)
+      cd->sccPrepTxBd->status = (status & M8xx_BD_WRAP)
         | M8xx_BD_READY | M8xx_BD_INTERRUPT;
-      if ((cd->sccPrepTxBd->status & M8xx_BD_WRAP) != 0) {
+
+      if ((status & M8xx_BD_WRAP) != 0) {
         cd->sccPrepTxBd = cd->sccFrstTxBd;
-      }
-      else {
+      } else {
         cd->sccPrepTxBd++;
       }
     }
@@ -757,29 +772,38 @@ static void
 sccPollWrite (rtems_termios_device_context *base, const char *buf, size_t len)
 {
   m8xx_console_chan_desc_t *cd = (m8xx_console_chan_desc_t *)base;
-  static char txBuf[CONS_CHN_CNT][SCC_TXBD_CNT];
-  int chan = cd->chan;
-  int bd_used;
-
-  while (len--) {
-    while (cd->sccPrepTxBd->status & M8xx_BD_READY)
-      continue;
-    bd_used = cd->sccPrepTxBd - cd->sccFrstTxBd;
-    txBuf[chan][bd_used] = *buf++;
-      rtems_cache_flush_multiple_data_lines((const void *)&txBuf[chan][bd_used],
-					    sizeof(txBuf[chan][bd_used]));
-    cd->sccPrepTxBd->buffer = &(txBuf[chan][bd_used]);
-    cd->sccPrepTxBd->length = 1;
-    cd->sccPrepTxBd->status =
-      (cd->sccPrepTxBd->status
-       & M8xx_BD_WRAP)
-      | M8xx_BD_READY;
-    if ((cd->sccPrepTxBd->status & M8xx_BD_WRAP) != 0) {
-      cd->sccPrepTxBd = cd->sccFrstTxBd;
-    }
-    else {
-      cd->sccPrepTxBd++;
+  volatile m8xxBufferDescriptor_t *bd = NULL;
+
+  rtems_cache_flush_multiple_data_lines (buf, len);
+
+  while (bd == NULL) {
+    rtems_interrupt_level level;
+    uint16_t status;
+
+    rtems_interrupt_disable(level);
+
+    bd = cd->sccPrepTxBd;
+    status = bd->status;
+
+    if ((status & M8xx_BD_READY) == 0) {
+      bd->buffer = RTEMS_DECONST (char *, buf);
+      bd->length = len;
+      bd->status = (status & M8xx_BD_WRAP) | M8xx_BD_READY;
+
+      if ((status & M8xx_BD_WRAP) != 0) {
+        cd->sccPrepTxBd = cd->sccFrstTxBd;
+      } else {
+        cd->sccPrepTxBd++;
+      }
+    } else {
+      bd = NULL;
     }
+
+    rtems_interrupt_enable(level);
+  }
+
+  while ((bd->status & M8xx_BD_READY) != 0) {
+    /* Wait */
   }
 }
 



More information about the vc mailing list