MODSERIAL with support for KL25Z + RTOS (beta, putc + puts currently)

Dependents:   kl25z_USB_4

Fork of MODSERIAL by Erik -

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Sun Nov 21 03:31:51 2010 +0000
Parent:
1:b7e435fbfe8e
Child:
3:0f10f536456e
Commit message:
1.4

Changed in this revision

ChangeLog.c Show annotated file Show diff for this revision Revisions of this file
FLUSH.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
MODSERIAL.cpp 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
example.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ChangeLog.c	Sun Nov 21 02:15:07 2010 +0000
+++ b/ChangeLog.c	Sun Nov 21 03:31:51 2010 +0000
@@ -1,5 +1,21 @@
 /* $Id:$
+
+1.3 - 21/11/2010
+
+    * Fixed a macro problem with txIsBusy()
+    * Started adding code to use "block data" sending using DMA
     
+1.2 - 21/11/2010
+
+    * Removed unsed variables from flushBuffer()
+    * Fixed a bug where both RX AND TX fifos are cleared/reset 
+      when just TX OR RX should be cleared.
+    * Fixed a bug that cleared IIR when in fact it should be left
+      alone so that any pending interrupt after flush is handled.
+    * Merged setBase() into init() as it wasn't required anywhere else.
+    * Changed init() to enforce _uidx is set by Serial to define the _base
+      address of the Uart in use.
+        
 1.1 - 20/11/2010
 
     * Added this file
--- a/FLUSH.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/FLUSH.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -28,9 +28,6 @@
 void
 MODSERIAL::flushBuffer(IrqType type)
 {
-    volatile char c __attribute__((unused));
-    volatile uint32_t iir __attribute__((unused));
-    
     uint32_t ier = _IER;
     switch(type) {
         case TxIrq: _IER &= ~(1UL << 1); break;
@@ -40,9 +37,10 @@
     buffer_out[type]      = 0;
     buffer_count[type]    = 0;
     buffer_overflow[type] = 0;  
-    _FCR = MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET;
-    _FCR = MODSERIAL_FIFO_ENABLE;
-    iir = _IIR;
+    switch(type) {
+        case TxIrq: _FCR = MODSERIAL_FIFO_TX_RESET; break;
+        case RxIrq: _FCR = MODSERIAL_FIFO_RX_RESET; break;
+    }
     _IER = ier;
 }
 
--- a/INIT.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/INIT.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -30,7 +30,13 @@
 {
     disableIrq();
     
-    setBase();
+    switch(_uidx) {
+        case 0:   _base = LPC_UART0; break;
+        case 1:   _base = LPC_UART1; break;
+        case 2:   _base = LPC_UART2; break;
+        case 3:   _base = LPC_UART3; break;
+        default : _base = NULL;      break;
+    }
     
     if (_base != NULL) {
         buffer_size[RxIrq]     = rxSize;
@@ -39,6 +45,7 @@
         buffer_out[RxIrq]      = 0;
         buffer_count[RxIrq]    = 0;
         buffer_overflow[RxIrq] = 0;
+        dmaInUse[RxIrq]        = -1;
         Serial::attach(this, &MODSERIAL::isr_rx, Serial::RxIrq);        
         
         buffer_size[TxIrq]     = txSize;
@@ -47,8 +54,12 @@
         buffer_out[TxIrq]      = 0;
         buffer_count[TxIrq]    = 0;
         buffer_overflow[TxIrq] = 0;
+        dmaInUse[TxIrq]        = -1;
         Serial::attach(this, &MODSERIAL::isr_tx, Serial::TxIrq);
     }
+    else {
+        error("MODSERIAL must have a defined UART to function.");
+    }
     
     if (!txBufferSane()) {
         error("Failed to allocate memory for TX buffer");
@@ -63,16 +74,4 @@
     enableIrq();
 }
 
-void 
-MODSERIAL::setBase(void)
-{
-    switch(_uidx) {
-        case 0:   _base = LPC_UART0; break;
-        case 1:   _base = LPC_UART1; break;
-        case 2:   _base = LPC_UART2; break;
-        case 3:   _base = LPC_UART3; break;
-        default : _base = NULL;      break;
-    }
-}
-
 }; // namespace AjK ends
--- a/ISR_RX.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/ISR_RX.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -28,7 +28,9 @@
 void 
 MODSERIAL::isr_rx(void)
 {
-    if (_base) {
+    if (! _base ) return;
+    
+    if ( dmaInUse[RxIrq] == NotInUse ) {
         while( MODSERIAL_RBR_HAS_DATA ) {
             rxc = (char)(_RBR & 0xFF); 
             if ( MODSERIAL_RX_BUFFER_FULL ) {
--- a/ISR_TX.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/ISR_TX.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -29,7 +29,9 @@
 void 
 MODSERIAL::isr_tx(void)
 {
-    if (_base) {
+    if (! _base ) return;
+    
+    if (dmaInUse[TxIrq] == NotInUse ) {
         while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) {
             _THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]);
             buffer_count[TxIrq]--;   
--- a/MODSERIAL.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/MODSERIAL.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -71,6 +71,12 @@
     return MODSERIAL_RX_BUFFER_EMPTY; 
 }
 
+bool 
+MODSERIAL::txIsBusy(void) 
+{ 
+    return (_LSR & (3UL << 5) == 0) ? true : false; 
+} 
+
 void
 MODSERIAL::disableIrq(void)
 {
--- a/MODSERIAL.h	Sun Nov 21 02:15:07 2010 +0000
+++ b/MODSERIAL.h	Sun Nov 21 03:31:51 2010 +0000
@@ -134,6 +134,19 @@
         , BufferOversize = -2   /*!< Oversized buffer. */
     };
     
