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

Committer:
DeMein
Date:
Sun Feb 27 18:54:40 2011 +0000
Revision:
0:67a55a82ce06
Version as submitted to the NXP Design Challenge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DeMein 0:67a55a82ce06 1 /* MMEx for MBED - processing for U commands
DeMein 0:67a55a82ce06 2 * Copyright (c) 2011 MK
DeMein 0:67a55a82ce06 3 *
DeMein 0:67a55a82ce06 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
DeMein 0:67a55a82ce06 5 * of this software and associated documentation files (the "Software"), to deal
DeMein 0:67a55a82ce06 6 * in the Software without restriction, including without limitation the rights
DeMein 0:67a55a82ce06 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
DeMein 0:67a55a82ce06 8 * copies of the Software, and to permit persons to whom the Software is
DeMein 0:67a55a82ce06 9 * furnished to do so, subject to the following conditions:
DeMein 0:67a55a82ce06 10 *
DeMein 0:67a55a82ce06 11 * The above copyright notice and this permission notice shall be included in
DeMein 0:67a55a82ce06 12 * all copies or substantial portions of the Software.
DeMein 0:67a55a82ce06 13 *
DeMein 0:67a55a82ce06 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
DeMein 0:67a55a82ce06 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
DeMein 0:67a55a82ce06 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
DeMein 0:67a55a82ce06 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
DeMein 0:67a55a82ce06 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
DeMein 0:67a55a82ce06 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
DeMein 0:67a55a82ce06 20 * THE SOFTWARE.
DeMein 0:67a55a82ce06 21 */
DeMein 0:67a55a82ce06 22
DeMein 0:67a55a82ce06 23 /**
DeMein 0:67a55a82ce06 24 \file ufuncs.cpp
DeMein 0:67a55a82ce06 25 \brief processing for U commands, to be filled in by users
DeMein 0:67a55a82ce06 26 */
DeMein 0:67a55a82ce06 27
DeMein 0:67a55a82ce06 28 #include "ufuncs.h"
DeMein 0:67a55a82ce06 29 #include "TMP102.h"
DeMein 0:67a55a82ce06 30 #include <RPCVariable.h>
DeMein 0:67a55a82ce06 31
DeMein 0:67a55a82ce06 32 TMP102 temperature(p28, p27, 0x90); //A0 pin is connected to ground
DeMein 0:67a55a82ce06 33
DeMein 0:67a55a82ce06 34 /*
DeMein 0:67a55a82ce06 35 * Registers from HP41
DeMein 0:67a55a82ce06 36 */
DeMein 0:67a55a82ce06 37 struct _regs {
DeMein 0:67a55a82ce06 38 char regX[14];
DeMein 0:67a55a82ce06 39 char regY[14];
DeMein 0:67a55a82ce06 40 char regZ[14];
DeMein 0:67a55a82ce06 41 char regT[14];
DeMein 0:67a55a82ce06 42 char regL[14];
DeMein 0:67a55a82ce06 43 char regA[29];
DeMein 0:67a55a82ce06 44 } regs;
DeMein 0:67a55a82ce06 45
DeMein 0:67a55a82ce06 46 /**
DeMein 0:67a55a82ce06 47 * return the struct Regs via RPC as a character string
DeMein 0:67a55a82ce06 48 * RPC call is /regs_read/run
DeMein 0:67a55a82ce06 49 * RPC has a size limit of 64 bytes. Therefore, the result depends
DeMein 0:67a55a82ce06 50 * on the first character of the argument string:
DeMein 0:67a55a82ce06 51 * A returns Alpha,
DeMein 0:67a55a82ce06 52 * L returns LastX
DeMein 0:67a55a82ce06 53 * Anything else returns the complete stack X~T
DeMein 0:67a55a82ce06 54 * All numerical data is in internal format, client must convert numbers.
DeMein 0:67a55a82ce06 55 */
DeMein 0:67a55a82ce06 56 void rpc_regsread( char *input, char *output )
DeMein 0:67a55a82ce06 57 {
DeMein 0:67a55a82ce06 58 switch ( toupper( *input ) ) {
DeMein 0:67a55a82ce06 59
DeMein 0:67a55a82ce06 60 case 'A':
DeMein 0:67a55a82ce06 61 strcpy( output, regs.regA );
DeMein 0:67a55a82ce06 62 break;
DeMein 0:67a55a82ce06 63
DeMein 0:67a55a82ce06 64 case 'L':
DeMein 0:67a55a82ce06 65 memcpy( output, regs.regL, 14 );
DeMein 0:67a55a82ce06 66 output[ 14 ] = '\0';
DeMein 0:67a55a82ce06 67 break;
DeMein 0:67a55a82ce06 68
DeMein 0:67a55a82ce06 69 default:
DeMein 0:67a55a82ce06 70 memcpy( output, &regs, 4 * 14 );
DeMein 0:67a55a82ce06 71 output[ 4 * 14 ] = '\0';
DeMein 0:67a55a82ce06 72 }
DeMein 0:67a55a82ce06 73 }
DeMein 0:67a55a82ce06 74 RPCFunction rpcregs( rpc_regsread, "regs_read" );
DeMein 0:67a55a82ce06 75
DeMein 0:67a55a82ce06 76 /**
DeMein 0:67a55a82ce06 77 * main entry for parsing U-commands
DeMein 0:67a55a82ce06 78 *
DeMein 0:67a55a82ce06 79 */
DeMein 0:67a55a82ce06 80 void parse_U() {
DeMein 0:67a55a82ce06 81 DBG_msg("parse_U", inbuf);
DeMein 0:67a55a82ce06 82 err_num = noerror;
DeMein 0:67a55a82ce06 83
DeMein 0:67a55a82ce06 84 // wipesp(inbuf); // remove all spaces from string
DeMein 0:67a55a82ce06 85
DeMein 0:67a55a82ce06 86 if (inbuf[1] != NULL) {
DeMein 0:67a55a82ce06 87 switch (inbuf[1]) {
DeMein 0:67a55a82ce06 88 case utemp : do_utemp();
DeMein 0:67a55a82ce06 89 break;
DeMein 0:67a55a82ce06 90 case ustack : do_ustack();
DeMein 0:67a55a82ce06 91 break;
DeMein 0:67a55a82ce06 92 case ualpha : do_ualpha();
DeMein 0:67a55a82ce06 93 break;
DeMein 0:67a55a82ce06 94 default : do_udefault(); // command not recognized
DeMein 0:67a55a82ce06 95 break;
DeMein 0:67a55a82ce06 96 }
DeMein 0:67a55a82ce06 97 } else { do_udefault(); }
DeMein 0:67a55a82ce06 98 }
DeMein 0:67a55a82ce06 99
DeMein 0:67a55a82ce06 100 /** read TMP02 temp sensor
DeMein 0:67a55a82ce06 101 *
DeMein 0:67a55a82ce06 102 * syntax: UT return temp value in degrees C
DeMein 0:67a55a82ce06 103 * \n UTF return temp value in degrees F
DeMein 0:67a55a82ce06 104 */
DeMein 0:67a55a82ce06 105 void do_utemp(){
DeMein 0:67a55a82ce06 106 char s[20];
DeMein 0:67a55a82ce06 107 wipesp(inbuf); // remove spaces
DeMein 0:67a55a82ce06 108 DBG_msg("do_utemp", inbuf);
DeMein 0:67a55a82ce06 109
DeMein 0:67a55a82ce06 110 float temp = temperature.read();
DeMein 0:67a55a82ce06 111 if (inbuf[2] == 'F') {
DeMein 0:67a55a82ce06 112 temp = (temp * 1.8) + 32;
DeMein 0:67a55a82ce06 113 }
DeMein 0:67a55a82ce06 114
DeMein 0:67a55a82ce06 115 sprintf(s, "%.4f", temp);
DeMein 0:67a55a82ce06 116 DBG_msg("do_utemp", s);
DeMein 0:67a55a82ce06 117 mldl.tx_string(s);
DeMein 0:67a55a82ce06 118 }
DeMein 0:67a55a82ce06 119
DeMein 0:67a55a82ce06 120 /** read 7 bytes as a register from input stream
DeMein 0:67a55a82ce06 121 *
DeMein 0:67a55a82ce06 122 * @param *reg pointer to a register (14 chars)
DeMein 0:67a55a82ce06 123 * @return last char read if all OK, -1 or -2 when interrupted
DeMein 0:67a55a82ce06 124 *
DeMein 0:67a55a82ce06 125 */
DeMein 0:67a55a82ce06 126 int read_reg(char *reg) {
DeMein 0:67a55a82ce06 127 int i;
DeMein 0:67a55a82ce06 128 int c;
DeMein 0:67a55a82ce06 129
DeMein 0:67a55a82ce06 130 for (i = 0; i < 7; i++) {
DeMein 0:67a55a82ce06 131 c = mldl.rxx_read(data_mode); // get byte
DeMein 0:67a55a82ce06 132 // DBG_chr("read", c);
DeMein 0:67a55a82ce06 133 if ((c == -1) || (c == -2)) {
DeMein 0:67a55a82ce06 134 return c; // <EOF> or interrupt
DeMein 0:67a55a82ce06 135 } else {
DeMein 0:67a55a82ce06 136 // data OK
DeMein 0:67a55a82ce06 137 reg[i * 2] = ((c >> 4) & 0x0f ) + '0';
DeMein 0:67a55a82ce06 138 reg[i * 2 + 1] = (c & 0x0f) + '0';
DeMein 0:67a55a82ce06 139 // DBG_int("1 - ", reg[i*2]);
DeMein 0:67a55a82ce06 140 // DBG_int("2 - ", reg[i*2+1]);
DeMein 0:67a55a82ce06 141 }
DeMein 0:67a55a82ce06 142 }
DeMein 0:67a55a82ce06 143 return c;
DeMein 0:67a55a82ce06 144 }
DeMein 0:67a55a82ce06 145
DeMein 0:67a55a82ce06 146 /** read 28 bytes re[presenting the ALPHA registers M, N, O and Pm
DeMein 0:67a55a82ce06 147 *
DeMein 0:67a55a82ce06 148 * @return last char read if all OK, -1 or -2 when interrupted
DeMein 0:67a55a82ce06 149 */
DeMein 0:67a55a82ce06 150 int read_alpha() {
DeMein 0:67a55a82ce06 151 int i;
DeMein 0:67a55a82ce06 152 int c;
DeMein 0:67a55a82ce06 153
DeMein 0:67a55a82ce06 154 regs.regA[28] = NULL;
DeMein 0:67a55a82ce06 155 for (i = 0; i < 28; i++) {
DeMein 0:67a55a82ce06 156 c = mldl.rxx_read(data_mode); // get byte
DeMein 0:67a55a82ce06 157 // DBG_chr("read", c);
DeMein 0:67a55a82ce06 158 if ((c == -1) || (c == -2)) {
DeMein 0:67a55a82ce06 159 return c; // <EOF> or interrupt
DeMein 0:67a55a82ce06 160 } else {
DeMein 0:67a55a82ce06 161 regs.regA[i] = c;
DeMein 0:67a55a82ce06 162 }
DeMein 0:67a55a82ce06 163 }
DeMein 0:67a55a82ce06 164 return c;
DeMein 0:67a55a82ce06 165 }
DeMein 0:67a55a82ce06 166
DeMein 0:67a55a82ce06 167
DeMein 0:67a55a82ce06 168 /** show a register on the debug console
DeMein 0:67a55a82ce06 169 *
DeMein 0:67a55a82ce06 170 * @param *reg pointer to a register (14 chars
DeMein 0:67a55a82ce06 171 */
DeMein 0:67a55a82ce06 172 void show_reg(char *c, char *reg) {
DeMein 0:67a55a82ce06 173 char s[25];
DeMein 0:67a55a82ce06 174
DeMein 0:67a55a82ce06 175 sprintf(s, "%c.%c%c%c%c%c%c%c%c%c%c.%c.%c%c",
DeMein 0:67a55a82ce06 176 reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6],
DeMein 0:67a55a82ce06 177 reg[7], reg[8], reg[9], reg[10], reg[11], reg[12], reg[13]);
DeMein 0:67a55a82ce06 178 DBG_msg(c, s);
DeMein 0:67a55a82ce06 179 }
DeMein 0:67a55a82ce06 180
DeMein 0:67a55a82ce06 181 /** receive stack from HP41
DeMein 0:67a55a82ce06 182 *
DeMein 0:67a55a82ce06 183 * syntax: US<CR> [data]
DeMein 0:67a55a82ce06 184 * \n [data] is a binary stream of 5* 7 bytes
DeMein 0:67a55a82ce06 185 * procedure is like File Write due to processing of escape characters
DeMein 0:67a55a82ce06 186 * must send exact number of bytes, or terminate with '>F'
DeMein 0:67a55a82ce06 187 * representing X, Y, Z, T, L
DeMein 0:67a55a82ce06 188 */
DeMein 0:67a55a82ce06 189 void do_ustack() {
DeMein 0:67a55a82ce06 190 int i;
DeMein 0:67a55a82ce06 191
DeMein 0:67a55a82ce06 192 DBG_msg("do_ustack", inbuf);
DeMein 0:67a55a82ce06 193
DeMein 0:67a55a82ce06 194 // command is received, just send prompt
DeMein 0:67a55a82ce06 195
DeMein 0:67a55a82ce06 196 send_prompt(); // now send a prompt and we are ready to go
DeMein 0:67a55a82ce06 197
DeMein 0:67a55a82ce06 198 i = read_reg(regs.regX);
DeMein 0:67a55a82ce06 199 i = read_reg(regs.regY);
DeMein 0:67a55a82ce06 200 i = read_reg(regs.regZ);
DeMein 0:67a55a82ce06 201 i = read_reg(regs.regT);
DeMein 0:67a55a82ce06 202 i = read_reg(regs.regL);
DeMein 0:67a55a82ce06 203
DeMein 0:67a55a82ce06 204 if (i >= 0) {
DeMein 0:67a55a82ce06 205 show_reg("L", regs.regL);
DeMein 0:67a55a82ce06 206 show_reg("T", regs.regT);
DeMein 0:67a55a82ce06 207 show_reg("Z", regs.regZ);
DeMein 0:67a55a82ce06 208 show_reg("Y", regs.regY);
DeMein 0:67a55a82ce06 209 show_reg("X", regs.regX);
DeMein 0:67a55a82ce06 210 } else {
DeMein 0:67a55a82ce06 211 DBG_msg("do_ustack", "interrupted");
DeMein 0:67a55a82ce06 212 show_reg("L", regs.regL);
DeMein 0:67a55a82ce06 213 show_reg("T", regs.regT);
DeMein 0:67a55a82ce06 214 show_reg("Z", regs.regZ);
DeMein 0:67a55a82ce06 215 show_reg("Y", regs.regY);
DeMein 0:67a55a82ce06 216 show_reg("X", regs.regX);
DeMein 0:67a55a82ce06 217 }
DeMein 0:67a55a82ce06 218 }
DeMein 0:67a55a82ce06 219
DeMein 0:67a55a82ce06 220 /** receive alpha from HP41
DeMein 0:67a55a82ce06 221 *
DeMein 0:67a55a82ce06 222 * syntax: US<CR> [data]
DeMein 0:67a55a82ce06 223 * \n [data] is a binary stream of 24 bytes
DeMein 0:67a55a82ce06 224 * procedure is like File Write due to processing of escape characters
DeMein 0:67a55a82ce06 225 * must send exact number of bytes, or terminate with '>F'
DeMein 0:67a55a82ce06 226 */
DeMein 0:67a55a82ce06 227 void do_ualpha() {
DeMein 0:67a55a82ce06 228 int i, j;
DeMein 0:67a55a82ce06 229 char tempA[29];
DeMein 0:67a55a82ce06 230
DeMein 0:67a55a82ce06 231 DBG_msg("do_ualpha", inbuf);
DeMein 0:67a55a82ce06 232
DeMein 0:67a55a82ce06 233 i = read_alpha();
DeMein 0:67a55a82ce06 234
DeMein 0:67a55a82ce06 235 if (i >= 0) {
DeMein 0:67a55a82ce06 236 DBG_msg("ALPHA", regs.regA);
DeMein 0:67a55a82ce06 237 } else {
DeMein 0:67a55a82ce06 238 DBG_msg("do_ualpha", "interrupted");
DeMein 0:67a55a82ce06 239 DBG_msg("ALPHA", regs.regA);
DeMein 0:67a55a82ce06 240 return;
DeMein 0:67a55a82ce06 241 }
DeMein 0:67a55a82ce06 242
DeMein 0:67a55a82ce06 243 // now rearrange due to the ordering of ALPHA
DeMein 0:67a55a82ce06 244 tempA[ 0] = regs.regA[25];
DeMein 0:67a55a82ce06 245 tempA[ 1] = regs.regA[26];
DeMein 0:67a55a82ce06 246 tempA[ 2] = regs.regA[27]; // P register
DeMein 0:67a55a82ce06 247
DeMein 0:67a55a82ce06 248 tempA[ 3] = regs.regA[14];
DeMein 0:67a55a82ce06 249 tempA[ 4] = regs.regA[15];
DeMein 0:67a55a82ce06 250 tempA[ 5] = regs.regA[16];
DeMein 0:67a55a82ce06 251 tempA[ 6] = regs.regA[17];
DeMein 0:67a55a82ce06 252 tempA[ 7] = regs.regA[18];
DeMein 0:67a55a82ce06 253 tempA[ 8] = regs.regA[19];
DeMein 0:67a55a82ce06 254 tempA[ 9] = regs.regA[20]; // O register
DeMein 0:67a55a82ce06 255
DeMein 0:67a55a82ce06 256 tempA[10] = regs.regA[ 7];
DeMein 0:67a55a82ce06 257 tempA[11] = regs.regA[ 8];
DeMein 0:67a55a82ce06 258 tempA[12] = regs.regA[ 9];
DeMein 0:67a55a82ce06 259 tempA[13] = regs.regA[10];
DeMein 0:67a55a82ce06 260 tempA[14] = regs.regA[11];
DeMein 0:67a55a82ce06 261 tempA[15] = regs.regA[12];
DeMein 0:67a55a82ce06 262 tempA[16] = regs.regA[13]; // N register
DeMein 0:67a55a82ce06 263
DeMein 0:67a55a82ce06 264 tempA[17] = regs.regA[ 0];
DeMein 0:67a55a82ce06 265 tempA[18] = regs.regA[ 1];
DeMein 0:67a55a82ce06 266 tempA[19] = regs.regA[ 2];
DeMein 0:67a55a82ce06 267 tempA[20] = regs.regA[ 3];
DeMein 0:67a55a82ce06 268 tempA[21] = regs.regA[ 4];
DeMein 0:67a55a82ce06 269 tempA[22] = regs.regA[ 5];
DeMein 0:67a55a82ce06 270 tempA[23] = regs.regA[ 6]; // M-register
DeMein 0:67a55a82ce06 271
DeMein 0:67a55a82ce06 272 // find first real ALPHA char
DeMein 0:67a55a82ce06 273 i = 0;
DeMein 0:67a55a82ce06 274 while (tempA[i] == NULL) i++;
DeMein 0:67a55a82ce06 275
DeMein 0:67a55a82ce06 276 for (j = 0; (j + i + 1) < 25; j++) {
DeMein 0:67a55a82ce06 277 regs.regA[j] = tempA[i + j];
DeMein 0:67a55a82ce06 278 }
DeMein 0:67a55a82ce06 279
DeMein 0:67a55a82ce06 280 regs.regA[j] = NULL;
DeMein 0:67a55a82ce06 281
DeMein 0:67a55a82ce06 282 DBG_msg("ALPHA", regs.regA);
DeMein 0:67a55a82ce06 283
DeMein 0:67a55a82ce06 284 }
DeMein 0:67a55a82ce06 285
DeMein 0:67a55a82ce06 286 /** send error message, command not recognized,
DeMein 0:67a55a82ce06 287 */
DeMein 0:67a55a82ce06 288 void do_udefault() {
DeMein 0:67a55a82ce06 289 // command not recognized
DeMein 0:67a55a82ce06 290 DBG_msg("do_udefault", inbuf);
DeMein 0:67a55a82ce06 291 send_error(err_notrecognized);
DeMein 0:67a55a82ce06 292 }