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
cfuncs.cpp@0:67a55a82ce06, 2011-02-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |