MODSERIAL with support for more devices

Dependents:   1D-Pong BMT-K9_encoder BMT-K9-Regelaar programma_filter ... more

Check the cookbook page for more information: https://mbed.org/cookbook/MODSERIAL

Did you add a device? Please send a pull request so we can keep everything in one library instead of many copies. In that case also send a PM, since currently mbed does not inform of new pull requests. I will then also add you to the developers of this library so you can do other changes directly.

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Mon Nov 22 09:58:34 2010 +0000
Parent:
7:ffa4a7cb7f8d
Child:
9:b3cdae80e7a9
Commit message:
1.8

Changed in this revision

ChangeLog.c Show annotated file Show diff for this revision Revisions of this file
GETC.cpp Show annotated file Show diff for this revision Revisions of this file
INIT.cpp Show annotated file Show diff for this revision Revisions of this file
ISR_RX.cpp Show annotated file Show diff for this revision Revisions of this file
ISR_TX.cpp Show annotated file Show diff for this revision Revisions of this file
MACROS.h Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.h Show annotated file Show diff for this revision Revisions of this file
PUTC.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ChangeLog.c	Mon Nov 22 09:19:50 2010 +0000
+++ b/ChangeLog.c	Mon Nov 22 09:58:34 2010 +0000
@@ -1,5 +1,14 @@
 /* $Id:$
 
+1.8 - 22/11/2010
+
+    * Added code so that if a buffer is set to zero length then
+      MODSERIAL defaults to just using the FIFO for that stream
+      thus making the library "fall back" to teh same operation
+      that the Mbed Serial library performs.
+    * Removed dmaSend() function that should have been removed 
+      at 1.7
+    
 1.7 - 21/11/2010
 
     * Remove the DMA enum from MODSERIAL.h as it's not currently 
--- a/GETC.cpp	Mon Nov 22 09:19:50 2010 +0000
+++ b/GETC.cpp	Mon Nov 22 09:58:34 2010 +0000
@@ -28,6 +28,14 @@
 int 
 MODSERIAL::__getc(bool block)
 {
+    // If no buffer is in use fall back to standard RX FIFO usage.
+    // Note, we must block in this case and ignore bool "block" 
+    // so as to maintain compat with Mbed Serial.
+    if (buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
+        while(! MODSERIAL_RBR_HAS_DATA ) ;
+        return (int)(_RBR & 0xFF);
+    }
+
     if (block) { while ( MODSERIAL_RX_BUFFER_EMPTY ) ; } // Blocks.
     else if ( MODSERIAL_RX_BUFFER_EMPTY ) return -1;
     
--- a/INIT.cpp	Mon Nov 22 09:19:50 2010 +0000
+++ b/INIT.cpp	Mon Nov 22 09:58:34 2010 +0000
@@ -40,7 +40,7 @@
     
     if (_base != NULL) {
         buffer_size[RxIrq]     = rxSize;
-        buffer[RxIrq]          = (char *)malloc(buffer_size[RxIrq]);    
+        buffer[RxIrq]          = rxSize > 0 ? (char *)malloc(buffer_size[RxIrq]) : (char *)NULL;
         buffer_in[RxIrq]       = 0;
         buffer_out[RxIrq]      = 0;
         buffer_count[RxIrq]    = 0;
@@ -48,7 +48,7 @@
         Serial::attach(this, &MODSERIAL::isr_rx, Serial::RxIrq);        
         
         buffer_size[TxIrq]     = txSize;
-        buffer[TxIrq]          = (char *)malloc(buffer_size[TxIrq]);
+        buffer[TxIrq]          = txSize > 0 ? (char *)malloc(buffer_size[TxIrq]) : (char *)NULL;
         buffer_in[TxIrq]       = 0;
         buffer_out[TxIrq]      = 0;
         buffer_count[TxIrq]    = 0;
@@ -59,14 +59,6 @@
         error("MODSERIAL must have a defined UART to function.");
     }
     
-    if (!txBufferSane()) {
-        error("Failed to allocate memory for TX buffer");
-    }
-    
-    if (!rxBufferSane()) {
-        error("Failed to allocate memory for RX buffer");
-    }
-    
     _FCR = MODSERIAL_FIFO_ENABLE | MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET;
     
     enableIrq();
--- a/ISR_RX.cpp	Mon Nov 22 09:19:50 2010 +0000
+++ b/ISR_RX.cpp	Mon Nov 22 09:58:34 2010 +0000
@@ -28,7 +28,10 @@
 void 
 MODSERIAL::isr_rx(void)
 {
-    if (! _base ) return;
+    if (! _base || buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
+        _isr[RxIrq].call(); 
+        return;
+    } 
     
     while( MODSERIAL_RBR_HAS_DATA ) {
         rxc = (char)(_RBR & 0xFF); 
--- a/ISR_TX.cpp	Mon Nov 22 09:19:50 2010 +0000
+++ b/ISR_TX.cpp	Mon Nov 22 09:58:34 2010 +0000
@@ -28,7 +28,10 @@
 void 
 MODSERIAL::isr_tx(bool doCallback)
 {
-    if (! _base ) return;
+    if (! _base || buffer_size[TxIrq] == 0 || buffer[TxIrq] == (char *)NULL) {
+        _isr[TxIrq].call(); 
+        return;
+    }
     
     while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) {
         _THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]);
--- a/MACROS.h	Mon Nov 22 09:19:50 2010 +0000
+++ b/MACROS.h	Mon Nov 22 09:58:34 2010 +0000
@@ -38,6 +38,15 @@
 #define MODSERIAL_FDR  0x28
 #define MODSERIAL_TER  0x30
 
+#define MODSERIAL_LSR_RDR  (1UL << 0)
+#define MODSERIAL_LSR_OE   (1UL << 1)
+#define MODSERIAL_LSR_PE   (1UL << 2)
+#define MODSERIAL_LSR_FE   (1UL << 3)
+#define MODSERIAL_LSR_BR   (1UL << 4)
+#define MODSERIAL_LSR_THRE (1UL << 5)
+#define MODSERIAL_LSR_TEMT (1UL << 6)
+#define MODSERIAL_LSR_RXFE (1UL << 7)
+
 #define MODSERIAL_FIFO_ENABLE   1
 #define MODSERIAL_FIFO_RX_RESET 2
 #define MODSERIAL_FIFO_TX_RESET 4
@@ -54,8 +63,8 @@
 #define MODSERIAL_TX_BUFFER_FULL  (buffer_count[TxIrq]==buffer_size[TxIrq])
 #define MODSERIAL_RX_BUFFER_FULL  (buffer_count[RxIrq]==buffer_size[RxIrq])
 
-#define MODSERIAL_THR_HAS_SPACE (int)_LSR&(1UL<<5)
-#define MODSERIAL_TEMT_IS_EMPTY (int)_LSR&(1UL<<6)
-#define MODSERIAL_RBR_HAS_DATA  (int)_LSR&0x1
+#define MODSERIAL_THR_HAS_SPACE (int)_LSR&MODSERIAL_LSR_THRE
+#define MODSERIAL_TEMT_IS_EMPTY (int)_LSR&MODSERIAL_LSR_TEMT
+#define MODSERIAL_RBR_HAS_DATA  (int)_LSR&MODSERIAL_LSR_RDR
 
 #endif
--- a/MODSERIAL.h	Mon Nov 22 09:19:50 2010 +0000
+++ b/MODSERIAL.h	Mon Nov 22 09:58:34 2010 +0000
@@ -501,15 +501,7 @@
      * @ingroup API
      */
     void rxBufferFlush(void) { flushBuffer(RxIrq); }
