MAX32620HSP (MAXREFDES100) RPC Example for Graphical User Interface

Dependencies:   USBDevice

Fork of HSP_Release by Jerry Bradshaw

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 "MAX30101_RPC.h"
00038 #include "LIS2DH_RPC.h"
00039 #include "Logging_RPC.h"
00040 #include "Peripherals.h"
00041 #include "I2C_RPC.h"
00042 #include "BMP280_RPC.h"
00043 #include "MAX30205_RPC.h"
00044 #include "HspLed_RPC.h"
00045 #include "S25FS512_RPC.h"
00046 #include "Testing_RPC.h"
00047 #include "MAX14720_RPC.h"
00048 #include "RpcDeclarations.h"
00049 #include "Device_Logging.h"
00050 
00051 /// define the version string that is reported with a RPC "ReadVer" command
00052 #define FW_VERSION_STRING "HSP FW Version 3.0.1 4/21/16"
00053 
00054 char args[32][32];
00055 char results[32][32];
00056 
00057 /// define a fifo for incoming USB data
00058 static fifo_t fifo;
00059 /// define a buffer for incoming USB data
00060 static uint8_t fifoBuffer[128];
00061 /// define stream out fifo
00062 static fifo_t fifoStreamOut;
00063 /// allocate a large fifo buffer for streaming out
00064 static uint32_t streamOutBuffer[0xC000 / 4];
00065 
00066 /// define a device log for the BMP280, keeps track of mission and loggin status
00067 Device_Logging *bmp280_Logging;
00068 /// define a device log for the MAX30205 (instance 0), keeps track of mission
00069 /// and loggin status
00070 Device_Logging *MAX30205_0_Logging;
00071 /// define a device log for the MAX30205 (instance 1), keeps track of mission
00072 /// and loggin status
00073 Device_Logging *MAX30205_1_Logging;
00074 
00075 ///Defines a timer to detect if a series of binary pages are being transfered via RPC
00076 Timer rpcFlashPagesTransferTimer;
00077 bool rpcFlashPagesTransferTimer_running;
00078 
00079 //******************************************************************************
00080 fifo_t *GetUSBIncomingFifo(void) { return &fifo; }
00081 
00082 //******************************************************************************
00083 fifo_t *GetStreamOutFifo(void) { return &fifoStreamOut; }
00084 
00085 //******************************************************************************
00086 int System_ReadVer(char argStrs[32][32], char replyStrs[32][32]) {
00087   strcpy(replyStrs[0], FW_VERSION_STRING);
00088   strcpy(replyStrs[1], "\0");
00089   return 0;
00090 }
00091 
00092 //******************************************************************************
00093 bool RPC_IsTransferingFlashPages(void) {
00094   if (rpcFlashPagesTransferTimer_running == true) {
00095     if (rpcFlashPagesTransferTimer.read_ms() < 200) {
00096       return true;
00097     } else {
00098       rpcFlashPagesTransferTimer.stop();
00099       rpcFlashPagesTransferTimer_running = false;
00100     }
00101   }
00102   return false;
00103 }
00104 
00105 //******************************************************************************
00106 void RPC_TransferingFlashPages(void) {
00107   if (rpcFlashPagesTransferTimer_running == false) {
00108     rpcFlashPagesTransferTimer.start();
00109     rpcFlashPagesTransferTimer_running = true;
00110   }
00111   rpcFlashPagesTransferTimer.reset();
00112 }
00113 
00114 //******************************************************************************
00115 int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]) {
00116   // strcpy(replyStrs[0],buildTime);
00117   // strcpy(replyStrs[1],"\0");
00118   return 0;
00119 }
00120 
00121 //******************************************************************************
00122 int System_SystemCoreClock(char argStrs[32][32], char replyStrs[32][32]) {
00123   sprintf(replyStrs[0], "SystemCoreClock = %d", (unsigned int)SystemCoreClock);
00124   strcpy(replyStrs[1], "\0");
00125   return 0;
00126 }
00127 
00128 //******************************************************************************
00129 int System_GetTimestamp(char argStrs[32][32], char replyStrs[32][32]) {
00130   sprintf(replyStrs[0], "GetTimestamp = %d", 0);
00131   strcpy(replyStrs[1], "\0");
00132   return 0;
00133 }
00134 
00135 static struct RPC_Object RPC_Procedures = {NULL, NULL};
00136 
00137 //******************************************************************************
00138 void RPC_addProcedure(struct RPC_registeredProcedure *procedure) {
00139   struct RPC_Object *obj = &RPC_Procedures;
00140   if (obj->last != NULL) {
00141     obj->last->next = procedure;
00142   }
00143   if (obj->head == NULL) {
00144     obj->head = procedure;
00145   }
00146   procedure->next = NULL;
00147   obj->last = procedure;
00148 }
00149 
00150 //******************************************************************************
00151 void RPC_init(void) {
00152   bmp280_Logging = new Device_Logging();
00153   MAX30205_0_Logging = new Device_Logging();
00154   MAX30205_1_Logging = new Device_Logging();
00155 
00156   rpcFlashPagesTransferTimer_running = false;
00157 
00158   fifo_init(&fifo, fifoBuffer, sizeof(fifoBuffer));
00159   fifo_init(&fifoStreamOut, streamOutBuffer,
00160             sizeof(streamOutBuffer) / sizeof(uint32_t));
00161 
00162   // I2c
00163   RPC_addProcedure(&Define_I2c_WriteRead);
00164 
00165   // MAX30101
00166   RPC_addProcedure(&Define_MAX30101_WriteReg);
00167   RPC_addProcedure(&Define_MAX30101_ReadReg);
00168   RPC_addProcedure(&Define_MAX30101_SpO2mode_Init);
00169   RPC_addProcedure(&Define_MAX30101_HRmode_Init);
00170   RPC_addProcedure(&Define_MAX30101_Multimode_init);
00171   RPC_addProcedure(&Define_MAX30101_SpO2mode_InitStart);
00172   RPC_addProcedure(&Define_MAX30101_HRmode_InitStart);
00173   RPC_addProcedure(&Define_MAX30101_Multimode_InitStart);
00174   RPC_addProcedure(&Define_MAX30101_SpO2mode_stop);
00175   RPC_addProcedure(&Define_MAX30101_HRmode_stop);
00176   RPC_addProcedure(&Define_MAX30101_Multimode_stop);
00177 
00178   // MAX30001
00179   RPC_addProcedure(&Define_MAX30001_WriteReg);
00180   RPC_addProcedure(&Define_MAX30001_ReadReg);
00181   RPC_addProcedure(&Define_MAX30001_Start);
00182   RPC_addProcedure(&Define_MAX30001_Stop);
00183   RPC_addProcedure(&Define_MAX30001_Enable_ECG_LeadON);
00184   RPC_addProcedure(&Define_MAX30001_Enable_BIOZ_LeadON);
00185   RPC_addProcedure(&Define_MAX30001_Read_LeadON);
00186   RPC_addProcedure(&Define_MAX30001_StartTest);
00187   RPC_addProcedure(&Define_MAX30001_INT_assignment);
00188   RPC_addProcedure(&Define_MAX30001_Rbias_FMSTR_Init);
00189   RPC_addProcedure(&Define_MAX30001_CAL_InitStart);
00190   RPC_addProcedure(&Define_MAX30001_ECG_InitStart);
00191   RPC_addProcedure(&Define_MAX30001_ECGFast_Init);
00192   RPC_addProcedure(&Define_MAX30001_PACE_InitStart);
00193   RPC_addProcedure(&Define_MAX30001_BIOZ_InitStart);
00194   RPC_addProcedure(&Define_MAX30001_RtoR_InitStart);
00195   RPC_addProcedure(&Define_MAX30001_Stop_ECG);
00196   RPC_addProcedure(&Define_MAX30001_Stop_PACE);
00197   RPC_addProcedure(&Define_MAX30001_Stop_BIOZ);
00198   RPC_addProcedure(&Define_MAX30001_Stop_RtoR);
00199   RPC_addProcedure(&Define_MAX30001_Stop_Cal);
00200 
00201   // Logging
00202   RPC_addProcedure(&Define_Logging_StartMissionDefine);
00203   RPC_addProcedure(&Define_Logging_AppendMissionCmd);
00204   RPC_addProcedure(&Define_Logging_EndMissionDefine);
00205   RPC_addProcedure(&Define_Logging_WriteMission);
00206   RPC_addProcedure(&Define_Logging_ReadMission);
00207   RPC_addProcedure(&Define_Logging_EraseMission);
00208   RPC_addProcedure(&Define_Logging_EraseWrittenSectors);
00209   RPC_addProcedure(&Define_Logging_StartLoggingUsb);
00210   RPC_addProcedure(&Define_Logging_StartLoggingFlash);
00211   RPC_addProcedure(&Define_Logging_GetLastWrittenPage);
00212   RPC_addProcedure(&Define_Logging_Start);
00213 
00214   // LIS2HD
00215   RPC_addProcedure(&Define_LIS2DH_InitStart);
00216   RPC_addProcedure(&Define_LIS2DH_ReadReg);
00217   RPC_addProcedure(&Define_LIS2DH_WriteReg);
00218   RPC_addProcedure(&Define_LIS2DH_Stop);
00219 
00220   // BMP280
00221   RPC_addProcedure(&Define_BMP280_InitStart);
00222 
00223   // MAX30205 and MAX31725 Alias
00224   RPC_addProcedure(&Define_MAX30205_1_InitStart);
00225   RPC_addProcedure(&Define_MAX30205_2_InitStart);
00226   RPC_addProcedure(&Define_MAX31725_1_InitStart);
00227   RPC_addProcedure(&Define_MAX31725_2_InitStart);
00228 
00229   // led
00230   RPC_addProcedure(&Define_Led_On);
00231   RPC_addProcedure(&Define_Led_Off);
00232   RPC_addProcedure(&Define_Led_BlinkHz);
00233   RPC_addProcedure(&Define_Led_BlinkPattern);
00234 
00235   // S25FS512
00236   RPC_addProcedure(&Define_S25FS512_ReadId);
00237   RPC_addProcedure(&Define_S25FS512_ReadPagesBinary);
00238   RPC_addProcedure(&Define_S25FS512_Reset);
00239   RPC_addProcedure(&Define_S25FS512_EnableHWReset);
00240   RPC_addProcedure(&Define_S25FS512_SpiWriteRead);
00241   RPC_addProcedure(&Define_S25FS512_SpiWriteRead4Wire);
00242 
00243   // Testing
00244   RPC_addProcedure(&Define_Testing_Test_S25FS512);
00245   RPC_addProcedure(&Define_Testing_Test_BMP280);
00246   RPC_addProcedure(&Define_Testing_Test_LIS2DH);
00247   RPC_addProcedure(&Define_Testing_Test_LSM6DS3);
00248   RPC_addProcedure(&Define_Testing_Test_MAX30205_1);
00249   RPC_addProcedure(&Define_Testing_Test_MAX30205_2);
00250   RPC_addProcedure(&Define_Testing_Test_MAX30101);
00251   RPC_addProcedure(&Define_Testing_Test_MAX30001);
00252   RPC_addProcedure(&Define_Testing_Test_EM9301);
00253 
00254   // System
00255   RPC_addProcedure(&Define_System_ReadVer);
00256   RPC_addProcedure(&Define_System_ReadBuildTime);
00257 
00258   // MAX14720
00259   RPC_addProcedure(&Define_MAX14720_ReadBoostVSet);
00260   RPC_addProcedure(&Define_MAX14720_WriteBoostVSet);
00261   RPC_addProcedure(&Define_MAX14720_ReadReg);
00262   RPC_addProcedure(&Define_MAX14720_WriteReg);
00263 }
00264 
00265 //******************************************************************************
00266 struct RPC_registeredProcedure *RPC_lookup(char *objectName, char *methodName) {
00267   struct RPC_registeredProcedure *ptr;
00268   // lookup all registered methods
00269   ptr = RPC_Procedures.head;
00270   while (ptr != NULL) {
00271     if (strcmp(ptr->objectName, objectName) == 0 &&
00272         strcmp(ptr->methodName, methodName) == 0) {
00273       // we found a match... return with it
00274       return ptr;
00275     }
00276     ptr = ptr->next;
00277   }
00278   return NULL;
00279 }
00280 
00281 //******************************************************************************
00282 char *GetToken(char *inStr, char *outStr, int start, char ch) {
00283   int i;
00284   int index = 0;
00285   int length = strlen(inStr);
00286   for (i = start; i < length; i++) {
00287     if (inStr[i] != ch) {
00288       outStr[index++] = inStr[i];
00289     } else {
00290       break;
00291     }
00292   }
00293   outStr[index++] = 0;
00294   return outStr;
00295 }
00296 
00297 //******************************************************************************
00298 void SendCommandList(char *reply) {
00299   struct RPC_registeredProcedure *ptr;
00300   reply[0] = 0;
00301   ptr = RPC_Procedures.head;
00302   while (ptr != NULL) {
00303     strcat(reply, "/");
00304     strcat(reply, ptr->objectName);
00305     strcat(reply, "/");
00306     strcat(reply, ptr->methodName);
00307     strcat(reply, ",");
00308     ptr = ptr->next;
00309   }
00310   strcat(reply, "\r\n");
00311 }
00312 
00313 //******************************************************************************
00314 int CheckForDoubleQuote(const char *str) {
00315   int doubleQuoteFound;
00316   // scan through arguments, see if there is a double quote for a string
00317   // argument
00318   doubleQuoteFound = 0;
00319   while (*str != 0) {
00320     if (*str == '\"') {
00321       doubleQuoteFound = 1;
00322       break;
00323     }
00324     str++;
00325   }
00326   return doubleQuoteFound;
00327 }
00328 
00329 //******************************************************************************
00330 void ExtractDoubleQuoteStr(const char *src, char *dst) {
00331   int start;
00332 
00333   dst[0] = 0;
00334   start = 0;
00335   while (*src != 0) {
00336     // look for start
00337     if ((*src == '\"') && (start == 0)) {
00338       start = 1;
00339       src++;
00340       continue;
00341     }
00342     // look for end
00343     if ((*src == '\"') && (start == 1)) {
00344       *dst = 0; // terminate the string
00345       break;
00346     }
00347     if (start == 1) {
00348       *dst = *src;
00349       dst++;
00350     }
00351     src++;
00352   }
00353 }
00354 
00355 //******************************************************************************
00356 void RPC_call_test(void) {
00357   int doubleQuoteFound;
00358   char doubleQuoteStr[64];
00359   const char *request = "/Logging/AppendMissionCmd \"BMP280 InitStart 1\"";
00360 
00361   // scan through arguments, see if there is a double quote for a string
00362   // argument
00363   doubleQuoteFound = CheckForDoubleQuote(request);
00364   if (doubleQuoteFound) {
00365     ExtractDoubleQuoteStr(request, doubleQuoteStr);
00366   }
00367 }
00368 
00369 //******************************************************************************
00370 void RPC_call(char *request, char *reply) {
00371   const char slash[2] = "/";
00372   const char space[2] = " ";
00373   char *objectName;
00374   char *methodName;
00375   char doubleQuoteStr[64];
00376   char requestCpy[128];
00377   char *token;
00378   int argIndex;
00379   int resultIndex;
00380   int doubleQuoteFound;
00381   struct RPC_registeredProcedure *procedurePtr;
00382   int callResult;
00383 
00384   // clear out the reply
00385   reply[0] = 0;
00386   // copy the request for scanning and extraction later
00387   strcpy(requestCpy, request);
00388   // check for beginning forward slash
00389   if (request[0] != '/') {
00390     return;
00391   }
00392   // check for only a forward slash
00393   if (request[0] == '/' && request[1] == 0) {
00394     SendCommandList(reply);
00395     return;
00396   }
00397   strcat(request, " ");
00398   // get the object name
00399   token = strtok(request, slash);
00400   // token = GetToken(request, tokenBuffer, 1, '/');
00401   objectName = token;
00402   if (objectName == NULL)
00403     return; // must have an object name
00404   // get the method name
00405   token = strtok(NULL, space);
00406   methodName = token;
00407   if (methodName == NULL)
00408     return; // must have a method name
00409 
00410   // scan through arguments, see if there is a double quote for a string
00411   // argument
00412   doubleQuoteFound = CheckForDoubleQuote(requestCpy);
00413 
00414   if (doubleQuoteFound == 0) {
00415     // walk through arguments
00416     argIndex = 0;
00417     token = strtok(NULL, space);
00418     while (token != NULL) {
00419       // save this arg in array
00420       strcpy(args[argIndex++], token);
00421       // read next token arg if any
00422       token = strtok(NULL, space);
00423     }
00424     // terminate the end of the string array with an empty string
00425     strcpy(args[argIndex], "\0");
00426     strcpy(results[0], "\0");
00427   } else {
00428     // grab out the double quote string
00429     ExtractDoubleQuoteStr(requestCpy, doubleQuoteStr);
00430     argIndex = 0;
00431     // token = strtok(NULL, quote);
00432     strcpy(args[argIndex++], doubleQuoteStr);
00433   }
00434 
00435   //
00436   // alias the MAX30001 and MAX30003 names
00437   //
00438   if (strcmp(objectName, MAX30003_NAME) == 0) {
00439     strcpy(objectName, MAX30001_NAME);
00440   }
00441 
00442   callResult = 0;
00443   procedurePtr = RPC_lookup(objectName, methodName);
00444   if (procedurePtr != NULL) {
00445     // printf("RPC_call: %s processing\n",requestCpy);
00446     callResult = procedurePtr->func(args, results);
00447   } else {
00448     printf("RPC_call: %s not found\n", requestCpy);
00449     // printf("Unable to lookup %s %s", objectName, methodName);
00450   }
00451 
00452   // loop while (if) there are results to return
00453   resultIndex = 0;
00454   strcpy(reply, "\0");
00455   if (callResult != RPC_SKIP_CRLF) { 
00456     while (results[resultIndex][0] != '\0') {
00457       strcat(reply, results[resultIndex++]);
00458       strcat(reply, " ");
00459     }
00460     strcat(reply, "\r\n");
00461   }
00462 }
00463 
00464 //******************************************************************************
00465 void RPC_ProcessCmds(char *cmds) {
00466   char cmd[32 * 32];
00467   char *ptrCmds;
00468   char reply[512];
00469   ptrCmds = cmds;
00470 
00471   while (*ptrCmds != 0) {
00472     ptrCmds = ParseUntilCRLF(ptrCmds, cmd, sizeof(cmd));
00473     if (*cmd != 0) {
00474       RPC_call(cmd, reply);
00475     }
00476   }
00477 }