MODSERIAL with support for more devices

Fork of MODSERIAL by Erik -

Revision:
8:775f860e94d3
Parent:
6:c8f77fe1cc10
Child:
9:b3cdae80e7a9
diff -r ffa4a7cb7f8d -r 775f860e94d3 PUTC.cpp
--- 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;