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.
main.cpp@0:b77c715e027c, 2011-04-21 (annotated)
- Committer:
- paulg
- Date:
- Thu Apr 21 21:35:16 2011 +0000
- Revision:
- 0:b77c715e027c
First revision
Who changed what in which revision?
User | Revision | Line number | New 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 |