dataXfer.c

Go to the documentation of this file.
00001 #include "dataXfer.h"
00002 #include <string.h>
00003 #include <stdio.h>
00004 
00009 void initDataXfer() {
00010   resetReceiveMachine();
00011   clearReceiveStruct();
00012 }
00013 
00014 
00016 
00017 
00018 void xferOutChar(char c) {
00019   // If we're sending a character that needs escaping, then escape it.
00020   OUT_CHAR(c);
00021   if (c == CMD_TOKEN)
00022     OUT_CHAR(ESCAPED_CMD);
00023 }
00024 
00025 void specifyVar(uint u_varIndex, void* pv_data, uint u_size, 
00026                 BOOL b_isWriteable, char* psz_format, char* psz_name,
00027                 char* psz_desc) {
00028   uint u_len;
00029 
00030   // Make sure this variable exists
00031   ASSERTM("specifyVar:indexTooHigh", u_varIndex < NUM_XFER_VARS);
00032   // Make sure the data isn't NULL
00033   ASSERTM("specifyVar:nullData", pv_data != NULL);
00034   // Make sure the size is valid
00035   ASSERTM("specifyVar:invalidSize", (u_size > 0) && (u_size <= 256));
00036 
00037   // Update data structure
00038   xferVar[u_varIndex].pu8_data = (uint8*) pv_data;
00039   xferVar[u_varIndex].u8_size = u_size - 1;
00040   assignBit(u_varIndex, b_isWriteable);
00041 
00042   // Send a command
00043   OUT_CHAR(CMD_TOKEN);
00044 
00045   // Send a specification: The spec code, index, then length
00046   xferOutChar(b_isWriteable ? CMD_SEND_RECEIVE_VAR : CMD_SEND_ONLY);
00047   xferOutChar(u_varIndex);
00048   // Include the space taken by the three NULL characters, minus one since a
00049   // length of 1 is sent as 0, plus one for the variable size byte.
00050   u_len = strlen(psz_format) + strlen(psz_name) + strlen(psz_desc) + 3 - 1 + 1;
00051   // Allow a maximum string length of 255.
00052   xferOutChar(u_len <= 255 ? u_len : 255);
00053 
00054   // Send the size of this variable, minus 1 since a size of 1 is sent as a 0.
00055   xferOutChar(u_size - 1);
00056 
00057   // Send the strings
00058   u_len = 1;
00059   do {
00060     if (u_len++ > 256) return;
00061     xferOutChar(*psz_format);
00062   } while (*psz_format++);
00063   do {
00064     if (u_len++ > 256) return;
00065     xferOutChar(*psz_name);
00066   } while (*psz_name++);
00067   do {
00068     if (u_len++ > 256) return;
00069     xferOutChar(*psz_desc);
00070   } while (*psz_desc++);
00071 }
00072 
00073 void sendVar(uint u_varIndex) {
00074   XFER_VAR* pXferVar;
00075   uint8 u8_size;
00076   uint8* pu8_data;
00077   // Make sure this variable exists
00078   ASSERTM("sendVar:indexTooHigh", u_varIndex < NUM_XFER_VARS);
00079   // Note: The MS C compiler flags the statement
00080   // XFER_VAR* pXferVar = xferVar + u_varIndex;
00081   // as an error. It's OK in MS C++. Apparently, the C compiler doesn't
00082   // support the newer C99 syntax. Therefore, u8_size and pu8_data are
00083   // also declared above.
00084   pXferVar = xferVar + u_varIndex;
00085   ASSERTM("sendVar:indexNotSpecified", pXferVar->pu8_data != NULL);
00086   // Make sure it's read/write (PC only)
00087 #ifndef __PIC__
00088   ASSERTM("sendVar:notWriteable", isVarWriteable(u_varIndex));
00089 #endif
00090 
00091   // Send a command
00092   OUT_CHAR(CMD_TOKEN);
00093 
00094   // Send short/long var info
00095   u8_size = pXferVar->u8_size;
00096   if ((u8_size + 1) > SHORT_VAR_MAX_LEN) {
00097     // Send a long var: The long var code, index, then length
00098     xferOutChar(CMD_LONG_VAR);
00099     xferOutChar(u_varIndex);
00100     xferOutChar(u8_size);
00101   } else {
00102     // Send a short var
00103     xferOutChar((u_varIndex << VAR_SIZE_BITS) | u8_size);
00104   }
00105 
00106   // Send data
00107   pu8_data = pXferVar->pu8_data;
00108   do {
00109     xferOutChar(*pu8_data++);
00110   } while (u8_size--);
00111 }
00112 
00114 
00115 #ifndef __PIC__
00116 int formatVar(uint u_varIndex, char* psz_buf) {
00117   XFER_VAR* pXferVar;
00118   uint8 u8_size;
00119   unsigned long long ull_buf = 0;  // The biggest data type available
00120 
00121   // Make sure this variable exists
00122   ASSERTM("formatVar:indexTooHigh", u_varIndex < NUM_XFER_VARS);
00123   // Note: The MS C compiler flags the statement
00124   // XFER_VAR* pXferVar = xferVar + u_varIndex;
00125   // as an error. It's OK in MS C++. Apparently, the C compiler doesn't
00126   // support the newer C99 syntax. Therefore, u8_size and pu8_data are
00127   // also declared above.
00128   pXferVar = xferVar + u_varIndex;
00129   ASSERTM("formatVar:indexNotSpecified", pXferVar->pu8_data != NULL);
00130   u8_size = pXferVar->u8_size + 1;
00131 
00132   // Copy the data over to the largest available var for formatting
00133   ASSERT(u8_size <= sizeof(ull_buf));
00134   memcpy(&ull_buf, pXferVar->pu8_data, u8_size);
00135   return sprintf(psz_buf, pXferVar->psz_format, ull_buf);
00136 }
00137 #endif
00138 
00139 #ifdef __PIC__
00140 uint receiveVar(char* c) {
00141     uint u_index;
00142 
00143   // Receive the data by stepping the machine until it outputs
00144   // something
00145   do {
00146     // While there's no data, run the timeout counter
00147     RECEIVE_ERROR re;
00148     char c;
00149     uint32 u32_count = 0;
00150     while (!isCharReady()) {
00151       if (u32_count < RECEIVE_TIMEOUT)
00152         u32_count++;
00153       doHeartbeat();
00154     }
00155 
00156     // Step the machine
00157     c = inChar();
00158     re = stepReceiveMachine(c, u32_count >= RECEIVE_TIMEOUT);
00159     if (re != ERR_NONE) {
00160       outString("Data receive error: ");
00161       outString(getReceiveErrorString());
00162       outChar('\n');
00163     }
00164   } while (!isReceiveMachineChar(c) && !isReceiveMachineData(&u_index));
00165 
00166   return getReceiveMachineIndex();
00167 }
00168 
00169 char inCharXfer() {
00170   char c;
00171   while (receiveVar(&c) != CHAR_RECEIVED_INDEX);
00172   return c;
00173 }
00174 #endif

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9