MMEx with SPI Slave to allow legacy devices to communicate with modern media such as USB, SD cards, the internet and all of the mbed\'s other interfaces

Dependencies:   NetServices MSCUsbHost mbed TMP102 SDFileSystem

Committer:
DeMein
Date:
Sun Feb 27 18:54:40 2011 +0000
Revision:
0:67a55a82ce06
Version as submitted to the NXP Design Challenge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DeMein 0:67a55a82ce06 1 /* MMEx for MBED - Console I/O Command processing
DeMein 0:67a55a82ce06 2 * Copyright (c) 2011 MK
DeMein 0:67a55a82ce06 3 *
DeMein 0:67a55a82ce06 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
DeMein 0:67a55a82ce06 5 * of this software and associated documentation files (the "Software"), to deal
DeMein 0:67a55a82ce06 6 * in the Software without restriction, including without limitation the rights
DeMein 0:67a55a82ce06 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
DeMein 0:67a55a82ce06 8 * copies of the Software, and to permit persons to whom the Software is
DeMein 0:67a55a82ce06 9 * furnished to do so, subject to the following conditions:
DeMein 0:67a55a82ce06 10 *
DeMein 0:67a55a82ce06 11 * The above copyright notice and this permission notice shall be included in
DeMein 0:67a55a82ce06 12 * all copies or substantial portions of the Software.
DeMein 0:67a55a82ce06 13 *
DeMein 0:67a55a82ce06 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
DeMein 0:67a55a82ce06 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
DeMein 0:67a55a82ce06 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
DeMein 0:67a55a82ce06 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
DeMein 0:67a55a82ce06 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
DeMein 0:67a55a82ce06 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
DeMein 0:67a55a82ce06 20 * THE SOFTWARE.
DeMein 0:67a55a82ce06 21 */
DeMein 0:67a55a82ce06 22
DeMein 0:67a55a82ce06 23 /**
DeMein 0:67a55a82ce06 24 \file cfuncs.cpp
DeMein 0:67a55a82ce06 25 \brief Commands starting with C for Console I/O
DeMein 0:67a55a82ce06 26 */
DeMein 0:67a55a82ce06 27
DeMein 0:67a55a82ce06 28 #include "cfuncs.h"
DeMein 0:67a55a82ce06 29
DeMein 0:67a55a82ce06 30 /** main entry for parsing C-commands
DeMein 0:67a55a82ce06 31 *
DeMein 0:67a55a82ce06 32 * syntax: Cx[argument]
DeMein 0:67a55a82ce06 33 */
DeMein 0:67a55a82ce06 34 void parse_C() {
DeMein 0:67a55a82ce06 35 DBG_msg("parse_C", inbuf);
DeMein 0:67a55a82ce06 36 err_num = noerror;
DeMein 0:67a55a82ce06 37
DeMein 0:67a55a82ce06 38 wipesp(inbuf); // remove all spaces from string
DeMein 0:67a55a82ce06 39
DeMein 0:67a55a82ce06 40 if (inbuf[1] != NULL) {
DeMein 0:67a55a82ce06 41 switch (inbuf[1]) {
DeMein 0:67a55a82ce06 42 case cwrite : do_cwrite(); // control LED's
DeMein 0:67a55a82ce06 43 break;
DeMein 0:67a55a82ce06 44 case cread : do_cread(); // get version string
DeMein 0:67a55a82ce06 45 break;
DeMein 0:67a55a82ce06 46 case copen : do_copen(); // get welcome string
DeMein 0:67a55a82ce06 47 break;
DeMein 0:67a55a82ce06 48 case cbaud : do_cbaud(); // get MMex status
DeMein 0:67a55a82ce06 49 break;
DeMein 0:67a55a82ce06 50 case cparam : do_cparam(); // control DEBUG level
DeMein 0:67a55a82ce06 51 break;
DeMein 0:67a55a82ce06 52 default : do_cdefault(); // command not recognized
DeMein 0:67a55a82ce06 53 break;
DeMein 0:67a55a82ce06 54 }
DeMein 0:67a55a82ce06 55 } else { do_mdefault(); }
DeMein 0:67a55a82ce06 56 }
DeMein 0:67a55a82ce06 57
DeMein 0:67a55a82ce06 58 /** write the string on the command line to the console
DeMein 0:67a55a82ce06 59 *
DeMein 0:67a55a82ce06 60 * syntax: CW[string]<CR>
DeMein 0:67a55a82ce06 61 */
DeMein 0:67a55a82ce06 62 void do_cwrite() {
DeMein 0:67a55a82ce06 63 int i = 2;
DeMein 0:67a55a82ce06 64
DeMein 0:67a55a82ce06 65 DBG_msg("do_cwrite", inbuf);
DeMein 0:67a55a82ce06 66
DeMein 0:67a55a82ce06 67 while (inbuf[i] != NULL) {
DeMein 0:67a55a82ce06 68 // now we write the data
DeMein 0:67a55a82ce06 69 pc.putc(inbuf[i]);
DeMein 0:67a55a82ce06 70 DBG_chr("do_cwrite", inbuf[i]);
DeMein 0:67a55a82ce06 71 i++;
DeMein 0:67a55a82ce06 72 }
DeMein 0:67a55a82ce06 73 pc.putc(c_cr); // write a <CR>
DeMein 0:67a55a82ce06 74 }
DeMein 0:67a55a82ce06 75
DeMein 0:67a55a82ce06 76 /** read characters from the console until a <CR> is found,
DeMein 0:67a55a82ce06 77 * stream may be interrupted by the HP41 by sending >F
DeMein 0:67a55a82ce06 78 *
DeMein 0:67a55a82ce06 79 * syntax: CR<CR>
DeMein 0:67a55a82ce06 80 */
DeMein 0:67a55a82ce06 81 void do_cread() {
DeMein 0:67a55a82ce06 82 bool go = true;
DeMein 0:67a55a82ce06 83 bool stopread = false;
DeMein 0:67a55a82ce06 84 char c = 0;
DeMein 0:67a55a82ce06 85
DeMein 0:67a55a82ce06 86 DBG_msg("do_cread", inbuf);
DeMein 0:67a55a82ce06 87
DeMein 0:67a55a82ce06 88 // now run the main reading loop
DeMein 0:67a55a82ce06 89 while (go) {
DeMein 0:67a55a82ce06 90 if (pc.readable()) {
DeMein 0:67a55a82ce06 91 // we have data
DeMein 0:67a55a82ce06 92 c = pc.getc();
DeMein 0:67a55a82ce06 93 mldl.tx_add(c); // add it to the SPI ringbuffer
DeMein 0:67a55a82ce06 94 DBG_chr("do_cread", c);
DeMein 0:67a55a82ce06 95 if (c == c_cr) { // is it a Carriage Return ?
DeMein 0:67a55a82ce06 96 mldl.tx_add(c_escape);
DeMein 0:67a55a82ce06 97 mldl.tx_add(c_eof);
DeMein 0:67a55a82ce06 98 DBG_msg("do_cread:", "CR found ");
DeMein 0:67a55a82ce06 99 }
DeMein 0:67a55a82ce06 100 }
DeMein 0:67a55a82ce06 101
DeMein 0:67a55a82ce06 102 // now check if we have to stop?
DeMein 0:67a55a82ce06 103 if (!mldl.rx_empty()) {
DeMein 0:67a55a82ce06 104 stopread = (mldl.rxx_read(data_mode) < 0); // intentional stop of read
DeMein 0:67a55a82ce06 105 }
DeMein 0:67a55a82ce06 106 go = !((c == c_cr) || stopread);
DeMein 0:67a55a82ce06 107 }
DeMein 0:67a55a82ce06 108
DeMein 0:67a55a82ce06 109 if (stopread) {
DeMein 0:67a55a82ce06 110 DBG_msg("do_cread", "forced stop read received");
DeMein 0:67a55a82ce06 111 mldl.flush_tx(); // empty transmit buffer
DeMein 0:67a55a82ce06 112 }
DeMein 0:67a55a82ce06 113 }
DeMein 0:67a55a82ce06 114
DeMein 0:67a55a82ce06 115 /** write the parameter indicated by the argument to the console,
DeMein 0:67a55a82ce06 116 * stream may be interrupted by the HP41 by sending >F
DeMein 0:67a55a82ce06 117 *
DeMein 0:67a55a82ce06 118 * syntax: CP[param]<CR>
DeMein 0:67a55a82ce06 119 */
DeMein 0:67a55a82ce06 120 void do_cparam() {
DeMein 0:67a55a82ce06 121 int pnum = 0;
DeMein 0:67a55a82ce06 122 int i = 0;
DeMein 0:67a55a82ce06 123 char * cstr;
DeMein 0:67a55a82ce06 124
DeMein 0:67a55a82ce06 125 DBG_msg("do_cparam", inbuf);
DeMein 0:67a55a82ce06 126
DeMein 0:67a55a82ce06 127 wipesp(inbuf);
DeMein 0:67a55a82ce06 128
DeMein 0:67a55a82ce06 129 pnum = getpnum(inbuf[2]);
DeMein 0:67a55a82ce06 130 if (pnum >= 0) {
DeMein 0:67a55a82ce06 131 cstr = new char [param[pnum].size() + 1];
DeMein 0:67a55a82ce06 132 strcpy (cstr, param[pnum].c_str());
DeMein 0:67a55a82ce06 133 DBG_int("get parameter #", pnum);
DeMein 0:67a55a82ce06 134 DBG_msg("get parameter: ", cstr);
DeMein 0:67a55a82ce06 135 while (cstr[i] != NULL) {
DeMein 0:67a55a82ce06 136 pc.putc(cstr[i]); // send the data
DeMein 0:67a55a82ce06 137 i++;
DeMein 0:67a55a82ce06 138 }
DeMein 0:67a55a82ce06 139 pc.putc(c_cr); // send an extra <CR>
DeMein 0:67a55a82ce06 140 delete[] cstr;
DeMein 0:67a55a82ce06 141 } else { do_cdefault(); }
DeMein 0:67a55a82ce06 142 }
DeMein 0:67a55a82ce06 143
DeMein 0:67a55a82ce06 144 /** set console baud rate
DeMein 0:67a55a82ce06 145 *
DeMein 0:67a55a82ce06 146 * syntax: CB[value]<CR>
DeMein 0:67a55a82ce06 147 */
DeMein 0:67a55a82ce06 148 void do_cbaud() {
DeMein 0:67a55a82ce06 149 long int baud = 0;
DeMein 0:67a55a82ce06 150
DeMein 0:67a55a82ce06 151 DBG_msg("do_cbaud", inbuf);
DeMein 0:67a55a82ce06 152
DeMein 0:67a55a82ce06 153 wipesp(inbuf);
DeMein 0:67a55a82ce06 154
DeMein 0:67a55a82ce06 155 // next chars on the commandline is the baud rate
DeMein 0:67a55a82ce06 156 if (inbuf[2] != NULL) {
DeMein 0:67a55a82ce06 157 // now process line
DeMein 0:67a55a82ce06 158 for (int i = 2; ((inbuf[i] >='0') && (inbuf[i] <= '9')); i++ ) {
DeMein 0:67a55a82ce06 159 baud = 10 * baud + (inbuf[i] - '0');
DeMein 0:67a55a82ce06 160 }
DeMein 0:67a55a82ce06 161 }
DeMein 0:67a55a82ce06 162 if (baud == 0) {
DeMein 0:67a55a82ce06 163 DBG_msg("do_cbaud", "invalid baud rate");
DeMein 0:67a55a82ce06 164 send_error(err_notrecognized);
DeMein 0:67a55a82ce06 165 } else {
DeMein 0:67a55a82ce06 166 // now set baud rate
DeMein 0:67a55a82ce06 167 DBG_int("set baudrate", baud);
DeMein 0:67a55a82ce06 168 pc.baud(baud);
DeMein 0:67a55a82ce06 169 }
DeMein 0:67a55a82ce06 170 }
DeMein 0:67a55a82ce06 171
DeMein 0:67a55a82ce06 172 /** open a channel between the MLDL2000 SPI and Console.
DeMein 0:67a55a82ce06 173 * Any data received from SPI will be sent to the Console,
DeMein 0:67a55a82ce06 174 * data read from the Console will be sent to SPI.
DeMein 0:67a55a82ce06 175 * \n Interrupt stream by sending >F or >I from the HP41,
DeMein 0:67a55a82ce06 176 * interruption from the Console is not possible.
DeMein 0:67a55a82ce06 177 * If the transmit buffer becomes full, characters from
DeMein 0:67a55a82ce06 178 * the Console may be lost, there is no handshake protocol
DeMein 0:67a55a82ce06 179 *
DeMein 0:67a55a82ce06 180 * syntax: CO<CR>
DeMein 0:67a55a82ce06 181 */
DeMein 0:67a55a82ce06 182 void do_copen() {
DeMein 0:67a55a82ce06 183 bool stopread = false;
DeMein 0:67a55a82ce06 184 char chin = 0;
DeMein 0:67a55a82ce06 185 int chout = 0;
DeMein 0:67a55a82ce06 186
DeMein 0:67a55a82ce06 187 DBG_msg("do_copen", inbuf);
DeMein 0:67a55a82ce06 188
DeMein 0:67a55a82ce06 189 // now run the main loop
DeMein 0:67a55a82ce06 190 while (!stopread) {
DeMein 0:67a55a82ce06 191 if (!mldl.rx_empty()) {
DeMein 0:67a55a82ce06 192 // there is data to send
DeMein 0:67a55a82ce06 193 chout = mldl.rxx_read(data_mode);
DeMein 0:67a55a82ce06 194 if (chout < 0) {
DeMein 0:67a55a82ce06 195 // >F or >I found
DeMein 0:67a55a82ce06 196 stopread = true;
DeMein 0:67a55a82ce06 197 DBG_msg("do_cread", "forced stop read received");
DeMein 0:67a55a82ce06 198 mldl.flush_tx(); // empty transmit buffer
DeMein 0:67a55a82ce06 199 } else {
DeMein 0:67a55a82ce06 200 // we can send the char
DeMein 0:67a55a82ce06 201 pc.putc(chout);
DeMein 0:67a55a82ce06 202 DBG_chr("do_copen write", chout);
DeMein 0:67a55a82ce06 203 }
DeMein 0:67a55a82ce06 204 }
DeMein 0:67a55a82ce06 205 if (pc.readable()) {
DeMein 0:67a55a82ce06 206 // we have data
DeMein 0:67a55a82ce06 207 chin = pc.getc();
DeMein 0:67a55a82ce06 208 mldl.tx_add(chin); // add it to the SPI ringbuffer
DeMein 0:67a55a82ce06 209 DBG_chr("do_copen read", chin);
DeMein 0:67a55a82ce06 210 }
DeMein 0:67a55a82ce06 211 }
DeMein 0:67a55a82ce06 212 }
DeMein 0:67a55a82ce06 213
DeMein 0:67a55a82ce06 214 /** send error message, command not recognized,
DeMein 0:67a55a82ce06 215 */
DeMein 0:67a55a82ce06 216 void do_cdefault() {
DeMein 0:67a55a82ce06 217 // command not recognized
DeMein 0:67a55a82ce06 218 DBG_msg("do_cdefault", inbuf);
DeMein 0:67a55a82ce06 219 send_error(err_notrecognized);
DeMein 0:67a55a82ce06 220 }