Meindert Kuipers / MMEx_Challenge

Description: 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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ufuncs.cpp Source File

ufuncs.cpp

Go to the documentation of this file.
00001 /* MMEx for MBED - processing for U commands
00002  * Copyright (c) 2011 MK
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022 
00023 /**
00024   \file ufuncs.cpp
00025   \brief processing for U commands, to be filled in by users
00026 */
00027 
00028 #include "ufuncs.h"
00029 #include "TMP102.h"
00030 #include <RPCVariable.h>
00031 
00032 TMP102 temperature(p28, p27, 0x90); //A0 pin is connected to ground
00033 
00034 /*
00035  *  Registers from HP41
00036  */
00037 struct _regs {
00038     char regX[14];
00039     char regY[14];
00040     char regZ[14];
00041     char regT[14];
00042     char regL[14];
00043     char regA[29];
00044 } regs;
00045 
00046 /**
00047  *  return the struct Regs via RPC as a character string
00048  *  RPC call is /regs_read/run
00049  *  RPC has a size limit of 64 bytes. Therefore, the result depends
00050  *  on the first character of the argument string: 
00051  *     A returns Alpha,
00052  *     L returns LastX
00053  *     Anything else returns the complete stack X~T
00054  *  All numerical data is in internal format, client must convert numbers.
00055  */
00056 void rpc_regsread( char *input, char *output )
00057 {
00058     switch ( toupper( *input ) ) {
00059     
00060     case 'A':
00061         strcpy( output, regs.regA );
00062         break;
00063         
00064     case 'L':
00065         memcpy( output, regs.regL, 14 );
00066         output[ 14 ] = '\0';
00067         break;
00068 
00069     default:
00070         memcpy( output, &regs, 4 * 14 );
00071         output[ 4 * 14 ] = '\0';
00072     }
00073 }
00074 RPCFunction rpcregs( rpc_regsread, "regs_read" );
00075  
00076 /** 
00077  *  main entry for parsing U-commands
00078  *
00079  */ 
00080 void parse_U() {
00081   DBG_msg("parse_U", inbuf);
00082   err_num = noerror;
00083  
00084   // wipesp(inbuf);                    // remove all spaces from string
00085 
00086   if (inbuf[1] != NULL) {
00087     switch (inbuf[1]) {
00088       case utemp  : do_utemp();     
00089                     break;       
00090       case ustack : do_ustack();     
00091                     break;                      
00092       case ualpha : do_ualpha();     
00093                     break;                      
00094       default     : do_udefault();    // command not recognized
00095                     break;
00096     }
00097   } else { do_udefault(); }
00098 }
00099 
00100 /** read TMP02 temp sensor
00101  *
00102  *  syntax:  UT     return temp value in degrees C
00103  *  \n       UTF    return temp value in degrees F
00104  */
00105 void do_utemp(){
00106   char s[20];
00107   wipesp(inbuf);  // remove spaces
00108   DBG_msg("do_utemp", inbuf);
00109   
00110   float temp = temperature.read();  
00111   if (inbuf[2] == 'F') {
00112     temp = (temp * 1.8) + 32;
00113   }
00114   
00115   sprintf(s, "%.4f", temp);
00116   DBG_msg("do_utemp", s);
00117   mldl.tx_string(s);
00118 } 
00119 
00120 /** read 7 bytes as a register from input stream
00121  *
00122  *  @param *reg pointer to a register (14 chars)
00123  *  @return last char read if all OK, -1 or -2 when interrupted
00124  *
00125  */
00126 int read_reg(char *reg) {
00127   int i;
00128   int c;
00129   
00130   for (i = 0; i < 7; i++) {
00131     c = mldl.rxx_read(data_mode);      // get byte
00132     // DBG_chr("read", c);
00133     if ((c == -1) || (c == -2)) {
00134       return c;                        // <EOF> or interrupt 
00135     } else {
00136       // data OK
00137       reg[i * 2]     = ((c >> 4) & 0x0f ) + '0';
00138       reg[i * 2 + 1] = (c & 0x0f) + '0';
00139       // DBG_int("1 - ", reg[i*2]);
00140       // DBG_int("2 - ", reg[i*2+1]);
00141     }
00142   }
00143   return c;
00144 }    
00145 
00146 /** read 28 bytes re[presenting the ALPHA registers M, N, O and Pm
00147  *
00148  *  @return last char read if all OK, -1 or -2 when interrupted
00149  */
00150 int read_alpha() {
00151   int i;
00152   int c;
00153   
00154   regs.regA[28] = NULL;
00155   for (i = 0; i < 28; i++) {
00156     c = mldl.rxx_read(data_mode);      // get byte
00157     // DBG_chr("read", c);
00158     if ((c == -1) || (c == -2)) {
00159       return c;                        // <EOF> or interrupt 
00160     } else {
00161       regs.regA[i] = c;
00162     }
00163   }
00164   return c;
00165 }      
00166 
00167  
00168 /** show a register on the debug console
00169  *
00170  *  @param *reg pointer to a register (14 chars
00171  */
00172 void show_reg(char *c, char *reg) {
00173   char s[25];
00174     
00175   sprintf(s, "%c.%c%c%c%c%c%c%c%c%c%c.%c.%c%c", 
00176           reg[0],  reg[1],  reg[2], reg[3],  reg[4],  reg[5],  reg[6],
00177           reg[7],  reg[8],  reg[9], reg[10], reg[11], reg[12], reg[13]);
00178   DBG_msg(c, s);
00179 }
00180   
00181 /** receive stack from HP41
00182  *
00183  *  syntax:  US<CR> [data]
00184  *  \n       [data] is a binary stream of 5* 7 bytes
00185  *  procedure is like File Write due to processing of escape characters
00186  *  must send exact number of bytes, or terminate with '>F'
00187  *  representing X, Y, Z, T, L
00188  */
00189 void do_ustack() {
00190   int i;
00191 
00192   DBG_msg("do_ustack", inbuf);
00193   
00194   // command is received, just send prompt
00195   
00196   send_prompt();              // now send a prompt and we are ready to go
00197   
00198   i = read_reg(regs.regX);
00199   i = read_reg(regs.regY);
00200   i = read_reg(regs.regZ);
00201   i = read_reg(regs.regT);
00202   i = read_reg(regs.regL);
00203    
00204   if (i >= 0) {
00205     show_reg("L", regs.regL);
00206     show_reg("T", regs.regT);
00207     show_reg("Z", regs.regZ);
00208     show_reg("Y", regs.regY);
00209     show_reg("X", regs.regX);           
00210   } else {
00211     DBG_msg("do_ustack", "interrupted");
00212     show_reg("L", regs.regL);
00213     show_reg("T", regs.regT);
00214     show_reg("Z", regs.regZ);
00215     show_reg("Y", regs.regY);
00216     show_reg("X", regs.regX); 
00217   }
00218 }
00219 
00220 /** receive alpha from HP41
00221  *
00222  *  syntax:  US<CR> [data]
00223  *  \n       [data] is a binary stream of 24 bytes
00224  *  procedure is like File Write due to processing of escape characters
00225  *  must send exact number of bytes, or terminate with '>F'
00226  */
00227 void do_ualpha() {
00228   int i, j;
00229   char tempA[29];
00230   
00231   DBG_msg("do_ualpha", inbuf);
00232 
00233   i = read_alpha();
00234 
00235   if (i >= 0) {
00236     DBG_msg("ALPHA", regs.regA);
00237   } else {
00238     DBG_msg("do_ualpha", "interrupted");
00239     DBG_msg("ALPHA", regs.regA);
00240     return;
00241   }
00242     
00243   // now rearrange due to the ordering of ALPHA
00244   tempA[ 0] = regs.regA[25];
00245   tempA[ 1] = regs.regA[26];
00246   tempA[ 2] = regs.regA[27];  // P register
00247   
00248   tempA[ 3] = regs.regA[14];
00249   tempA[ 4] = regs.regA[15];
00250   tempA[ 5] = regs.regA[16];
00251   tempA[ 6] = regs.regA[17];
00252   tempA[ 7] = regs.regA[18];
00253   tempA[ 8] = regs.regA[19];
00254   tempA[ 9] = regs.regA[20];  // O register
00255     
00256   tempA[10] = regs.regA[ 7];
00257   tempA[11] = regs.regA[ 8];
00258   tempA[12] = regs.regA[ 9];
00259   tempA[13] = regs.regA[10];
00260   tempA[14] = regs.regA[11];
00261   tempA[15] = regs.regA[12];
00262   tempA[16] = regs.regA[13];  // N register
00263   
00264   tempA[17] = regs.regA[ 0];
00265   tempA[18] = regs.regA[ 1];
00266   tempA[19] = regs.regA[ 2];
00267   tempA[20] = regs.regA[ 3];
00268   tempA[21] = regs.regA[ 4];
00269   tempA[22] = regs.regA[ 5];
00270   tempA[23] = regs.regA[ 6];  // M-register
00271   
00272   // find first real ALPHA char
00273   i = 0;
00274   while (tempA[i] == NULL) i++;
00275   
00276   for (j = 0; (j + i + 1) < 25; j++) {
00277     regs.regA[j] = tempA[i + j];
00278   }
00279   
00280   regs.regA[j] = NULL;  
00281 
00282   DBG_msg("ALPHA", regs.regA);
00283 
00284 }
00285 
00286 /** send error message, command not recognized,
00287  */                                 
00288 void do_udefault() {
00289   // command not recognized
00290   DBG_msg("do_udefault", inbuf);
00291   send_error(err_notrecognized); 
00292 }