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();
}

iSerial.cpp

Committer:
ykuroda
Date:
2012-09-01
Revision:
3:d5353b68105f
Parent:
2:3fc74f4d685a
Child:
4:b38ef9675d39

File content as of revision 3:d5353b68105f:

//
//  iSerial.cpp ... Serial Driver with Interrupt Rec/Send
//
//  2009.11.13 ... Originally written by Y.Kuroda for Renesas H83664
//  2012.08.31 ... Code convert for mbed in C++
//
#include "mbed.h"
#include "RingBuffer.h"
#include "iSerial.h"


/*
 *    Interrupt Function
 */
void
iSerial::rx_handler(void)
{
    if(Serial::readable()){
        rxbuf.save(Serial::getc());
    }

    NVIC_EnableIRQ(UART_IRQn); // UART1_IRQn);
}

void
iSerial::tx_handler(void)
{
    if(Serial::writeable()){
        if(txbuf.check()){
            Serial::putc( txbuf.read() );
        }
    }
    NVIC_EnableIRQ(UART_IRQn); // UART1_IRQn);
}

/*
 *  void sci_init(void)
 *
 *@ƒ|[ƒg‰Šú‰»ŠÖ”DDDD‚·‚ׂĂÌI/O‚̐ݒè‚ðs‚Á‚Ä‚¢‚éD
 *
 *@@ˆø”F‚È‚µ
 *@@–ß‚è’lF‚È‚µ
 *
 */
iSerial::iSerial(PinName _tx, PinName _rx, const char *_name, int _txbufsize, int _rxbufsize)
:   Serial(_tx, _rx, _name),
    txbuf(RingBuffer(_txbufsize)),
    rxbuf(RingBuffer(_rxbufsize))
{
    __disable_irq();

    attach(this, &iSerial::tx_handler, Serial::TxIrq);
    attach(this, &iSerial::rx_handler, Serial::RxIrq);

//  format(8,Serial::None,1);   // default
//  baud(baudrate);

    __enable_irq();
    NVIC_EnableIRQ(UART_IRQn); // UART1_IRQn);
}

/*
 *  ƒVƒŠƒAƒ‹“ü—Í‚É•¶Žš‚ª‚ ‚é‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN
 *  •Ô’lF    ƒoƒbƒtƒ@‚É‚ ‚镶Žš”
 */
int
iSerial::readable(void)
{
    return rxbuf.check();
}

/*
 *  ƒVƒŠƒAƒ‹‚©‚çˆê•¶Žš“ü—Í
 *    --- •¶Žš“ü—Í‚ð‘Ò‚Â
 */
int
iSerial::getc(void)
{
    unsigned short int c;

    while(!rxbuf.check());
    c = rxbuf.read();

    return c;
}


/*
 *@ƒVƒŠƒAƒ‹‚ֈꕶŽšo—Í
 */
void
iSerial::putc(short ch)
{
    if(txbuf.check()==0 && Serial::writeable()){
        Serial::putc(ch);
        
    } else {
        while(txbuf.full());
        txbuf.save(ch);
        NVIC_EnableIRQ(UART_IRQn); // UART1_IRQn);
    }
}

/*
 *@ƒVƒŠƒAƒ‹‚Ö•¶Žš—ñ‚ðo—Í
 *@@’Fˆê‰ñ‚̍ő啶Žš”‚ÍLINESIZE
 *@@’F•¶Žš—ñ‚̏I‚í‚è‚ɂ̓kƒ‹•¶Žš‚ª•K—vD
 *
 *@@ˆø”F•¶Žš—ñ‚ւ̃|ƒCƒ“ƒ^
 *@@•Ô’lFo—Í‚µ‚½•¶Žš”
 */
short int
iSerial::putstr(const char* s)
{
    int i=0;
    for(; ; i++){
        if(*s==0) break;
        putc(*s++);
    }
    return i;
}

/*@short int sci_puts(char* s)
 *@ƒVƒŠƒAƒ‹‚Ö•¶Žš—ñ‚ðˆêso—Í
 *@@’FÅŒã‚ɉüsƒR[ƒh‚𑗂鑼‚Ísci_putstr‚Æ“¯‚¶
 *
 *@@ˆø”F•¶Žš—ñ‚ւ̃|ƒCƒ“ƒ^
 *@@•Ô’lFo—Í‚µ‚½•¶Žš”
 */
short int
iSerial::puts(const char* s)
{
    short int n = putstr(s);
    putc(CR);
    putc(LF);
    return n;
}