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: mfuncs.cpp
- Revision:
- 0:67a55a82ce06
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mfuncs.cpp Sun Feb 27 18:54:40 2011 +0000 @@ -0,0 +1,363 @@ +/* MMEx for MBED - MBED specific 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 mfuncs.cpp + \brief Commands starting with M for MBED features +*/ + +#include "mfuncs.h" + +/** main entry for parsing M-commands + * + */ +void parse_M() { + // process M-commands for mbed + DBG_msg("parse_M", inbuf); + err_num = noerror; + + wipesp(inbuf); // remove all spaces from string + + if (inbuf[1] != NULL) { + switch (inbuf[1]) { + case mled : do_mled(); // control LED's + break; + case mversion : do_mversion(); // get version string + break; + case mwelcome : do_mwelcome(); // get welcome string + break; + case mstatus : do_mstatus(); // get MMex status + break; + case mdebug : do_mdebug(); // control DEBUG level + break; + case merror : do_merror(); // get latest error message + break; + case mbaud : do_mbaud(); // set console baud rate + break; + case mcase : do_mcase(); + break; + case mtime : do_mtime(); + break; + case mreset : do_mreset(); // reset mbed + break; + default : do_mdefault(); // command not recognized + break; + } + } else { do_mdefault(); } +} + +/** control/read MBED led status + * + * syntax: ML[number][value]<CR> + * \n [number]: 1, 2, 3, 4, LED number + * \n [value] : 0 (off), 1(ON), T(toggle), R(read) + */ +void do_mled() { + DBG_msg("mled", inbuf); + if ((inbuf[2] != NULL) && (inbuf[3] != NULL)) { + // we have enough arguments + switch (inbuf[3]) { + case ledon : + switch (inbuf[2]) { + case '1' : _led1.write(1); break; + case '2' : _led2.write(1); break; + case '3' : _led3.write(1); break; + case '4' : _led4.write(1); break; + default : do_mdefault(); break; + } + break; + + case ledoff : + switch (inbuf[2]) { + case '1' : _led1.write(0); break; + case '2' : _led2.write(0); break; + case '3' : _led3.write(0); break; + case '4' : _led4.write(0); break; + default : do_mdefault(); break; + } + break; + + case ledtog : + switch (inbuf[2]) { + case '1' : _led1 = !_led1; break; + case '2' : _led2 = !_led2; break; + case '3' : _led3 = !_led3; break; + case '4' : _led4 = !_led4; break; + default : do_mdefault(); break; + } + break; + + case ledread : + switch (inbuf[2]) { + case '1' : send_int(_led1); break; + case '2' : send_int(_led2); break; + case '3' : send_int(_led3); break; + case '4' : send_int(_led4); break; + default : do_mdefault(); break; + } + break; + + default : do_mdefault(); + break; + } + } else { do_mdefault(); } +} + +/** Read MMEx version information + * + * syntax: MV<CR> + * + */ +void do_mversion() { + DBG_msg("mversion", inbuf); + char str[] = msg_version; + upstring(str); + mldl.tx_string(str); +} + +/** Read MMEx welcome message + * + * syntax: MW<CR> + * + */ +void do_mwelcome() { + DBG_msg("mwelcome", inbuf); + welcome(); +} + +/** Read MMEx status message + * + * syntax: MS<CR> + * + */ +void do_mstatus() { + DBG_msg("mstatus", inbuf); + send_status(); +} + +/** Set MMEx debug level + * + * syntax: MD[value]<CR> + * \n [value]: 0 no debug output + * \n [value]: 1 high level debug messages + * \n [value]: 2 like 1, including SPI straffic + * + */ +void do_mdebug() { + DBG_msg("mdebug", inbuf); + if (inbuf[2] != NULL) { + // we have enough arguments + switch (inbuf[2]) { + case '0' : DBG_level = DBG_OFF; + mldl.DBG_set(DBG_OFF); + // now redirect stderr to NULL + freopen(NULL, "w", stderr); + freopen(NULL, "w", stdout); + break; + case '1' : DBG_level = DBG_ON; + mldl.DBG_set(DBG_ON); + //restore sterr and stdout + freopen("/pc", "w", stderr); + freopen("/pc", "w", stdout); + break; + case '2' : DBG_level = DBG_FULL; + mldl.DBG_set(DBG_FULL); + //restore sterr and stdout + freopen("/pc", "w", stderr); + freopen("/pc", "w", stdout); + break; + default : do_mdefault(); + break; + } + } else { do_mdefault(); } +} + +/** get latest error number + * + * syntax: ME<CR> + * + */ +void do_merror() { + // get latest error message + DBG_msg("do_merror", inbuf); + send_2int(last_err); + last_err = 0; // clear after reading +} + +/** set console (UBSB) baud rate + * + * syntax: MB[value]<CR> + * \n [value]: new baud rate + * + */ +void do_mbaud() { + long int baud = 0; + + DBG_msg("do_mbaud", 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_mbaud", "invalid baud rate"); + send_error(err_notrecognized); + } else { + // now set baud rate + DBG_int("set baudrate", baud); + pc.baud(baud); + } +} + +/** set case for output of text commands + * + * syntax: MC[value]<CR> + * \n [value]: U all output upper case + * \n [value]: N no change to output (or any other value) + * + */ +void do_mcase() { + DBG_msg("do_mcase", inbuf); + + // next char on commandline is 'U' + upcase = false; // default value + if (inbuf[2] == ucase ) { + upcase = true; // change default if 'U' + DBG_msg("do_mcase", "change to uppercase"); + } else { + DBG_msg("do_mcase", "no change"); + } +} + +/** get or set the MBED RTC time + * + * syntax: MT<CR> return the current time set in the RTC in date format + * \n MTS<CR> return the current time in seconds + * \n MT[value]<CR> set the time in date format + * \n MTS[value]<CR> set the current time in seconds + * \n date format is [year][month][day][hour][minute][second], all 2 digits, + * \n year is 4 digits + * \n seconds format is number of seconds since Jan 1, 1970 (Unix convention) + */ +void do_mtime() { + bool secs = false; + time_t seconds; + struct tm t; // for YYYYMMDDHHMMSS format + + + char s[40]; // to hold output string + int i = 2; + DBG_msg("do_mtime", inbuf); + + if (inbuf[2] == 'S') { + secs = true; // seconds mode + i = 3; // char counter for time value + } + + // check if there is a parameter, if so read it + if (inbuf[i] == NULL) { + // no parameter, return current time + seconds = time(NULL); // get current time + if (!secs) { + // translate to YYYYMMDDHHMMSS + t = *localtime(&seconds); + sprintf(s, "%04d%02d%02d%02d%02d%02d", + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec); + DBG_msg("read time", s); + mldl.tx_string(s); + } else { + sprintf(s, "%d", seconds); + DBG_msg("read time", s); + mldl.tx_string(s); + } + + } else { + // set time from input + if (secs) { + // seconds format + seconds = 0; + while ((inbuf[i] != NULL) && (inbuf[i] >= '0') && (inbuf[i] <= '9')) { + seconds = (10 * seconds) + (inbuf[i] - '0'); + i++; + } + sprintf(s, "%d", seconds); + DBG_msg("set time", s); + } else { + // YYYYMMDDHHMMSS format + DBG_msg("set time", inbuf); + int j = 0; + for (j = 0; j < 39; j++) s[j] = '0'; + s[39] = NULL; + j = 0; + while ((inbuf[i] != NULL) && (inbuf[i] >= '0') && (inbuf[i] <= '9')) { + s[j] = inbuf[i]; + i++; + j++; + } + DBG_msg("set time s", s); + i = 1000 * (s[ 0] - '0') + 100 * (s[ 1] - '0') + 10 * (s[ 1] - '0') + (s[ 3] - '0'); + t.tm_year = i - 1900; + + i = 10 * (s[ 4] - '0') + (s[ 5] - '0'); + t.tm_mon = i - 1; + + i = 10 * (s[ 6] - '0') + (s[ 7] - '0');; + t.tm_mday = i; + + i = 10 * (s[ 8] - '0') + (s[ 9] - '0'); + t.tm_hour = i; + + i = 10 * (s[10] - '0') + (s[11] - '0'); + t.tm_min = i; + + i = 10 * (s[10] - '0') + (s[11] - '0'); + t.tm_sec = i; + + seconds = mktime(&t); + + } + set_time(seconds); + } +} + +/** (soft) reset the MBED module + * + * syntax: MR<CR> + * + */ +void do_mreset() { + DBG_msg("do_mreset", inbuf); + mbed_reset(); +} + +/** send error message, command not recognized + * + */ +void do_mdefault() { + // command not recognized + DBG_msg("do_mdefault", inbuf); + send_error(err_notrecognized); +} \ No newline at end of file