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/ufuncs.cpp	Sun Feb 27 18:54:40 2011 +0000
@@ -0,0 +1,292 @@
+/* MMEx for MBED - processing for U commands
+ * 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 ufuncs.cpp
+  \brief processing for U commands, to be filled in by users
+*/
+
+#include "ufuncs.h"
+#include "TMP102.h"
+#include <RPCVariable.h>
+
+TMP102 temperature(p28, p27, 0x90); //A0 pin is connected to ground
+
+/*
+ *  Registers from HP41
+ */
+struct _regs {
+    char regX[14];
+    char regY[14];
+    char regZ[14];
+    char regT[14];
+    char regL[14];
+    char regA[29];
+} regs;
+
+/**
+ *  return the struct Regs via RPC as a character string
+ *  RPC call is /regs_read/run
+ *  RPC has a size limit of 64 bytes. Therefore, the result depends
+ *  on the first character of the argument string: 
+ *     A returns Alpha,
+ *     L returns LastX
+ *     Anything else returns the complete stack X~T
+ *  All numerical data is in internal format, client must convert numbers.
+ */
+void rpc_regsread( char *input, char *output )
+{
+    switch ( toupper( *input ) ) {
+    
+    case 'A':
+        strcpy( output, regs.regA );
+        break;
+        
+    case 'L':
+        memcpy( output, regs.regL, 14 );
+        output[ 14 ] = '\0';
+        break;
+
+    default:
+        memcpy( output, &regs, 4 * 14 );
+        output[ 4 * 14 ] = '\0';
+    }
+}
+RPCFunction rpcregs( rpc_regsread, "regs_read" );
+ 
+/** 
+ *  main entry for parsing U-commands
+ *
+ */ 
+void parse_U() {
+  DBG_msg("parse_U", inbuf);
+  err_num = noerror;
+ 
+  // wipesp(inbuf);                    // remove all spaces from string
+
+  if (inbuf[1] != NULL) {
+    switch (inbuf[1]) {
+      case utemp  : do_utemp();     
+                    break;       
+      case ustack : do_ustack();     
+                    break;                      
+      case ualpha : do_ualpha();     
+                    break;                      
+      default     : do_udefault();    // command not recognized
+                    break;
+    }
+  } else { do_udefault(); }
+}
+
+/** read TMP02 temp sensor
+ *
+ *  syntax:  UT     return temp value in degrees C
+ *  \n       UTF    return temp value in degrees F
+ */
+void do_utemp(){
+  char s[20];
+  wipesp(inbuf);  // remove spaces
+  DBG_msg("do_utemp", inbuf);
+  
+  float temp = temperature.read();  
+  if (inbuf[2] == 'F') {
+    temp = (temp * 1.8) + 32;
+  }
+  
+  sprintf(s, "%.4f", temp);
+  DBG_msg("do_utemp", s);
+  mldl.tx_string(s);
+} 
+
+/** read 7 bytes as a register from input stream
+ *
+ *  @param *reg pointer to a register (14 chars)
+ *  @return last char read if all OK, -1 or -2 when interrupted
+ *
+ */
+int read_reg(char *reg) {
+  int i;
+  int c;
+  
+  for (i = 0; i < 7; i++) {
+    c = mldl.rxx_read(data_mode);      // get byte
+    // DBG_chr("read", c);
+    if ((c == -1) || (c == -2)) {
+      return c;                        // <EOF> or interrupt 
+    } else {
+      // data OK
+      reg[i * 2]     = ((c >> 4) & 0x0f ) + '0';
+      reg[i * 2 + 1] = (c & 0x0f) + '0';
+      // DBG_int("1 - ", reg[i*2]);
+      // DBG_int("2 - ", reg[i*2+1]);
+    }
+  }
+  return c;
+}    
+
+/** read 28 bytes re[presenting the ALPHA registers M, N, O and Pm
+ *
+ *  @return last char read if all OK, -1 or -2 when interrupted
+ */
+int read_alpha() {
+  int i;
+  int c;
+  
+  regs.regA[28] = NULL;
+  for (i = 0; i < 28; i++) {
+    c = mldl.rxx_read(data_mode);      // get byte
+    // DBG_chr("read", c);
+    if ((c == -1) || (c == -2)) {
+      return c;                        // <EOF> or interrupt 
+    } else {
+      regs.regA[i] = c;
+    }
+  }
+  return c;
+}      
+
+ 
+/** show a register on the debug console
+ *
+ *  @param *reg pointer to a register (14 chars
+ */
+void show_reg(char *c, char *reg) {
+  char s[25];
+    
+  sprintf(s, "%c.%c%c%c%c%c%c%c%c%c%c.%c.%c%c", 
+          reg[0],  reg[1],  reg[2], reg[3],  reg[4],  reg[5],  reg[6],
+          reg[7],  reg[8],  reg[9], reg[10], reg[11], reg[12], reg[13]);
+  DBG_msg(c, s);
+}
+  
+/** receive stack from HP41
+ *
+ *  syntax:  US<CR> [data]
+ *  \n       [data] is a binary stream of 5* 7 bytes
+ *  procedure is like File Write due to processing of escape characters
+ *  must send exact number of bytes, or terminate with '>F'
+ *  representing X, Y, Z, T, L
+ */
+void do_ustack() {
+  int i;
+
+  DBG_msg("do_ustack", inbuf);
+  
+  // command is received, just send prompt
+  
+  send_prompt();              // now send a prompt and we are ready to go
+  
+  i = read_reg(regs.regX);
+  i = read_reg(regs.regY);
+  i = read_reg(regs.regZ);
+  i = read_reg(regs.regT);
+  i = read_reg(regs.regL);
+   
+  if (i >= 0) {
+    show_reg("L", regs.regL);
+    show_reg("T", regs.regT);
+    show_reg("Z", regs.regZ);
+    show_reg("Y", regs.regY);
+    show_reg("X", regs.regX);           
+  } else {
+    DBG_msg("do_ustack", "interrupted");
+    show_reg("L", regs.regL);
+    show_reg("T", regs.regT);
+    show_reg("Z", regs.regZ);
+    show_reg("Y", regs.regY);
+    show_reg("X", regs.regX); 
+  }
+}
+
+/** receive alpha from HP41
+ *
+ *  syntax:  US<CR> [data]
+ *  \n       [data] is a binary stream of 24 bytes
+ *  procedure is like File Write due to processing of escape characters
+ *  must send exact number of bytes, or terminate with '>F'
+ */
+void do_ualpha() {
+  int i, j;
+  char tempA[29];
+  
+  DBG_msg("do_ualpha", inbuf);
+
+  i = read_alpha();
+
+  if (i >= 0) {
+    DBG_msg("ALPHA", regs.regA);
+  } else {
+    DBG_msg("do_ualpha", "interrupted");
+    DBG_msg("ALPHA", regs.regA);
+    return;
+  }
+    
+  // now rearrange due to the ordering of ALPHA
+  tempA[ 0] = regs.regA[25];
+  tempA[ 1] = regs.regA[26];
+  tempA[ 2] = regs.regA[27];  // P register
+  
+  tempA[ 3] = regs.regA[14];
+  tempA[ 4] = regs.regA[15];
+  tempA[ 5] = regs.regA[16];
+  tempA[ 6] = regs.regA[17];
+  tempA[ 7] = regs.regA[18];
+  tempA[ 8] = regs.regA[19];
+  tempA[ 9] = regs.regA[20];  // O register
+    
+  tempA[10] = regs.regA[ 7];
+  tempA[11] = regs.regA[ 8];
+  tempA[12] = regs.regA[ 9];
+  tempA[13] = regs.regA[10];
+  tempA[14] = regs.regA[11];
+  tempA[15] = regs.regA[12];
+  tempA[16] = regs.regA[13];  // N register
+  
+  tempA[17] = regs.regA[ 0];
+  tempA[18] = regs.regA[ 1];
+  tempA[19] = regs.regA[ 2];
+  tempA[20] = regs.regA[ 3];
+  tempA[21] = regs.regA[ 4];
+  tempA[22] = regs.regA[ 5];
+  tempA[23] = regs.regA[ 6];  // M-register
+  
+  // find first real ALPHA char
+  i = 0;
+  while (tempA[i] == NULL) i++;
+  
+  for (j = 0; (j + i + 1) < 25; j++) {
+    regs.regA[j] = tempA[i + j];
+  }
+  
+  regs.regA[j] = NULL;  
+
+  DBG_msg("ALPHA", regs.regA);
+
+}
+
+/** send error message, command not recognized,
+ */                                 
+void do_udefault() {
+  // command not recognized
+  DBG_msg("do_udefault", inbuf);
+  send_error(err_notrecognized); 
+}
\ No newline at end of file