Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DataLoggingService.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 "mbed.h" 00034 #include "Logging.h" 00035 #include "Streaming.h" 00036 #include "RpcServer.h" 00037 #include "S25FS512.h" 00038 #include "PacketFifo.h" 00039 #include "DataLoggingService.h" 00040 #include "HspLed.h" 00041 #include "MAX30001_helper.h" 00042 #include "StringInOut.h" 00043 #include "StringHelper.h" 00044 #include "Peripherals.h" 00045 #include "Device_Logging.h" 00046 00047 /// BMP280 logging object reference 00048 extern Device_Logging *bmp280_Logging; 00049 /// MAX14720 instance 0 logging object reference 00050 extern Device_Logging *MAX30205_0_Logging; 00051 /// MAX14720 instance 1 logging object reference 00052 extern Device_Logging *MAX30205_1_Logging; 00053 00054 #define PING_PONG_BUFFER_SIZE 512 00055 #define HALF_OF_PING_PONG_BUFFER_SIZE PING_PONG_BUFFER_SIZE / 2 00056 #define MISSION_DEFINITION_SIZE 4096 00057 #define MISSION_FILE_NAME_LEN 32 00058 00059 eLoggingTrigger loggingTrigger; 00060 00061 /// file on SDCard where mission strings are stored 00062 char missionFileName[MISSION_FILE_NAME_LEN] = "/sd/missions.txt"; 00063 00064 /// data file on SDCard where mission strings are stored 00065 char dataFileName[MISSION_FILE_NAME_LEN] = "/sd/data.txt"; 00066 00067 /// buffer where mission strings are stored 00068 char loggingMissionCmds[MISSION_DEFINITION_SIZE]; 00069 /// This houses two 256 byte ram concatenated to act as a ping-pong 00070 uint8_t PingPong_SRAM[PING_PONG_BUFFER_SIZE]; 00071 uint32_t buttonTrigger = 0; 00072 00073 eLoggingOutput loggingOutput; 00074 // extern int bleStartCommand; 00075 bool volatile globalFlag; 00076 extern int highDataRate; 00077 static uint32_t currentPage; 00078 static uint32_t sramIndex; 00079 /// flag to indicate that sram buffer 0 is dirty and will need to be flushed 00080 static uint32_t sram_buffer_0_dirty; 00081 /// flag to indicate that sram buffer 1 is dirty and will need to be flushed 00082 static uint32_t sram_buffer_1_dirty; 00083 /// usb byte buffer for sending out a bulk transfer 00084 static uint8_t usb_block[64]; 00085 /// running index used to accumulate bytes to send as a block via bulk transfer 00086 static uint16_t usb_block_index = 0; 00087 00088 typedef enum { 00089 eStartEvent_NULL, 00090 eStartEvent_BLE, 00091 eStartEvent_BUTTON, 00092 eStartEvent_RPC_TO_USB, 00093 eStartEvent_RPC_TO_FLASH 00094 } eStartEvent; 00095 static eStartEvent startEvent; 00096 00097 /** 00098 * @brief Sets a flag to start USB logging (streaming) 00099 */ 00100 void LoggingService_StartLoggingUsb(void) { 00101 loggingTrigger = eTriggerLog_RPC_USB; 00102 } 00103 00104 /** 00105 * @brief Sets a flag to start flash logging 00106 */ 00107 void LoggingService_StartLoggingFlash(void) { 00108 loggingTrigger = eTriggerLog_RPC_FLASH; 00109 } 00110 00111 /** 00112 * @brief Checks the various logging start condition 00113 * @return 1 if a start condition is true, 0 if there is no start condition 00114 */ 00115 static bool _LoggingService_CheckStartCondition(void) { 00116 bool buttonPressed; 00117 buttonPressed = Peripherals::pushButton()->GetButtonFallState(); 00118 00119 // default not logging USB or flash 00120 loggingOutput = eLogToNothing; 00121 startEvent = eStartEvent_NULL; 00122 if (buttonPressed) { 00123 Peripherals::pushButton()->clearButtonFallState(); 00124 // a falling state has been detected... wait for a fraction of a second and 00125 // re-read the pin 00126 // only start datalogging if the pin was released within this wait time 00127 wait(0.75f); 00128 int buttonRead = Peripherals::pushButton()->Read(); 00129 // if after a period of time the button is still pressed then get out 00130 if (buttonRead == 0) 00131 return 0; 00132 buttonTrigger = 0; 00133 00134 loggingTrigger = eTriggerLog_BUTTON; 00135 loggingOutput = eLogToFlash; 00136 startEvent = eStartEvent_BUTTON; 00137 return true; 00138 } 00139 if (loggingTrigger == eTriggerLog_RPC_FLASH) { 00140 loggingOutput = eLogToFlash; 00141 startEvent = eStartEvent_RPC_TO_FLASH; 00142 return true; 00143 } 00144 /*if (Peripherals::hspBLE()->getStartDataLogging()) { 00145 loggingTrigger = eTriggerLog_BLE; 00146 loggingOutput = eLogToFlash; 00147 startEvent = eStartEvent_BLE; 00148 return true; 00149 }*/ 00150 // check if start is from RPC call for USB streaming 00151 if (loggingTrigger == eTriggerLog_RPC_USB) { 00152 loggingOutput = eLogtoUsb; 00153 startEvent = eStartEvent_RPC_TO_USB; 00154 return true; 00155 } 00156 return false; 00157 } 00158 00159 /** 00160 * @brief Read the mission string from flash into a buffer 00161 * @return false if a mission was not defined, true if mission was read and 00162 * buffered 00163 */ 00164 static bool _LoggingService_ReadMissionFromFlash(void) { 00165 // get mission from flash 00166 Logging_ReadMissionFromFlash((uint8_t *)loggingMissionCmds); 00167 if (Logging_IsMissionDefined((uint8_t *)loggingMissionCmds) == 0) { 00168 return false; 00169 } 00170 printf(loggingMissionCmds); 00171 fflush(stdout); 00172 RPC_ProcessCmds(loggingMissionCmds); 00173 return true; 00174 } 00175 00176 /** 00177 * @brief Read the mission string from SDCARD into a buffer 00178 * @return false if a mission was not defined, true if mission was read and 00179 * buffered 00180 */ 00181 static bool _LoggingService_ReadMissionFromSDCard(void) { 00182 // get mission from flash 00183 Logging_ReadMissionFromSDCard((uint8_t *)loggingMissionCmds); 00184 if (Logging_IsMissionDefined((uint8_t *)loggingMissionCmds) == 0) { 00185 return false; 00186 } 00187 printf(loggingMissionCmds); 00188 fflush(stdout); 00189 RPC_ProcessCmds(loggingMissionCmds); 00190 return true; 00191 } 00192 00193 /** 00194 * @brief Process a RPC command that is pointed to. 00195 * @param cmd RPC string to process 00196 */ 00197 void ProcessCmd(char *cmd) { 00198 char cmd_[256]; 00199 char reply[512]; 00200 strcpy(cmd_, cmd); 00201 RPC_call(cmd_, reply); 00202 } 00203 00204 /** 00205 * @brief Buffer sensor fifo data in ram buffers, when a ram buffer is full (a 00206 * flash page worth of data is accumulated) then flash that buffer. 00207 * A buffer ping pong method is used so that one buffer can be flashing as 00208 * the other buffer fills with sensor fifo data. 00209 * @param fifoData Sensor data taken from the fifo to be stored into flash 00210 */ 00211 static void _LoggingServer_OutputToFlash(uint32_t fifoData) { 00212 uint32_t index; 00213 char str[128]; 00214 uint8_t *ptr; 00215 // 00216 // Log To Flash 00217 // 00218 // i.e. there is data, read one 32-bit size data at a time. 00219 // put the fifo data into the ping-pong SRAM 00220 PingPong_SRAM[sramIndex++] = fifoData & 0xFF; // LSByte goes into index N 00221 PingPong_SRAM[sramIndex++] = (fifoData >> 8) & 0xFF; 00222 PingPong_SRAM[sramIndex++] = (fifoData >> 16) & 0xFF; 00223 PingPong_SRAM[sramIndex++] = (fifoData >> 24) & 0xFF; // MSByte goes into index N+3 00224 00225 // flag this buffer as dirty 00226 if (sramIndex <= 256) 00227 sram_buffer_0_dirty = 1; 00228 else 00229 sram_buffer_1_dirty = 1; 00230 00231 if (sramIndex == 256 || 00232 sramIndex == 512) // Either Ping SRAM or Pong SRAM location is full 00233 { // therefore write to Flash 00234 00235 index = sramIndex - 256; 00236 ptr = &PingPong_SRAM[index]; 00237 sprintf(str, "currentPage=%d", currentPage); 00238 Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0); 00239 00240 // this page is no longer dirty 00241 if (index == 0) 00242 sram_buffer_0_dirty = 0; 00243 if (index == 256) 00244 sram_buffer_1_dirty = 0; 00245 00246 currentPage++; 00247 } 00248 sramIndex = sramIndex % 512; // Wrap around the index 00249 } 00250 00251 /** 00252 * @brief Buffer sensor fifo data in ram buffers, when a ram buffer is full (a 00253 * flash page worth of data is accumulated) then flash that buffer. 00254 * A buffer ping pong method is used so that one buffer can be flashing as 00255 * the other buffer fills with sensor fifo data. 00256 * @param fifoData Sensor data taken from the fifo to be stored into flash 00257 */ 00258 static void _LoggingServer_OutputToSDCard(FILE* fp, uint32_t fifoData) { 00259 if (fp != NULL){ 00260 fwrite(&fifoData,sizeof(fifoData),1,fp); 00261 } 00262 } 00263 00264 /** 00265 * @brief If flash ram buffers are flagged as dirty, flush to flash 00266 */ 00267 static void _LoggingServer_WriteDirtySramBufferToFlash(void) { 00268 uint8_t *ptr = PingPong_SRAM; 00269 if (sram_buffer_0_dirty == 0 && sram_buffer_1_dirty == 0) 00270 return; 00271 if (sram_buffer_0_dirty == 1) { 00272 ptr += 0; 00273 } 00274 if (sram_buffer_1_dirty == 1) { 00275 ptr += 256; 00276 } 00277 printf("_LoggingServer_WriteDirtySramBufferToFlash:%d,%d\n", 00278 sram_buffer_0_dirty, sram_buffer_1_dirty); 00279 fflush(stdout); 00280 // s25fs512_WritePage_Helper(currentPage, ptr, 0); 00281 Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0); 00282 } 00283 00284 /** 00285 * @brief Initialize the USB block running index 00286 * @param fifoData Sensor data taken from the fifo to be sent out USB 00287 */ 00288 static void _LoggingServer_OutputToCdcAcm(uint32_t fifoData) { 00289 uint8_t *ptr; 00290 uint8_t str[16]; 00291 sprintf((char *)str, "%X ", fifoData); 00292 ptr = str; 00293 usb_block_index = 0; 00294 while (*ptr != 0) { 00295 usb_block[usb_block_index] = *ptr; 00296 ptr++; 00297 usb_block_index++; 00298 } 00299 Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index); 00300 } 00301 00302 /** 00303 * @brief Initialize the USB block running index 00304 */ 00305 static void _LoggingServer_OutputToCdcAcm_Start(void) { usb_block_index = 0; } 00306 00307 /** 00308 * @brief Buffer up fifoData from sensors, do a USB block transfer if buffer is 00309 * full 00310 * @param fifoData Sensor data taken from the fifo to be send out USB within a 00311 * bulk block transfer 00312 * @return Return the success status of the writeblock operation 00313 */ 00314 static bool _LoggingServer_OutputToCdcAcm_Block(uint32_t fifoData) { 00315 uint8_t str[64]; 00316 uint8_t *ptr; 00317 bool result; 00318 // 00319 // Log to CDCACM 00320 // 00321 result = true; 00322 sprintf((char *)str, "%X ", fifoData); 00323 ptr = str; 00324 while (*ptr != 0) { 00325 usb_block[usb_block_index] = *ptr; 00326 ptr++; 00327 usb_block_index++; 00328 if (usb_block_index >= 64) { 00329 result = Peripherals::usbSerial()->writeBlock(usb_block, 64); 00330 usb_block_index = 0; 00331 } 00332 } 00333 return result; 00334 } 00335 00336 /** 00337 * @brief Output a full USB block via bulk transfer 00338 */ 00339 static void _LoggingServer_OutputToCdcAcm_End(void) { 00340 if (usb_block_index == 0) 00341 return; 00342 Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index - 1); 00343 } 00344 00345 /** 00346 * @brief Blink LED pattern that indicates that the flash end boundary has been 00347 * reached 00348 */ 00349 static void BlinkEndOfDatalogging(void) { 00350 // blink to signal end of logging 00351 Peripherals::hspLed()->pattern(0x55555555, 20); 00352 wait(2); 00353 } 00354 00355 /** 00356 * @brief Reads the first data page of flash, if all FF's then the page is empty 00357 * @return 1 if the flash is empty as indicated by the first data page of the 00358 * flash, 0 if not 00359 */ 00360 int isFlashEmpty(void) { 00361 int i; 00362 uint8_t data[256]; 00363 int firstDataPage = Logging_GetLoggingStartPage(); 00364 Peripherals::s25FS512()->readPages_Helper(firstDataPage, firstDataPage, data, 0); 00365 for (i = 0; i < 256; i++) { 00366 if (data[i] != 0xFF) 00367 return 0; 00368 } 00369 return 1; 00370 } 00371 00372 /** 00373 * @brief Reads the first data from SDCard, if all FF's then the page is empty 00374 * @return 1 if the flash is empty as indicated by the first data page of the 00375 * flash, 0 if not 00376 */ 00377 int isSDCardWithoutDataLog(void) { 00378 FILE *fp = NULL; 00379 fp = fopen(dataFileName, "rb"); 00380 if (fp != NULL) { 00381 uint8_t count = 0; 00382 do 00383 { 00384 count ++; 00385 char c = (char)fgetc(fp); 00386 if (count > 2) 00387 { 00388 fclose(fp); 00389 return 0; 00390 } 00391 } while(!feof(fp)); 00392 fclose(fp); 00393 } 00394 return 1; 00395 00396 } 00397 00398 /** 00399 * @brief Blink LED pattern that indicates that the flash is not empty and a new 00400 * flash logging session can not occur 00401 */ 00402 void BlinkFlashNotEmpty(void) { 00403 Peripherals::hspLed()->pattern(0x55555555, 20); 00404 wait(1); 00405 } 00406 00407 void ExecuteDefaultMission(void) { 00408 ProcessCmd("/MAX30001/CAL_InitStart 01 01 01 03 7FF 00"); 00409 ProcessCmd("/MAX30001/ECG_InitStart 01 01 01 00 02 03 1F 0 00 00 01"); 00410 ProcessCmd("/MAX30001/RtoR_InitStart 01 03 0F 00 03 01 00 00 01"); 00411 ProcessCmd("/MAX30001/Rbias_FMSTR_Init 01 02 01 01 00"); 00412 } 00413 00414 void LoggingService_Init(void) { loggingTrigger = eTriggerLog_NULL; } 00415 00416 /** 00417 * @brief This routine checks to see if a USB or flash logging action needs to be taken 00418 * The routine checks for a start condition via button press, USB command, or BLE command 00419 * Once one of these start conditions is present, the logging begins until stopped or memory is full 00420 * @return 1 if successful, 0 if error or logging was aborted and no logging occurred 00421 */ 00422 uint8_t LoggingService_ServiceRoutine(void) { 00423 uint32_t fifoData; 00424 uint32_t endPage; 00425 FILE *fp; 00426 USBSerial *usbSerial = Peripherals::usbSerial(); 00427 // BMP280 *bmp280 = Peripherals::bmp280(); 00428 bool buttonPressed; 00429 bool endSDLogging = false; 00430 int packetBurstCount = 0; 00431 HspLed *hspLed = Peripherals::hspLed(); 00432 00433 sramIndex = 0; 00434 // only start logging if conditions exist 00435 00436 if (_LoggingService_CheckStartCondition() == false) return 0; 00437 printf("Begin Logging..."); 00438 if (startEvent == eStartEvent_NULL) printf("eStartEvent_NULL..."); 00439 if (startEvent == eStartEvent_BLE) printf("eStartEvent_BLE..."); 00440 if (startEvent == eStartEvent_BUTTON) printf("eStartEvent_BUTTON..."); 00441 if (startEvent == eStartEvent_RPC_TO_USB) printf("eStartEvent_RPC_TO_USB..."); 00442 if (startEvent == eStartEvent_RPC_TO_FLASH) printf("eStartEvent_RPC_TO_FLASH..."); 00443 fflush(stdout); 00444 00445 // start logging stuttered blink pattern 00446 hspLed->pattern(0xA0F3813, 20); 00447 00448 if (startEvent == eStartEvent_RPC_TO_FLASH || 00449 startEvent == eStartEvent_BUTTON) { 00450 // check to see if datalog already in flash... abort and force user to erase 00451 // flash if needed 00452 if (loggingOutput == eLogToFlash) { 00453 if (isSDCardWithoutDataLog() == 0) { 00454 Logging_SetStart(false); 00455 // bleStartCommand = 0x00; 00456 BlinkFlashNotEmpty(); 00457 hspLed->blink(1000); 00458 printf("Abort Logging, flash log exists. "); 00459 fflush(stdout); 00460 return 0; 00461 } 00462 } 00463 } 00464 00465 if (startEvent == eStartEvent_BLE) { 00466 // check for mission in flash 00467 if (_LoggingService_ReadMissionFromSDCard() == false) { 00468 // if there is no mission in flash then do a default mission for the sake 00469 // of ble Android app working "out-of-the-box" and stream RtoR and Accel 00470 printf("No Mission in Flash...ExecuteDefaultMission..."); 00471 fflush(stdout); 00472 ExecuteDefaultMission(); 00473 // do not log this data 00474 loggingOutput = eLogToNothing; 00475 } else { 00476 // there is a mission in flash check if there is already logged data 00477 if (isSDCardWithoutDataLog() == 0) { 00478 // just do default mission 00479 printf("Logged Data Detected...ExecuteDefaultMission..."); 00480 fflush(stdout); 00481 ExecuteDefaultMission(); 00482 // do not log this data 00483 loggingOutput = eLogToNothing; 00484 } else { 00485 // flag that we are logging to flash 00486 loggingOutput = eLogToFlash; 00487 } 00488 } 00489 } 00490 00491 // if we are logging to flash then read mission in flash 00492 if (loggingOutput == eLogToFlash) { 00493 if (_LoggingService_ReadMissionFromSDCard() == 00494 false) { // if there is no mission in flash then get out 00495 Logging_SetStart(false); 00496 Peripherals::hspLed()->pattern(0xC3C3C3C3, 20); 00497 wait(2); 00498 printf("Abort Logging, Mission does not exist. "); 00499 fflush(stdout); 00500 return 0; 00501 } 00502 currentPage = Logging_GetLoggingStartPage(); 00503 endPage = Logging_GetLoggingEndPage(); 00504 } 00505 00506 MAX30001_Helper_SetupInterrupts(); 00507 if (MAX30001_AnyStreamingSet() == 1) { 00508 MAX30001_Helper_StartSync(); 00509 } 00510 00511 SetDataLoggingStream(TRUE); 00512 00513 while (usbSerial->readable()) { 00514 usbSerial->_getc(); 00515 } 00516 fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo 00517 fifo_clear(GetStreamOutFifo()); 00518 00519 sram_buffer_0_dirty = 0; 00520 sram_buffer_1_dirty = 0; 00521 00522 00523 if (loggingOutput == eLogToNothing) printf("eLogToNothing..."); fflush(stdout); 00524 if (loggingOutput == eLogToFlash) printf("eLogToFlash..."); fflush(stdout); 00525 if (loggingOutput == eLogtoUsb) printf("eLogtoUsb..."); fflush(stdout); 00526 printf("highDataRate=%d...",highDataRate); fflush(stdout); 00527 00528 00529 Peripherals::timestampTimer()->reset(); 00530 Peripherals::timestampTimer()->start(); 00531 00532 _LoggingServer_OutputToCdcAcm_Start(); 00533 while (1) { 00534 if (loggingOutput == eLogToFlash) { 00535 // check if we are at the end of flash 00536 if (currentPage >= endPage) { 00537 BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging 00538 break; 00539 } 00540 } 00541 00542 if (startEvent == eStartEvent_BUTTON) { 00543 buttonPressed = Peripherals::pushButton()->GetButtonFallState(); 00544 if (buttonPressed) { 00545 printf("button pressed, flush the FIFO buffer to SDCard before ending logging\r\n"); 00546 Peripherals::pushButton()->clearButtonFallState(); 00547 // if there is a dirty sram buffer... flush it to flash 00548 _LoggingServer_WriteDirtySramBufferToFlash(); 00549 endSDLogging = true; 00550 } 00551 } 00552 00553 if (startEvent == eStartEvent_RPC_TO_USB || 00554 startEvent == eStartEvent_RPC_TO_FLASH) { 00555 if (usbSerial->available()) { 00556 if (loggingOutput == eLogToFlash) { 00557 _LoggingServer_WriteDirtySramBufferToFlash(); 00558 } 00559 wait(0.2f); 00560 while (usbSerial->available()) { 00561 usbSerial->_getc(); 00562 } 00563 fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo 00564 fifo_clear(GetStreamOutFifo()); 00565 break; 00566 } 00567 } 00568 if (fp == NULL && loggingOutput == eLogToFlash) 00569 fp = fopen(dataFileName, "ab+"); 00570 // check to see if data is available 00571 packetBurstCount = 0; 00572 while (PacketFifo_Empty() == 0) { 00573 printf("*"); 00574 if (packetBurstCount >= 100 && endSDLogging == false) 00575 break; 00576 fifoData = PacketFifo_GetUint32(); 00577 if (loggingOutput == eLogToFlash) { 00578 //_LoggingServer_OutputToFlash(fifoData); 00579 _LoggingServer_OutputToSDCard(fp, fifoData); 00580 } 00581 if (loggingOutput == eLogtoUsb) { 00582 if (highDataRate == 0) 00583 _LoggingServer_OutputToCdcAcm(fifoData); 00584 else 00585 _LoggingServer_OutputToCdcAcm_Block(fifoData); 00586 } 00587 packetBurstCount++; 00588 } 00589 00590 if (endSDLogging) { 00591 endSDLogging = false; 00592 if (fp != NULL) fclose(fp); 00593 fp == NULL; 00594 BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging 00595 break; 00596 } 00597 00598 } 00599 _LoggingServer_OutputToCdcAcm_End(); 00600 printf("End Logging.\n"); 00601 fflush(stdout); 00602 00603 MAX30001_Helper_Stop(); // if any MAX30001 streams have been started, stop 00604 // them 00605 SetDataLoggingStream(FALSE); 00606 Peripherals::timestampTimer()->stop(); 00607 hspLed->blink(1000); 00608 // default to non-usb packet speed optimizing 00609 highDataRate = 0; 00610 loggingTrigger = eTriggerLog_NULL; 00611 return 1; 00612 } 00613
Generated on Wed Jul 13 2022 08:45:46 by
1.7.2