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
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, ®s, 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 }
