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
Diff: cfuncs.cpp
- Revision:
- 0:67a55a82ce06
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cfuncs.cpp Sun Feb 27 18:54:40 2011 +0000 @@ -0,0 +1,220 @@ +/* MMEx for MBED - Console I/O Command processing + * Copyright (c) 2011 MK + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + \file cfuncs.cpp + \brief Commands starting with C for Console I/O +*/ + +#include "cfuncs.h" + +/** main entry for parsing C-commands + * + * syntax: Cx[argument] + */ +void parse_C() { + DBG_msg("parse_C", inbuf); + err_num = noerror; + + wipesp(inbuf); // remove all spaces from string + + if (inbuf[1] != NULL) { + switch (inbuf[1]) { + case cwrite : do_cwrite(); // control LED's + break; + case cread : do_cread(); // get version string + break; + case copen : do_copen(); // get welcome string + break; + case cbaud : do_cbaud(); // get MMex status + break; + case cparam : do_cparam(); // control DEBUG level + break; + default : do_cdefault(); // command not recognized + break; + } + } else { do_mdefault(); } +} + +/** write the string on the command line to the console + * + * syntax: CW[string]<CR> + */ +void do_cwrite() { + int i = 2; + + DBG_msg("do_cwrite", inbuf); + + while (inbuf[i] != NULL) { + // now we write the data + pc.putc(inbuf[i]); + DBG_chr("do_cwrite", inbuf[i]); + i++; + } + pc.putc(c_cr); // write a <CR> +} + +/** read characters from the console until a <CR> is found, + * stream may be interrupted by the HP41 by sending >F + * + * syntax: CR<CR> + */ +void do_cread() { + bool go = true; + bool stopread = false; + char c = 0; + + DBG_msg("do_cread", inbuf); + + // now run the main reading loop + while (go) { + if (pc.readable()) { + // we have data + c = pc.getc(); + mldl.tx_add(c); // add it to the SPI ringbuffer + DBG_chr("do_cread", c); + if (c == c_cr) { // is it a Carriage Return ? + mldl.tx_add(c_escape); + mldl.tx_add(c_eof); + DBG_msg("do_cread:", "CR found "); + } + } + + // now check if we have to stop? + if (!mldl.rx_empty()) { + stopread = (mldl.rxx_read(data_mode) < 0); // intentional stop of read + } + go = !((c == c_cr) || stopread); + } + + if (stopread) { + DBG_msg("do_cread", "forced stop read received"); + mldl.flush_tx(); // empty transmit buffer + } +} + +/** write the parameter indicated by the argument to the console, + * stream may be interrupted by the HP41 by sending >F + * + * syntax: CP[param]<CR> + */ +void do_cparam() { + int pnum = 0; + int i = 0; + char * cstr; + + DBG_msg("do_cparam", inbuf); + + wipesp(inbuf); + + pnum = getpnum(inbuf[2]); + if (pnum >= 0) { + cstr = new char [param[pnum].size() + 1]; + strcpy (cstr, param[pnum].c_str()); + DBG_int("get parameter #", pnum); + DBG_msg("get parameter: ", cstr); + while (cstr[i] != NULL) { + pc.putc(cstr[i]); // send the data + i++; + } + pc.putc(c_cr); // send an extra <CR> + delete[] cstr; + } else { do_cdefault(); } +} + +/** set console baud rate + * + * syntax: CB[value]<CR> + */ +void do_cbaud() { + long int baud = 0; + + DBG_msg("do_cbaud", inbuf); + + wipesp(inbuf); + + // next chars on the commandline is the baud rate + if (inbuf[2] != NULL) { + // now process line + for (int i = 2; ((inbuf[i] >='0') && (inbuf[i] <= '9')); i++ ) { + baud = 10 * baud + (inbuf[i] - '0'); + } + } + if (baud == 0) { + DBG_msg("do_cbaud", "invalid baud rate"); + send_error(err_notrecognized); + } else { + // now set baud rate + DBG_int("set baudrate", baud); + pc.baud(baud); + } +} + +/** open a channel between the MLDL2000 SPI and Console. + * Any data received from SPI will be sent to the Console, + * data read from the Console will be sent to SPI. + * \n Interrupt stream by sending >F or >I from the HP41, + * interruption from the Console is not possible. + * If the transmit buffer becomes full, characters from + * the Console may be lost, there is no handshake protocol + * + * syntax: CO<CR> + */ +void do_copen() { + bool stopread = false; + char chin = 0; + int chout = 0; + + DBG_msg("do_copen", inbuf); + + // now run the main loop + while (!stopread) { + if (!mldl.rx_empty()) { + // there is data to send + chout = mldl.rxx_read(data_mode); + if (chout < 0) { + // >F or >I found + stopread = true; + DBG_msg("do_cread", "forced stop read received"); + mldl.flush_tx(); // empty transmit buffer + } else { + // we can send the char + pc.putc(chout); + DBG_chr("do_copen write", chout); + } + } + if (pc.readable()) { + // we have data + chin = pc.getc(); + mldl.tx_add(chin); // add it to the SPI ringbuffer + DBG_chr("do_copen read", chin); + } + } +} + +/** send error message, command not recognized, + */ +void do_cdefault() { + // command not recognized + DBG_msg("do_cdefault", inbuf); + send_error(err_notrecognized); +} \ No newline at end of file