+    //! DMA channels.
+    enum dmaChannel {
+          NotInUse = -1     /*!< DMA not in use */
+        , Channel0 = 0      /*!< Channel 0 */
+        , Channel1          /*!< Channel 1 */
+        , Channel2          /*!< Channel 2 */
+        , Channel3          /*!< Channel 3 */
+        , Channel4          /*!< Channel 4 */
+        , Channel5          /*!< Channel 5 */
+        , Channel6          /*!< Channel 6 */
+        , Channel7          /*!< Channel 7 */
+    };
+    
     /**
      * The MODSERIAL constructor is used to initialise the serial object.
      *
@@ -549,7 +562,7 @@
      * @ingroup API
      * @return bool
      */
-    bool txIsBusy(void) { return (_LSR & (3UL << 5) == 0) ? true : false; } 
+    bool txIsBusy(void);
     
     #if 0 // Inhereted from Serial/Stream, for documentation only
     /**
@@ -650,6 +663,12 @@
     volatile int   buffer_overflow[2];
     
     /**
+     * DMA channel in use.
+     * @ingroup INTERNALS
+     */
+    volatile int dmaInUse[2];
+    
+    /**
      * Callback system.
      * @ingroup INTERNALS
      */
@@ -706,13 +725,7 @@
      * Overloaded virtual function.
      */
     virtual int _getc()      { return __getc(true); }
-    
-    /**
-     * Set's the Uart base pointer.
-     * @ingroup INTERNALS
-     */
-    void setBase(void);
-    
+        
     /** 
      * Function: init
      * Initialize the MODSERIAL object
--- a/PUTC.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/PUTC.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -29,24 +29,26 @@
 MODSERIAL::__putc(int c, bool block) {
     uint32_t lsr = (uint32_t)*((char *)_base + MODSERIAL_LSR);
     
-    if (lsr & 0x20 && MODSERIAL_TX_BUFFER_EMPTY ) {
-        _THR = (uint32_t)c;
-    }
-    else {
-        if (buffer[TxIrq] != (char *)NULL) {
-            if (block) while ( MODSERIAL_TX_BUFFER_FULL ) ; // Blocks!
-            else if( MODSERIAL_TX_BUFFER_FULL ) {
-                buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
-                _isr[TxOvIrq].call();
-                return -1;
+    if ( dmaInUse[TxIrq] == NotInUse ) {
+        if (lsr & 0x20 && MODSERIAL_TX_BUFFER_EMPTY ) {
+            _THR = (uint32_t)c;
+        }
+        else {
+            if (buffer[TxIrq] != (char *)NULL) {
+                if (block) while ( MODSERIAL_TX_BUFFER_FULL ) ; // Blocks!
+                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;
             }
-            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;
         }
     }
     
--- a/example.cpp	Sun Nov 21 02:15:07 2010 +0000
+++ b/example.cpp	Sun Nov 21 03:31:51 2010 +0000
@@ -54,7 +54,7 @@
     
     // Ensure the baud rate for the PC "USB" serial is much
     // higher than "uart" baud rate below.
-    pc.baud(115200);
+    pc.baud(PC_BAUD);
     
     // Use a deliberatly slow baud to fill up the TX buffer
     uart.baud(1200);