Better Serial C++ class library with interrupt

Dependencies:   RingBuffer

Dependents:   Dumb_box_rev2 mbed_GPSproject

iSerial class library can easy be used just by swapping Serial declarations.

API

iSerial

Examples

#include "mbed.h"
#include "iSerial.h"

char s[] = "12345678901234567890123456789012345678901234567890";

int main() {

    iSerial pc(USBTX,USBRX);
    char* c = s;

    while(1) {
        pc.puts(s);
        
        while(pc.readable()){
            int ret = pc.getc();
            if(ret)
                *c++ = ret;
            if(c >= s+sizeof(s)-1)
                c = s;
        }
        wait(1);
    }
}

Example 2

Comparing speed of ordinary Serial functions

#include "mbed.h"
#include "iSerial.h"

char s[] = "12345678901234567890123456789012345678901234567890";    // 50 bytes

int main() {

    Timer t;

    Serial pc(USBTX,USBRX);
    pc.baud(921600);
    
    t.reset();
    t.start();
    for(int i=0; i<30; i++) {
        pc.printf(s);
        wait(0.001);
    }
    t.stop();
    
    int t1 = t.read_us();

    pc.puts("\n\n\n");


    iSerial ipc(USBTX,USBRX,NULL,1000,100); // try NOT to set the buffer over flowed
//    iSerial ipc(USBTX,USBRX);   // set as default = 100, 100
    ipc.baud(921600);

    t.reset();
    t.start();
    for(int i=0; i<30; i++) {
        ipc.printf(s);
        wait(0.001);
    }
    t.stop();
    
    int t2 = t.read_us();

    ipc.printf("\n\n\nThe time %d, %d [us] was taken.\n", t1, t2);
    ipc.puts("End.");
    ipc.flush();
}
Revision:
7:5a25789c3b55
Parent:
6:8d4b95b90c3b
Child:
8:20759f992d48
--- a/iSerial.cpp	Mon Sep 03 12:01:55 2012 +0000
+++ b/iSerial.cpp	Mon Sep 03 17:26:38 2012 +0000
@@ -10,7 +10,7 @@
 #include "iSerial.h"
 
 
-//DigitalOut led1(LED1);
+DigitalOut led4(LED4);
 
 
 void
@@ -45,6 +45,37 @@
     }
 }
 
+void
+iSerial::disable_uart_irq(void)
+{
+    switch(tx){
+    case USBTX:
+        #if defined(TARGET_LPC1768)
+            NVIC_DisableIRQ(UART2_IRQn);
+        #elif defined(TARGET_LPC11U24)
+            NVIC_DisableIRQ(UART_IRQn);
+        #endif
+//        led1 = !led1;
+        break;
+        
+    case p9:
+        #if defined(TARGET_LPC1768)
+            NVIC_DisableIRQ(UART1_IRQn);
+        #elif defined(TARGET_LPC11U24)
+            NVIC_DisableIRQ(UART_IRQn);
+        #endif
+        break;
+
+    #if defined(TARGET_LPC1768)
+    case p13:
+        NVIC_DisableIRQ(UART3_IRQn);
+        break;
+    case p28:
+        NVIC_DisableIRQ(UART0_IRQn);
+        break;
+    #endif
+    }
+}
 
 /*
  *    Interrupt Function
@@ -52,21 +83,22 @@
 void
 iSerial::rx_handler(void)
 {
+//    disable_uart_irq();
     if(Serial::readable()){
         rxbuf.save(Serial::getc());
     }
-    enable_uart_irq();
+//    enable_uart_irq();
 }
 
 void
 iSerial::tx_handler(void)
 {
-    if(Serial::writeable()){
-        if(txbuf.check()){
-            Serial::putc( txbuf.read() );
-        }
-    }
-    enable_uart_irq();
+led4 = 1;
+//    disable_uart_irq();
+    while(Serial::writeable() && txbuf.check())
+        Serial::putc( txbuf.read() );
+//    enable_uart_irq();
+led4 = 0;
 }
 
 iSerial::iSerial(PinName _tx, PinName _rx, const char *_name, int _txbufsize, int _rxbufsize)
@@ -107,7 +139,8 @@
 {
     unsigned short int c;
 
-    while(!rxbuf.check());
+    while(!rxbuf.check())   // wait receiving a character
+        enable_uart_irq();
     c = rxbuf.read();
 
     return c;
@@ -120,7 +153,13 @@
         Serial::putc(ch);
         
     } else {
-        while(txbuf.full());
+        while(txbuf.full()){
+            disable_uart_irq();
+            tx_handler();
+            enable_uart_irq();
+        }
+        
+        disable_uart_irq();
         txbuf.save(ch);
         enable_uart_irq();
     }
@@ -161,7 +200,8 @@
 void
 iSerial::flush(void)
 {
-    while(txbuf.check());
+    while(txbuf.check())
+        enable_uart_irq();
 }