This program shows how to use the MODSERIAL library by Andy Kirkham to do canonical input processing. This allows you to enter and edit a command line (in the same way that you do in DOS or Linux) without tying up your main routine.
Diff: main.cpp
- Revision:
- 0:b77c715e027c
diff -r 000000000000 -r b77c715e027c main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Apr 21 21:35:16 2011 +0000 @@ -0,0 +1,134 @@ +/* Test of canonical input processing using MODSERIAL library by Andy Kirkham. + * + * The RX callback feature is used to echo input and perform basic line editing. + * This happens outside of the main routine which is free to do other things. + * + * Backspace removes previous character from buffer and updates terminal. + * Delete flushes the buffer and updates terminal. + * CR or LF causes an "end of line" flag to be set. + * Other characters are put into the buffer and echoed on terminal. + */ + +#define DATE "21 Apr 2011" +#define VERSION "1.00" + +#include "mbed.h" +#include "MODSERIAL.h" + +void serial_command_handler(void); +void flashes3(void); +void flashes4(void); +void rxCallback(MODSERIAL_IRQ_INFO *info); + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +MODSERIAL pc(USBTX, USBRX); + +bool eol_flag = false; +char buf[100]; + +int main() { + + pc.printf("%c[2J", 0x1B); //VT100 erase screen + pc.printf("%c[H", 0x1B); //VT100 home + pc.printf("MODSERIAL test program (Version %s, %s)\n", VERSION, DATE); + + //set up serial rx callback + pc.baud(9600); + pc.attach(&rxCallback, MODSERIAL::RxIrq); + + pc.printf("> "); + while(1) { //main loop + if (eol_flag) { //service command line + serial_command_handler(); + eol_flag = false; + } + //service an "event" + flashes3(); + //and service another one + flashes4(); + } +} + +// Serial command handler + +void serial_command_handler(void) { + char *cp; + + led2 = 1; //light LED2 to show command processing + pc.printf("\n"); + //read input into buffer (gets() does not seem to be supported!) + cp = buf; + while (pc.readable() ) { + *cp++ = pc.getc(); + } + --cp; //move back to CR or LF + *cp = '\0'; //terminate buffer + //print buffer length and contents in both ASCII and hex + int i = (int) (cp - buf); + pc.printf("cnt = %d, buf = <%s>\n", i, buf); + cp = buf; + while (i--) { + pc.printf("%02x ", (int) *cp++); + } + pc.printf("\n> "); + led2 = 0; +} + +// Dummy event handlers - flash LED3 or LED4 for a few seconds + +void flashes3(void) { + for (int i = 4; i > 0; i--) { + led3 = 1; + wait(0.25); + led3 = 0; + wait(0.25); + } +} + +void flashes4(void) { + for (int i = 3; i > 0; i--) { + led4 = 1; + wait(0.4); + led4 = 0; + wait(0.4); + } +} + +// Rx callback routine + +void rxCallback(MODSERIAL_IRQ_INFO *info) { + + MODSERIAL *pc = info->serial; + + led1 = !led1; //toggle LED1 to show char received + char c = pc->rxGetLastChar(); + if (c == 0x7f) { //flush input buffer and erase line on terminal + int i = pc->rxBufferGetCount(); + pc->rxBufferFlush(); + while (i--) { + pc->putc(0x8); + pc->putc(' '); + pc->putc(0x8); + } + } + else if (c == 0x8) { //remove last char from buffer and erase on terminal + //remove the BS and the previous char + info->rxDiscardLastChar(); + info->rxDiscardLastChar(); + pc->putc(0x8); + pc->putc(' '); + pc->putc(0x8); + } + else if (c == '\n' || c == '\r') { //end of line, signal command available + eol_flag = true; + } + else { //echo char on terminal + pc->putc(c); + } +} + +// END \ No newline at end of file