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: pfuncs.cpp
- Revision:
- 0:67a55a82ce06
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pfuncs.cpp Sun Feb 27 18:54:40 2011 +0000 @@ -0,0 +1,428 @@ +/* MMEx for MBED - Parameter 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 pfuncs.cpp + \brief Commands starting with P for processing Parameters +*/ + +#include "pfuncs.h" + +string param[maxparams + 1]; // our array of parameter strings + +/** translate the parameter character to its array index + * + * @param C parameter character '0' to '9', 'E', etc + * @return index in Parameter array, -1 if C was not valid + * + */ +int getpnum(char C) { + + switch (C) { + case par_0: + case par_1: + case par_2: + case par_3: + case par_4: + case par_5: + case par_6: + case par_7: + case par_8: + case par_9: return(C - '0'); + case par_E: return(10); + case par_R: return(11); + case par_S: return(12); + case par_C: return(13); + case par_X: return(14); + case par_I: return(15); + case par_J: return(16); + case par_H: return(17); + case par_M: return(18); + case par_U: return(19); + case par_N: return(20); + case par_P: return(21); + + default: return(-1); + } +} + +/** translate the parameter index to its character value + * + * @param pnum index in Parameter array, -1 if C was not valid + * @return parameter character '0' to '9', 'E', etc + * + */ +char getnump(int pnum) { + switch (pnum) { + case 0: return('0'); + case 1: return('1'); + case 2: return('2'); + case 3: return('3'); + case 4: return('4'); + case 5: return('5'); + case 6: return('6'); + case 7: return('7'); + case 8: return('8'); + case 9: return('9'); + case 10: return('E'); + case 11: return('R'); + case 12: return('S'); + case 13: return('C'); + case 14: return('X'); + case 15: return('I'); + case 16: return('J'); + case 17: return('H'); + case 18: return('M'); + case 19: return('U'); + case 20: return('N'); + case 21: return('P'); + default: return(NULL); + } +} + +/** main entry for parsing P-commands + * + */ +void parse_P() { + DBG_msg("parse_P", inbuf); + + if (inbuf[1] != NULL) { + switch (inbuf[1]) { + case pclear : do_pclear(); // clear parameter + break; + case pget : do_pget(); // get parameter + break; + case pset : do_pset(); // set parameter + break; + case plen : do_plen(); // retrun the length of a parametr string + break; + case psave : do_psave(); // save all parameters to LocalDisk + break; + case pread : do_pread(); // read all parameters from LocalDisk + break; + case pxeq : do_pxeq(); + break; + default : do_pdefault(); // command not recognized + break; + } + } else { do_pdefault(); } +} + +/** clear a Parameter + * + * syntax: PC [param] + * \n [param]: one of the defined Parameters + * + */ +void do_pclear() { + int pnum = 0; + + DBG_msg("do_pclear", inbuf); + + wipesp(inbuf); + pnum = getpnum(inbuf[2]); + if (pnum >= 0) { + DBG_int("clear parameter #", pnum); + param[pnum].clear(); + } else { do_pdefault(); } +} + +/** retrieve the value of a parameter + * + * syntax: PG [param] + * \n [param]: one of the defined Parameters + * + */ +void do_pget() { + int pnum = 0; + char * cstr; + + DBG_msg("do_pget", 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); + upstring(cstr); + mldl.tx_string(cstr); + delete[] cstr; + } else { do_pdefault(); } +} + +/** set the value of a parameter + * + * syntax: PS [param][string] overwrites previous Parameter + * \n or PS [param]>+[string] to append to Parameter + * \n [param]: one of the defined Parameters + * + */ +void do_pset() { + int pnum = 0; + + DBG_msg("do_pset", inbuf); + + while (inbuf[2] == c_space) remchar(inbuf, 2, 1); // remove the spaces + + pnum = getpnum(inbuf[2]); + DBG_int("pnum", pnum); + if (pnum >= 0) { + // now retrieve string from the command line, i starts at 3 + DBG_int("set parameter #", pnum); + + // if first chars are not ">+" the string will be new + if ((inbuf[3] == c_escape) && (inbuf[4] == c_append)) { + // string is append, remove first 5 chars (command and >+) from inbuf + remchar(inbuf, 0, 5); + DBG_msg("append parameter ", inbuf); + param[pnum].append(inbuf); + } else { + remchar(inbuf, 0, 3); + DBG_msg("new parameter ", inbuf); + param[pnum].assign(inbuf); // no append, assign string + } + } else { do_pdefault(); } +} + +/** return the length of a parameter string + * + * syntax: PL [param] + * \n [param]: one of the defined Parameters + * + */ +void do_plen() { + int pnum = 0; + char tmp[25]; + + DBG_msg("do_plen", inbuf); + + wipesp(inbuf); + pnum = getpnum(inbuf[2]); + if (pnum >= 0) { + DBG_int("parameter #", pnum); + sprintf(tmp,"%d", param[pnum].length()); + DBG_msg("parameter length ", tmp); + mldl.tx_string(tmp); + } else { do_pdefault(); } +} + +/** save all parameters to LocalDisk, with filename PARAMS_[num].TXT + * + * syntax: PV [num] + * \n [num]: simngle digit or character + * \n overwrites an existing file + + */ +void do_psave() { + int pnum = 0; + char fname[25]; + char * cstr; + + DBG_msg("do_psave", inbuf); + + wipesp(inbuf); + + if (inbuf[2] != NULL) { + sprintf(fname, "/local/param_%c.txt", inbuf[2]); + DBG_msg("create file ", fname); + FILE *fp = fopen(fname, "w"); // Open file for writing + if (fp != NULL) { + for (pnum = 0; pnum <= maxparams; pnum++) { + cstr = new char [param[pnum].size() + 1]; + sprintf(cstr, "%c-", getnump(pnum)); + strcat (cstr, param[pnum].c_str()); + DBG_msg("saving ", cstr); + fprintf(fp, "%s\n", cstr); + delete[] cstr; + } + fclose(fp); + } else { + // error opening file + DBG_msg("do_psave", "file NOT opened"); + send_error(err_filenotopen); + } + } else { + DBG_msg("do_psave", inbuf); + send_error(err_novalidcommand); + } +} + +/** read all parameters from LocalDisk, with filename PARAMS_[num].TXT + * + * syntax: PR [num] + * \n [num]: single digit or character + * + */ +void do_pread() { + int pnum = 0; + char fname[25]; + char cstr[511]; // maximum length per parameter + + DBG_msg("do_pread", inbuf); + + wipesp(inbuf); + + if (inbuf[2] != NULL) { + sprintf(fname, "/local/param_%c.txt", inbuf[2]); + DBG_msg("open file ", fname); + FILE *fp = fopen(fname, "r"); // Open file for reading + if (fp != NULL) { + for (pnum = 0; pnum <= maxparams; pnum++) { + DBG_int("param ", pnum); + fgets(cstr, 511, fp); + DBG_msg("read ", cstr); + remchar(cstr, 0, 2); // remove the firs 2 chars (parameter char) + param[pnum].assign(cstr); + param[pnum].erase(param[pnum].end() - 1); // remove /n + } + fclose(fp); + } else { + // error opening file + DBG_msg("do_pread", "file NOT opened"); + send_error(err_filenotopen); + } + } else { + DBG_msg("do_pread", inbuf); + send_error(err_novalidcommand); + } +} + +/** Execute the chosen parameter string as an MMEx command + * + * syntax: PX [param] + * \n [param]: one of the defined Parameters + * + */ +void do_pxeq() { + int pnum = 0; + int i; + char * cstr; + + DBG_msg("do_pxeq", inbuf); + + wipesp(inbuf); + pnum = getpnum(inbuf[2]); + if (((pnum >= 0) && (pnum <= 9)) || (pnum == par_C_) || (pnum == par_X_)) { + // only for valid parameters + cstr = new char [param[pnum].size() + 1]; + strcpy (cstr, param[pnum].c_str()); + DBG_int("xeq parameter #", pnum); + DBG_msg("xeq parameter: ", cstr); + + if (mldl.rx_room() >= (param[pnum].length() + 1)) { + DBG_int("init XQ", mldl.rx_room()); + // enough room in our rx buffer + i = 0; + while (cstr[i] != NULL) { + // add to buffer + mldl.rx_add(cstr[i]); + DBG_chr("XQ add", cstr[i]); + i++; + } + mldl.rx_add(c_cr); + } else { + // not enough room + DBG_msg("do_pxeq", "rx buffer full"); + send_error(err_paramnoxeq); + } + delete[] cstr; + } else { + if (pnum == par_R_) { + // RPC function to execute + do_pdefault(); + } else { do_pdefault(); } + } +} + +/** automatic all parameters from LocalDisk on startup, with filename PARAMS_A.TXT + * + */ +void init_loadp() { + int pnum = 0; + char cstr[511]; // maximum length per parameter + + DBG_msg("init_loadp", "PARAM_A.TXT"); + + FILE *fp = fopen("/local/PARAM_A.TXT", "r"); // Open file for reading + if (fp != NULL) { + for (pnum = 0; pnum <= maxparams; pnum++) { + DBG_int("param ", pnum); + fgets(cstr, 511, fp); + DBG_msg("read ", cstr); + remchar(cstr, 0, 2); // remove the firs 2 chars (parameter char) + param[pnum].assign(cstr); + param[pnum].erase(param[pnum].end() - 1); // remove /n + } + fclose(fp); + } else { + // error opening file + DBG_msg("file not found", "PARAM_A.TXT"); + // send_error(err_filenotopen); // no error sent on startup + } +} + +/** execute the auto execute string in Parameter X on startup if it exists + * + */ +void init_xeq() { + int pnum = 0; + int i; + char * cstr; + + DBG_msg("init_xeq", "parameter X"); + + pnum = getpnum('X'); + if (pnum >= 0) { + cstr = new char [param[pnum].size() + 1]; + strcpy (cstr, param[pnum].c_str()); + DBG_int("xeq parameter #", pnum); + DBG_msg("xeq parameter: ", cstr); + + + if ((mldl.rx_room() >= param[pnum].length() + 1) && !param[pnum].empty()) { + // enough room in our rx buffer and we have something to execute + DBG_int("init XQ", mldl.rx_room()); + i = 0; + while (cstr[i] != NULL) { + // add to buffer + mldl.rx_add(cstr[i]); + DBG_chr("XQI add", cstr[i]); + i++; + } + mldl.rx_add(c_cr); + } else { + // not enough room + DBG_msg("init_xeq", "rx buffer full or no command"); + } + delete[] cstr; + } +} + +/** send error message, command not recognized + * + */ +void do_pdefault() { + DBG_msg("do_pdefault", inbuf); + send_error(err_notrecognized); +} \ No newline at end of file