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

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