Better Serial C++ class library with interrupt
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-03
- Revision:
- 8:20759f992d48
- Parent:
- 7:5a25789c3b55
File content as of revision 8:20759f992d48:
//
// 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();
}
Yoji KURODA