-    
-    /**
-     * Function: dmaSend
-     *  
-     * Remove all bytes from the RX buffer.
-     * @ingroup API
-     */
-    int dmaSend(char *buffer, int length, dmaChannel q = Channel7);
-    
+        
     /**
      * Function: getcNb
      *
--- a/PUTC.cpp	Mon Nov 22 09:19:50 2010 +0000
+++ b/PUTC.cpp	Mon Nov 22 09:58:34 2010 +0000
@@ -27,41 +27,47 @@
 
 int
 MODSERIAL::__putc(int c, bool block) {
-    uint32_t lsr = (uint32_t)*((char *)_base + MODSERIAL_LSR);
     
-    if (lsr & 0x20 && MODSERIAL_TX_BUFFER_EMPTY ) {
+    // If no buffer is in use fall back to standard TX FIFO usage.
+    // Note, we must block in this case and ignore bool "block" 
+    // so as to maintain compat with Mbed Serial.
+    if (buffer[TxIrq] == (char *)NULL || buffer_size[TxIrq] == 0) {
+        while (! MODSERIAL_THR_HAS_SPACE) ; // Wait for space in the TX FIFO.
+        _THR = (uint32_t)c;
+        return 0;
+    }
+    
+    if ( MODSERIAL_THR_HAS_SPACE && MODSERIAL_TX_BUFFER_EMPTY ) {
         _THR = (uint32_t)c;
     }
     else {
-        if (buffer[TxIrq] != (char *)NULL) {
-            if (block) {
-                while ( MODSERIAL_TX_BUFFER_FULL ) {  // Blocks!
-                    // If putc() is called from an ISR then we are stuffed
-                    // because in an ISR no bytes from the TX buffer will 
-                    // get transferred to teh TX FIFOs while we block here.
-                    // So, to work around this, instead of sitting in a 
-                    // loop waiting for space in the TX buffer (which will
-                    // never happen in IRQ context), check to see if the
-                    // TX FIFO has space available to move bytes from the
-                    // TX buffer to TX FIFO to make space. The easiest way
-                    // to do this is to poll the isr_tx() function while we
-                    // are blocking.
-                    isr_tx(false);
-                }
+        if (block) {
+            while ( MODSERIAL_TX_BUFFER_FULL ) {  // Blocks!
+                // If putc() is called from an ISR then we are stuffed
+                // because in an ISR no bytes from the TX buffer will 
+                // get transferred to teh TX FIFOs while we block here.
+                // So, to work around this, instead of sitting in a 
+                // loop waiting for space in the TX buffer (which will
+                // never happen in IRQ context), check to see if the
+                // TX FIFO has space available to move bytes from the
+                // TX buffer to TX FIFO to make space. The easiest way
+                // to do this is to poll the isr_tx() function while we
+                // are blocking.
+                isr_tx(false);
             }
-            else if( MODSERIAL_TX_BUFFER_FULL ) {
-                buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
-                _isr[TxOvIrq].call();
-                return -1;
-            }
-            buffer[TxIrq][buffer_in[TxIrq]] = c;
-            buffer_count[TxIrq]++;
-            buffer_in[TxIrq]++;
-            if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
-                buffer_in[TxIrq] = 0;
-            }            
-            _IER |= 0x2;
+        }
+        else if( MODSERIAL_TX_BUFFER_FULL ) {
+            buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
+            _isr[TxOvIrq].call();
+            return -1;
         }
+        buffer[TxIrq][buffer_in[TxIrq]] = c;
+        buffer_count[TxIrq]++;
+        buffer_in[TxIrq]++;
+        if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
+            buffer_in[TxIrq] = 0;
+        }            
+        _IER |= 0x2;        
     }
       
     return 0;