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/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