MAX30001-MAX32630FTHR SYS EvKit

Dependencies:   USBDevice max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RpcServer.cpp Source File

RpcServer.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 #include "RpcServer.h"
00034 #include "StringInOut.h"
00035 #include "StringHelper.h"
00036 #include "MAX30001_RPC.h"
00037 #include "Logging_RPC.h"
00038 #include "Peripherals.h"
00039 #include "HspLed_RPC.h"
00040 #include "S25FS512_RPC.h"
00041 #include "Testing_RPC.h"
00042 #include "RpcDeclarations.h"
00043 #include "Device_Logging.h"
00044 #include "../version.h"
00045 
00046 /// define the version string that is reported with a RPC "ReadVer" command
00047 #define FW_VERSION_STRING "MAX30001 FW Ver"
00048 
00049 char args[32][32];
00050 char results[32][32];
00051 
00052 /// define a fifo for incoming USB data
00053 static fifo_t fifo;
00054 /// define a buffer for incoming USB data
00055 static uint8_t fifoBuffer[128];
00056 /// define stream out fifo
00057 static fifo_t fifoStreamOut;
00058 /// allocate a large fifo buffer for streaming out
00059 static uint32_t streamOutBuffer[0xC000 / 4];
00060 
00061 /// define a device log for the BMP280, keeps track of mission and loggin status
00062 Device_Logging *bmp280_Logging;
00063 /// define a device log for the MAX30205 (instance 0), keeps track of mission
00064 /// and loggin status
00065 Device_Logging *MAX30205_0_Logging;
00066 /// define a device log for the MAX30205 (instance 1), keeps track of mission
00067 /// and loggin status
00068 Device_Logging *MAX30205_1_Logging;
00069 
00070 //******************************************************************************
00071 fifo_t *GetUSBIncomingFifo(void) { return &fifo; }
00072 
00073 //******************************************************************************
00074 fifo_t *GetStreamOutFifo(void) { return &fifoStreamOut; }
00075 
00076 //******************************************************************************
00077 int System_ReadVer(char argStrs[32][32], char replyStrs[32][32]) {
00078   char version[32];
00079   snprintf(version, sizeof(version)/sizeof(char), "%s %d.%d.%d %02d/%02d/%02d", 
00080   FW_VERSION_STRING, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
00081   VERSION_MONTH, VERSION_DAY, VERSION_SHORT_YEAR);
00082   strcpy(replyStrs[0], version);
00083   strcpy(replyStrs[1], "\0");
00084   return 0;
00085 }
00086 
00087 //******************************************************************************
00088 int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]) {
00089   // strcpy(replyStrs[0],buildTime);
00090   // strcpy(replyStrs[1],"\0");
00091   return 0;
00092 }
00093 
00094 //******************************************************************************
00095 int System_SystemCoreClock(char argStrs[32][32], char replyStrs[32][32]) {
00096   sprintf(replyStrs[0], "SystemCoreClock = %d", SystemCoreClock);
00097   strcpy(replyStrs[1], "\0");
00098   return 0;
00099 }
00100 
00101 //******************************************************************************
00102 int System_GetTimestamp(char argStrs[32][32], char replyStrs[32][32]) {
00103   sprintf(replyStrs[0], "GetTimestamp = %d", 0);
00104   strcpy(replyStrs[1], "\0");
00105   return 0;
00106 }
00107 
00108 static struct RPC_Object RPC_Procedures = {NULL, NULL};
00109 
00110 //******************************************************************************
00111 void RPC_addProcedure(struct RPC_registeredProcedure *procedure) {
00112   struct RPC_Object *obj = &RPC_Procedures;
00113   if (obj->last != NULL) {
00114     obj->last->next = procedure;
00115   }
00116   if (obj->head == NULL) {
00117     obj->head = procedure;
00118   }
00119   procedure->next = NULL;
00120   obj->last = procedure;
00121 }
00122 
00123 //******************************************************************************
00124 void RPC_init(void) {
00125 
00126   fifo_init(&fifo, fifoBuffer, sizeof(fifoBuffer));
00127   fifo_init(&fifoStreamOut, streamOutBuffer,
00128             sizeof(streamOutBuffer) / sizeof(uint32_t));
00129 
00130   // MAX30001
00131   RPC_addProcedure(&Define_MAX30001_WriteReg);
00132   RPC_addProcedure(&Define_MAX30001_ReadReg);
00133   RPC_addProcedure(&Define_MAX30001_Start);
00134   RPC_addProcedure(&Define_MAX30001_Stop);
00135   RPC_addProcedure(&Define_MAX30001_Enable_ECG_LeadON);
00136   RPC_addProcedure(&Define_MAX30001_Enable_BIOZ_LeadON);
00137   RPC_addProcedure(&Define_MAX30001_Read_LeadON);
00138   RPC_addProcedure(&Define_MAX30001_StartTest);
00139   RPC_addProcedure(&Define_MAX30001_INT_assignment);
00140   RPC_addProcedure(&Define_MAX30001_Rbias_FMSTR_Init);
00141   RPC_addProcedure(&Define_MAX30001_CAL_InitStart);
00142   RPC_addProcedure(&Define_MAX30001_ECG_InitStart);
00143   RPC_addProcedure(&Define_MAX30001_ECGFast_Init);
00144   RPC_addProcedure(&Define_MAX30001_PACE_InitStart);
00145   RPC_addProcedure(&Define_MAX30001_BIOZ_InitStart);
00146   RPC_addProcedure(&Define_MAX30001_RtoR_InitStart);
00147   RPC_addProcedure(&Define_MAX30001_Stop_ECG);
00148   RPC_addProcedure(&Define_MAX30001_Stop_PACE);
00149   RPC_addProcedure(&Define_MAX30001_Stop_BIOZ);
00150   RPC_addProcedure(&Define_MAX30001_Stop_RtoR);
00151   RPC_addProcedure(&Define_MAX30001_Stop_Cal);
00152 
00153   // Logging
00154   RPC_addProcedure(&Define_Logging_StartMissionDefine);
00155   RPC_addProcedure(&Define_Logging_AppendMissionCmd);
00156   RPC_addProcedure(&Define_Logging_EndMissionDefine);
00157   RPC_addProcedure(&Define_Logging_WriteMission);
00158   RPC_addProcedure(&Define_Logging_ReadMission);
00159   RPC_addProcedure(&Define_Logging_EraseMission);
00160   RPC_addProcedure(&Define_Logging_EraseWrittenSectors);
00161   RPC_addProcedure(&Define_Logging_StartLoggingUsb);
00162   RPC_addProcedure(&Define_Logging_StartLoggingFlash);
00163   RPC_addProcedure(&Define_Logging_GetLastWrittenPage);
00164   RPC_addProcedure(&Define_Logging_Start);
00165 
00166   // led
00167   RPC_addProcedure(&Define_Led_On);
00168   RPC_addProcedure(&Define_Led_Off);
00169   RPC_addProcedure(&Define_Led_BlinkHz);
00170   RPC_addProcedure(&Define_Led_BlinkPattern);
00171 
00172   // S25FS512
00173   RPC_addProcedure(&Define_S25FS512_ReadId);
00174   RPC_addProcedure(&Define_S25FS512_ReadPagesBinary);
00175   RPC_addProcedure(&Define_S25FS512_Reset);
00176   RPC_addProcedure(&Define_S25FS512_EnableHWReset);
00177   RPC_addProcedure(&Define_S25FS512_SpiWriteRead);
00178   RPC_addProcedure(&Define_S25FS512_SpiWriteRead4Wire);
00179 
00180   RPC_addProcedure(&Define_Testing_Test_MAX30001);
00181   
00182   // SDCard
00183   RPC_addProcedure(&Define_SDCard_IsReady);
00184 
00185   // System
00186   RPC_addProcedure(&Define_System_ReadVer);
00187   RPC_addProcedure(&Define_System_ReadBuildTime);
00188 }
00189 
00190 //******************************************************************************
00191 struct RPC_registeredProcedure *RPC_lookup(char *objectName, char *methodName) {
00192   struct RPC_registeredProcedure *ptr;
00193   // lookup all registered methods
00194   ptr = RPC_Procedures.head;
00195   while (ptr != NULL) {
00196     if (strcmp(ptr->objectName, objectName) == 0 &&
00197         strcmp(ptr->methodName, methodName) == 0) {
00198       // we found a match... return with it
00199       return ptr;
00200     }
00201     ptr = ptr->next;
00202   }
00203   return NULL;
00204 }
00205 
00206 //******************************************************************************
00207 char *GetToken(char *inStr, char *outStr, int start, char ch) {
00208   int i;
00209   int index = 0;
00210   int length = strlen(inStr);
00211   for (i = start; i < length; i++) {
00212     if (inStr[i] != ch) {
00213       outStr[index++] = inStr[i];
00214     } else {
00215       break;
00216     }
00217   }
00218   outStr[index++] = 0;
00219   return outStr;
00220 }
00221 
00222 //******************************************************************************
00223 void SendCommandList(char *reply) {
00224   struct RPC_registeredProcedure *ptr;
00225   reply[0] = 0;
00226   ptr = RPC_Procedures.head;
00227   while (ptr != NULL) {
00228     strcat(reply, "/");
00229     strcat(reply, ptr->objectName);
00230     strcat(reply, "/");
00231     strcat(reply, ptr->methodName);
00232     strcat(reply, ",");
00233     ptr = ptr->next;
00234   }
00235   strcat(reply, "\r\n");
00236 }
00237 
00238 //******************************************************************************
00239 int CheckForDoubleQuote(char *str) {
00240   int doubleQuoteFound;
00241   // scan through arguments, see if there is a double quote for a string
00242   // argument
00243   doubleQuoteFound = 0;
00244   while (*str != 0) {
00245     if (*str == '\"') {
00246       doubleQuoteFound = 1;
00247       break;
00248     }
00249     str++;
00250   }
00251   return doubleQuoteFound;
00252 }
00253 
00254 //******************************************************************************
00255 void ExtractDoubleQuoteStr(char *src, char *dst) {
00256   int start;
00257 
00258   dst[0] = 0;
00259   start = 0;
00260   while (*src != 0) {
00261     // look for start
00262     if ((*src == '\"') && (start == 0)) {
00263       start = 1;
00264       src++;
00265       continue;
00266     }
00267     // look for end
00268     if ((*src == '\"') && (start == 1)) {
00269       *dst = 0; // terminate the string
00270       break;
00271     }
00272     if (start == 1) {
00273       *dst = *src;
00274       dst++;
00275     }
00276     src++;
00277   }
00278 }
00279 
00280 //******************************************************************************
00281 void RPC_call_test(void) {
00282   int doubleQuoteFound;
00283   char doubleQuoteStr[64];
00284   char *request = "/Logging/AppendMissionCmd \"BMP280 InitStart 1\"";
00285 
00286   // scan through arguments, see if there is a double quote for a string
00287   // argument
00288   doubleQuoteFound = CheckForDoubleQuote(request);
00289   if (doubleQuoteFound) {
00290     ExtractDoubleQuoteStr(request, doubleQuoteStr);
00291   }
00292 }
00293 
00294 //******************************************************************************
00295 void RPC_call(char *request, char *reply) {
00296   const char slash[2] = "/";
00297   const char space[2] = " ";
00298   char *objectName;
00299   char *methodName;
00300   char doubleQuoteStr[128];
00301   char requestCpy[256];
00302   char *token;
00303   int argIndex;
00304   int resultIndex;
00305   int doubleQuoteFound;
00306   struct RPC_registeredProcedure *procedurePtr;
00307 
00308   // clear out the reply
00309   reply[0] = 0;
00310   // copy the request for scanning and extraction later
00311   strcpy(requestCpy, request);
00312   // check for beginning forward slash
00313   if (request[0] != '/') {
00314     return;
00315   }
00316   // check for only a forward slash
00317   if (request[0] == '/' && request[1] == 0) {
00318     SendCommandList(reply);
00319     return;
00320   }
00321   strcat(request, " ");
00322   // get the object name
00323   token = strtok(request, slash);
00324   // token = GetToken(request, tokenBuffer, 1, '/');
00325   objectName = token;
00326   if (objectName == NULL)
00327     return; // must have an object name
00328   // get the method name
00329   token = strtok(NULL, space);
00330   methodName = token;
00331   if (methodName == NULL)
00332     return; // must have a method name
00333 
00334   // scan through arguments, see if there is a double quote for a string
00335   // argument
00336   doubleQuoteFound = CheckForDoubleQuote(requestCpy);
00337 
00338   if (doubleQuoteFound == 0) {
00339     // walk through arguments
00340     argIndex = 0;
00341     token = strtok(NULL, space);
00342     while (token != NULL) {
00343       // save this arg in array
00344       strcpy(args[argIndex++], token);
00345       // read next token arg if any
00346       token = strtok(NULL, space);
00347     }
00348     // terminate the end of the string array with an empty string
00349     strcpy(args[argIndex], "\0");
00350     strcpy(results[0], "\0");
00351   } else {
00352     // grab out the double quote string
00353     ExtractDoubleQuoteStr(requestCpy, doubleQuoteStr);
00354     argIndex = 0;
00355     // token = strtok(NULL, quote);
00356     strcpy(args[argIndex++], doubleQuoteStr);
00357   }
00358 
00359   //
00360   // alias the MAX30001 and MAX30003 names
00361   //
00362   if (strcmp(objectName, MAX30003_NAME) == 0) {
00363     strcpy(objectName, MAX30001_NAME);
00364   }
00365 
00366   procedurePtr = RPC_lookup(objectName, methodName);
00367   if (procedurePtr != NULL) {
00368     // printf("RPC_call: %s processing\n",requestCpy);
00369     procedurePtr->func(args, results);
00370   } else {
00371     printf("RPC_call: %s not found\n", requestCpy);
00372     // printf("Unable to lookup %s %s", objectName, methodName);
00373   }
00374 
00375   // loop while (if) there are results to return
00376   resultIndex = 0;
00377   strcpy(reply, "\0");
00378   while (results[resultIndex][0] != '\0') {
00379     strcat(reply, results[resultIndex++]);
00380     strcat(reply, " ");
00381   }
00382   strcat(reply, "\r\n");
00383 }
00384 
00385 //******************************************************************************
00386 void RPC_ProcessCmds(char *cmds) {
00387   char cmd[32 * 32];
00388   char *ptrCmds;
00389   char reply[512];
00390   ptrCmds = cmds;
00391 
00392   while (*ptrCmds != 0) {
00393     ptrCmds = ParseUntilCRLF(ptrCmds, cmd, sizeof(cmd));
00394     if (*cmd != 0) {
00395       RPC_call(cmd, reply);
00396     }
00397   }
00398 }
00399