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.

Dependencies:   mbed

Committer:
paulg
Date:
Thu Apr 21 21:35:16 2011 +0000
Revision:
0:b77c715e027c
First revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
paulg 0:b77c715e027c 1 /* Test of canonical input processing using MODSERIAL library by Andy Kirkham.
paulg 0:b77c715e027c 2 *
paulg 0:b77c715e027c 3 * The RX callback feature is used to echo input and perform basic line editing.
paulg 0:b77c715e027c 4 * This happens outside of the main routine which is free to do other things.
paulg 0:b77c715e027c 5 *
paulg 0:b77c715e027c 6 * Backspace removes previous character from buffer and updates terminal.
paulg 0:b77c715e027c 7 * Delete flushes the buffer and updates terminal.
paulg 0:b77c715e027c 8 * CR or LF causes an "end of line" flag to be set.
paulg 0:b77c715e027c 9 * Other characters are put into the buffer and echoed on terminal.
paulg 0:b77c715e027c 10 */
paulg 0:b77c715e027c 11
paulg 0:b77c715e027c 12 #define DATE "21 Apr 2011"
paulg 0:b77c715e027c 13 #define VERSION "1.00"
paulg 0:b77c715e027c 14
paulg 0:b77c715e027c 15 #include "mbed.h"
paulg 0:b77c715e027c 16 #include "MODSERIAL.h"
paulg 0:b77c715e027c 17
paulg 0:b77c715e027c 18 void serial_command_handler(void);
paulg 0:b77c715e027c 19 void flashes3(void);
paulg 0:b77c715e027c 20 void flashes4(void);
paulg 0:b77c715e027c 21 void rxCallback(MODSERIAL_IRQ_INFO *info);
paulg 0:b77c715e027c 22
paulg 0:b77c715e027c 23 DigitalOut led1(LED1);
paulg 0:b77c715e027c 24 DigitalOut led2(LED2);
paulg 0:b77c715e027c 25 DigitalOut led3(LED3);
paulg 0:b77c715e027c 26 DigitalOut led4(LED4);
paulg 0:b77c715e027c 27
paulg 0:b77c715e027c 28 MODSERIAL pc(USBTX, USBRX);
paulg 0:b77c715e027c 29
paulg 0:b77c715e027c 30 bool eol_flag = false;
paulg 0:b77c715e027c 31 char buf[100];
paulg 0:b77c715e027c 32
paulg 0:b77c715e027c 33 int main() {
paulg 0:b77c715e027c 34
paulg 0:b77c715e027c 35 pc.printf("%c[2J", 0x1B); //VT100 erase screen
paulg 0:b77c715e027c 36 pc.printf("%c[H", 0x1B); //VT100 home
paulg 0:b77c715e027c 37 pc.printf("MODSERIAL test program (Version %s, %s)\n", VERSION, DATE);
paulg 0:b77c715e027c 38
paulg 0:b77c715e027c 39 //set up serial rx callback
paulg 0:b77c715e027c 40 pc.baud(9600);
paulg 0:b77c715e027c 41 pc.attach(&rxCallback, MODSERIAL::RxIrq);
paulg 0:b77c715e027c 42
paulg 0:b77c715e027c 43 pc.printf("> ");
paulg 0:b77c715e027c 44 while(1) { //main loop
paulg 0:b77c715e027c 45 if (eol_flag) { //service command line
paulg 0:b77c715e027c 46 serial_command_handler();
paulg 0:b77c715e027c 47 eol_flag = false;
paulg 0:b77c715e027c 48 }
paulg 0:b77c715e027c 49 //service an "event"
paulg 0:b77c715e027c 50 flashes3();
paulg 0:b77c715e027c 51 //and service another one
paulg 0:b77c715e027c 52 flashes4();
paulg 0:b77c715e027c 53 }
paulg 0:b77c715e027c 54 }
paulg 0:b77c715e027c 55
paulg 0:b77c715e027c 56 // Serial command handler
paulg 0:b77c715e027c 57
paulg 0:b77c715e027c 58 void serial_command_handler(void) {
paulg 0:b77c715e027c 59 char *cp;
paulg 0:b77c715e027c 60
paulg 0:b77c715e027c 61 led2 = 1; //light LED2 to show command processing
paulg 0:b77c715e027c 62 pc.printf("\n");
paulg 0:b77c715e027c 63 //read input into buffer (gets() does not seem to be supported!)
paulg 0:b77c715e027c 64 cp = buf;
paulg 0:b77c715e027c 65 while (pc.readable() ) {
paulg 0:b77c715e027c 66 *cp++ = pc.getc();
paulg 0:b77c715e027c 67 }
paulg 0:b77c715e027c 68 --cp; //move back to CR or LF
paulg 0:b77c715e027c 69 *cp = '\0'; //terminate buffer
paulg 0:b77c715e027c 70 //print buffer length and contents in both ASCII and hex
paulg 0:b77c715e027c 71 int i = (int) (cp - buf);
paulg 0:b77c715e027c 72 pc.printf("cnt = %d, buf = <%s>\n", i, buf);
paulg 0:b77c715e027c 73 cp = buf;
paulg 0:b77c715e027c 74 while (i--) {
paulg 0:b77c715e027c 75 pc.printf("%02x ", (int) *cp++);
paulg 0:b77c715e027c 76 }
paulg 0:b77c715e027c 77 pc.printf("\n> ");
paulg 0:b77c715e027c 78 led2 = 0;
paulg 0:b77c715e027c 79 }
paulg 0:b77c715e027c 80
paulg 0:b77c715e027c 81 // Dummy event handlers - flash LED3 or LED4 for a few seconds
paulg 0:b77c715e027c 82
paulg 0:b77c715e027c 83 void flashes3(void) {
paulg 0:b77c715e027c 84 for (int i = 4; i > 0; i--) {
paulg 0:b77c715e027c 85 led3 = 1;
paulg 0:b77c715e027c 86 wait(0.25);
paulg 0:b77c715e027c 87 led3 = 0;
paulg 0:b77c715e027c 88 wait(0.25);
paulg 0:b77c715e027c 89 }
paulg 0:b77c715e027c 90 }
paulg 0:b77c715e027c 91
paulg 0:b77c715e027c 92 void flashes4(void) {
paulg 0:b77c715e027c 93 for (int i = 3; i > 0; i--) {
paulg 0:b77c715e027c 94 led4 = 1;
paulg 0:b77c715e027c 95 wait(0.4);
paulg 0:b77c715e027c 96 led4 = 0;
paulg 0:b77c715e027c 97 wait(0.4);
paulg 0:b77c715e027c 98 }
paulg 0:b77c715e027c 99 }
paulg 0:b77c715e027c 100
paulg 0:b77c715e027c 101 // Rx callback routine
paulg 0:b77c715e027c 102
paulg 0:b77c715e027c 103 void rxCallback(MODSERIAL_IRQ_INFO *info) {
paulg 0:b77c715e027c 104
paulg 0:b77c715e027c 105 MODSERIAL *pc = info->serial;
paulg 0:b77c715e027c 106
paulg 0:b77c715e027c 107 led1 = !led1; //toggle LED1 to show char received
paulg 0:b77c715e027c 108 char c = pc->rxGetLastChar();
paulg 0:b77c715e027c 109 if (c == 0x7f) { //flush input buffer and erase line on terminal
paulg 0:b77c715e027c 110 int i = pc->rxBufferGetCount();
paulg 0:b77c715e027c 111 pc->rxBufferFlush();
paulg 0:b77c715e027c 112 while (i--) {
paulg 0:b77c715e027c 113 pc->putc(0x8);
paulg 0:b77c715e027c 114 pc->putc(' ');
paulg 0:b77c715e027c 115 pc->putc(0x8);
paulg 0:b77c715e027c 116 }
paulg 0:b77c715e027c 117 }
paulg 0:b77c715e027c 118 else if (c == 0x8) { //remove last char from buffer and erase on terminal
paulg 0:b77c715e027c 119 //remove the BS and the previous char
paulg 0:b77c715e027c 120 info->rxDiscardLastChar();
paulg 0:b77c715e027c 121 info->rxDiscardLastChar();
paulg 0:b77c715e027c 122 pc->putc(0x8);
paulg 0:b77c715e027c 123 pc->putc(' ');
paulg 0:b77c715e027c 124 pc->putc(0x8);
paulg 0:b77c715e027c 125 }
paulg 0:b77c715e027c 126 else if (c == '\n' || c == '\r') { //end of line, signal command available
paulg 0:b77c715e027c 127 eol_flag = true;
paulg 0:b77c715e027c 128 }
paulg 0:b77c715e027c 129 else { //echo char on terminal
paulg 0:b77c715e027c 130 pc->putc(c);
paulg 0:b77c715e027c 131 }
paulg 0:b77c715e027c 132 }
paulg 0:b77c715e027c 133
paulg 0:b77c715e027c 134 // END