5555+

Dependencies:   RingBuffer

Fork of iSerial by BE@R lab

iSerial.cpp

Committer:
palmdotax
Date:
2016-06-07
Revision:
12:3ffc21af1595
Parent:
9:e121a1503afa

File content as of revision 12:3ffc21af1595:

//
//  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 <stdarg.h>
#include "mbed.h"
#include "RingBuffer.h"
#include "iSerial.h"

//DigitalOut led3(LED3);
//DigitalOut led4(LED4);


void
iSerial::enable_uart_irq(void)
{
    switch(tx){
    case USBTX:
        #if defined(TARGET_LPC1768)
            NVIC_EnableIRQ(UART2_IRQn);
        #elif defined(TARGET_LPC11U24)
            NVIC_EnableIRQ(UART_IRQn);
        #endif
//        led1 = !led1;
        break;
  /*      
    case p9:
        #if defined(TARGET_LPC1768)
            NVIC_EnableIRQ(UART1_IRQn);
        #elif defined(TARGET_LPC11U24)
            NVIC_EnableIRQ(UART_IRQn);
        #endif
        break;

    #if defined(TARGET_LPC1768)
    case p13:
        NVIC_EnableIRQ(UART3_IRQn);
        break;
    case p28:
        NVIC_EnableIRQ(UART0_IRQn);
        break;
    #endif
    */
    }
}

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
 */
void
iSerial::rx_handler(void)
{
//  led3 = 1;
    while(Serial::readable())
        rxbuf.save(Serial::getc());
//  led3 = 0;
}

void
iSerial::tx_handler(void)
{
//  led4 = 1;
    while(Serial::writeable() && txbuf.check())
        Serial::putc( txbuf.read() );
//  led4 = 0;
}

iSerial::iSerial(PinName _tx, PinName _rx, const char *_name, int _txbufsize, int _rxbufsize)
:   Serial(_tx, _rx, _name),
    tx(_tx),
    rx(_rx),
    txbufsize(_txbufsize),
    rxbufsize(_rxbufsize),
    txbuf(RingBuffer(txbufsize)),
    rxbuf(RingBuffer(rxbufsize)),
    str(new char [txbufsize])    
{
    __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();
    enable_uart_irq();    
}

iSerial::~iSerial()
{
    delete [] str;
}

int
iSerial::readable(void)
{
    return rxbuf.check();
}

int
iSerial::getc(void)
{
    unsigned short int c;

    while(!rxbuf.check());   // wait receiving a character
    disable_uart_irq();
    c = rxbuf.read();
    enable_uart_irq();

    return c;
}

void
iSerial::putc(short ch)
{
    if(txbuf.check()==0 && Serial::writeable()){
        Serial::putc(ch);
        
    } else {
        while(txbuf.full()){
            disable_uart_irq();
            tx_handler();
            enable_uart_irq();
        }
        
        disable_uart_irq();
        txbuf.save(ch);
        enable_uart_irq();
    }
}

short int
iSerial::putstr(const char* s)
{
    int i=0;
    for(; ; i++){
        if(*s==0) break;
        putc(*s++);
    }
    return i;
}

short int
iSerial::puts(const char* s)
{
    short int n = putstr(s);
    putc(CR);
    putc(LF);
    return n;
}

char*
iSerial::printf(const char* format, ...)
{
    va_list arg;
    va_start(arg,format);
    vsprintf(str, format, arg);
    va_end(arg);
    putstr(str);
    return str;
}


void
iSerial::flush(void)
{
    while(txbuf.check())
        enable_uart_irq();
}