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

Revision:
0:b77c715e027c
--- /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