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
ufuncs.cpp
- Committer:
- DeMein
- Date:
- 2011-02-27
- Revision:
- 0:67a55a82ce06
File content as of revision 0:67a55a82ce06:
/* 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, ®s, 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); }