Maxim Integrated / Mbed OS HSP_RPC_GUI

Dependencies:   USBDevice

Fork of HSP_Release by Jerry Bradshaw

This is an example program for the MAX32620HSP (MAXREFDES100 Health Sensor Platform). It demonstrates all the features of the platform and works with a companion graphical user interface (GUI) to help evaluate/configure/monitor the board. Go to the MAXREFDES100 product page and click on "design resources" to download the companion software. The GUI connects to the board through an RPC interface on a virtual serial port over the USB interface.

The RPC interface provides access to all the features of the board and is available to interface with other development environments such Matlab. This firmware provides realtime data streaming through the RPC interface over USB, and also provides the ability to log the data to flash for untethered battery operation. The data logging settings are configured through the GUI, and the GUI also provides the interface to download logged data.

Details on the RPC interface can be found here: HSP RPC Interface Documentation

Windows

With this program loaded, the MAX32620HSP will appear on your computer as a serial port. On Mac and Linux, this will happen by default. For Windows, you need to install a driver: HSP serial port windows driver

For more details about this platform and how to use it, see the MAXREFDES100 product page.

Committer:
jbradshaw
Date:
Tue Oct 25 15:22:11 2016 +0000
Revision:
0:e4a10ed6eb92
Child:
1:9490836294ea
tewt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jbradshaw 0:e4a10ed6eb92 1 /*******************************************************************************
jbradshaw 0:e4a10ed6eb92 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
jbradshaw 0:e4a10ed6eb92 3 *
jbradshaw 0:e4a10ed6eb92 4 * Permission is hereby granted, free of charge, to any person obtaining a
jbradshaw 0:e4a10ed6eb92 5 * copy of this software and associated documentation files (the "Software"),
jbradshaw 0:e4a10ed6eb92 6 * to deal in the Software without restriction, including without limitation
jbradshaw 0:e4a10ed6eb92 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
jbradshaw 0:e4a10ed6eb92 8 * and/or sell copies of the Software, and to permit persons to whom the
jbradshaw 0:e4a10ed6eb92 9 * Software is furnished to do so, subject to the following conditions:
jbradshaw 0:e4a10ed6eb92 10 *
jbradshaw 0:e4a10ed6eb92 11 * The above copyright notice and this permission notice shall be included
jbradshaw 0:e4a10ed6eb92 12 * in all copies or substantial portions of the Software.
jbradshaw 0:e4a10ed6eb92 13 *
jbradshaw 0:e4a10ed6eb92 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
jbradshaw 0:e4a10ed6eb92 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
jbradshaw 0:e4a10ed6eb92 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
jbradshaw 0:e4a10ed6eb92 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
jbradshaw 0:e4a10ed6eb92 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
jbradshaw 0:e4a10ed6eb92 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
jbradshaw 0:e4a10ed6eb92 20 * OTHER DEALINGS IN THE SOFTWARE.
jbradshaw 0:e4a10ed6eb92 21 *
jbradshaw 0:e4a10ed6eb92 22 * Except as contained in this notice, the name of Maxim Integrated
jbradshaw 0:e4a10ed6eb92 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
jbradshaw 0:e4a10ed6eb92 24 * Products, Inc. Branding Policy.
jbradshaw 0:e4a10ed6eb92 25 *
jbradshaw 0:e4a10ed6eb92 26 * The mere transfer of this software does not imply any licenses
jbradshaw 0:e4a10ed6eb92 27 * of trade secrets, proprietary technology, copyrights, patents,
jbradshaw 0:e4a10ed6eb92 28 * trademarks, maskwork rights, or any other form of intellectual
jbradshaw 0:e4a10ed6eb92 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
jbradshaw 0:e4a10ed6eb92 30 * ownership rights.
jbradshaw 0:e4a10ed6eb92 31 *******************************************************************************
jbradshaw 0:e4a10ed6eb92 32 */
jbradshaw 0:e4a10ed6eb92 33 #include "mbed.h"
jbradshaw 0:e4a10ed6eb92 34 #include "Logging.h"
jbradshaw 0:e4a10ed6eb92 35 #include "Streaming.h"
jbradshaw 0:e4a10ed6eb92 36 #include "RpcServer.h"
jbradshaw 0:e4a10ed6eb92 37 #include "S25FS512.h"
jbradshaw 0:e4a10ed6eb92 38 #include "BMP280.h"
jbradshaw 0:e4a10ed6eb92 39 #include "PacketFifo.h"
jbradshaw 0:e4a10ed6eb92 40 #include "DataLoggingService.h"
jbradshaw 0:e4a10ed6eb92 41 #include "ServiceNonInterrupt.h"
jbradshaw 0:e4a10ed6eb92 42 #include "HspLed.h"
jbradshaw 0:e4a10ed6eb92 43 #include "MAX30001_helper.h"
jbradshaw 0:e4a10ed6eb92 44 #include "MAX30101_helper.h"
jbradshaw 0:e4a10ed6eb92 45 #include "StringInOut.h"
jbradshaw 0:e4a10ed6eb92 46 #include "StringHelper.h"
jbradshaw 0:e4a10ed6eb92 47 #include "Peripherals.h"
jbradshaw 0:e4a10ed6eb92 48 #include "Device_Logging.h"
jbradshaw 0:e4a10ed6eb92 49
jbradshaw 0:e4a10ed6eb92 50 /// BMP280 logging object reference
jbradshaw 0:e4a10ed6eb92 51 extern Device_Logging *bmp280_Logging;
jbradshaw 0:e4a10ed6eb92 52 /// MAX14720 instance 0 logging object reference
jbradshaw 0:e4a10ed6eb92 53 extern Device_Logging *MAX30205_0_Logging;
jbradshaw 0:e4a10ed6eb92 54 /// MAX14720 instance 1 logging object reference
jbradshaw 0:e4a10ed6eb92 55 extern Device_Logging *MAX30205_1_Logging;
jbradshaw 0:e4a10ed6eb92 56
jbradshaw 0:e4a10ed6eb92 57 #define PING_PONG_BUFFER_SIZE 512
jbradshaw 0:e4a10ed6eb92 58 #define HALF_OF_PING_PONG_BUFFER_SIZE PING_PONG_BUFFER_SIZE / 2
jbradshaw 0:e4a10ed6eb92 59 #define MISSION_DEFINITION_SIZE 4096
jbradshaw 0:e4a10ed6eb92 60
jbradshaw 0:e4a10ed6eb92 61 eLoggingTrigger loggingTrigger;
jbradshaw 0:e4a10ed6eb92 62
jbradshaw 0:e4a10ed6eb92 63 /// buffer where mission strings are stored
jbradshaw 0:e4a10ed6eb92 64 char loggingMissionCmds[MISSION_DEFINITION_SIZE];
jbradshaw 0:e4a10ed6eb92 65 /// This houses two 256 byte ram concatenated to act as a ping-pong
jbradshaw 0:e4a10ed6eb92 66 uint8_t PingPong_SRAM[PING_PONG_BUFFER_SIZE];
jbradshaw 0:e4a10ed6eb92 67 uint32_t buttonTrigger = 0;
jbradshaw 0:e4a10ed6eb92 68
jbradshaw 0:e4a10ed6eb92 69 eLoggingOutput loggingOutput;
jbradshaw 0:e4a10ed6eb92 70 // extern int bleStartCommand;
jbradshaw 0:e4a10ed6eb92 71 bool volatile globalFlag;
jbradshaw 0:e4a10ed6eb92 72 extern int highDataRate;
jbradshaw 0:e4a10ed6eb92 73 static uint32_t currentPage;
jbradshaw 0:e4a10ed6eb92 74 static uint32_t sramIndex;
jbradshaw 0:e4a10ed6eb92 75 /// flag to indicate that sram buffer 0 is dirty and will need to be flushed
jbradshaw 0:e4a10ed6eb92 76 static uint32_t sram_buffer_0_dirty;
jbradshaw 0:e4a10ed6eb92 77 /// flag to indicate that sram buffer 1 is dirty and will need to be flushed
jbradshaw 0:e4a10ed6eb92 78 static uint32_t sram_buffer_1_dirty;
jbradshaw 0:e4a10ed6eb92 79 /// usb byte buffer for sending out a bulk transfer
jbradshaw 0:e4a10ed6eb92 80 static uint8_t usb_block[64];
jbradshaw 0:e4a10ed6eb92 81 /// running index used to accumulate bytes to send as a block via bulk transfer
jbradshaw 0:e4a10ed6eb92 82 static uint16_t usb_block_index = 0;
jbradshaw 0:e4a10ed6eb92 83
jbradshaw 0:e4a10ed6eb92 84 typedef enum {
jbradshaw 0:e4a10ed6eb92 85 eStartEvent_NULL,
jbradshaw 0:e4a10ed6eb92 86 eStartEvent_BLE,
jbradshaw 0:e4a10ed6eb92 87 eStartEvent_BUTTON,
jbradshaw 0:e4a10ed6eb92 88 eStartEvent_RPC_TO_USB,
jbradshaw 0:e4a10ed6eb92 89 eStartEvent_RPC_TO_FLASH
jbradshaw 0:e4a10ed6eb92 90 } eStartEvent;
jbradshaw 0:e4a10ed6eb92 91 static eStartEvent startEvent;
jbradshaw 0:e4a10ed6eb92 92
jbradshaw 0:e4a10ed6eb92 93 /**
jbradshaw 0:e4a10ed6eb92 94 * @brief Sets a flag to start USB logging (streaming)
jbradshaw 0:e4a10ed6eb92 95 */
jbradshaw 0:e4a10ed6eb92 96 void LoggingService_StartLoggingUsb(void) {
jbradshaw 0:e4a10ed6eb92 97 loggingTrigger = eTriggerLog_RPC_USB;
jbradshaw 0:e4a10ed6eb92 98 }
jbradshaw 0:e4a10ed6eb92 99
jbradshaw 0:e4a10ed6eb92 100 /**
jbradshaw 0:e4a10ed6eb92 101 * @brief Sets a flag to start flash logging
jbradshaw 0:e4a10ed6eb92 102 */
jbradshaw 0:e4a10ed6eb92 103 void LoggingService_StartLoggingFlash(void) {
jbradshaw 0:e4a10ed6eb92 104 loggingTrigger = eTriggerLog_RPC_FLASH;
jbradshaw 0:e4a10ed6eb92 105 }
jbradshaw 0:e4a10ed6eb92 106
jbradshaw 0:e4a10ed6eb92 107 /**
jbradshaw 0:e4a10ed6eb92 108 * @brief Checks the various logging start condition
jbradshaw 0:e4a10ed6eb92 109 * @return 1 if a start condition is true, 0 if there is no start condition
jbradshaw 0:e4a10ed6eb92 110 */
jbradshaw 0:e4a10ed6eb92 111 static bool _LoggingService_CheckStartCondition(void) {
jbradshaw 0:e4a10ed6eb92 112 bool buttonPressed;
jbradshaw 0:e4a10ed6eb92 113 buttonPressed = Peripherals::pushButton()->GetButtonFallState();
jbradshaw 0:e4a10ed6eb92 114
jbradshaw 0:e4a10ed6eb92 115 // default not logging USB or flash
jbradshaw 0:e4a10ed6eb92 116 loggingOutput = eLogToNothing;
jbradshaw 0:e4a10ed6eb92 117 startEvent = eStartEvent_NULL;
jbradshaw 0:e4a10ed6eb92 118 if (buttonPressed) {
jbradshaw 0:e4a10ed6eb92 119 Peripherals::pushButton()->clearButtonFallState();
jbradshaw 0:e4a10ed6eb92 120 // a falling state has been detected... wait for a fraction of a second and
jbradshaw 0:e4a10ed6eb92 121 // re-read the pin
jbradshaw 0:e4a10ed6eb92 122 // only start datalogging if the pin was released within this wait time
jbradshaw 0:e4a10ed6eb92 123 wait(0.75f);
jbradshaw 0:e4a10ed6eb92 124 int buttonRead = Peripherals::pushButton()->Read();
jbradshaw 0:e4a10ed6eb92 125 // if after a period of time the button is still pressed then get out
jbradshaw 0:e4a10ed6eb92 126 if (buttonRead == 0)
jbradshaw 0:e4a10ed6eb92 127 return 0;
jbradshaw 0:e4a10ed6eb92 128 buttonTrigger = 0;
jbradshaw 0:e4a10ed6eb92 129
jbradshaw 0:e4a10ed6eb92 130 loggingTrigger = eTriggerLog_BUTTON;
jbradshaw 0:e4a10ed6eb92 131 loggingOutput = eLogToFlash;
jbradshaw 0:e4a10ed6eb92 132 startEvent = eStartEvent_BUTTON;
jbradshaw 0:e4a10ed6eb92 133 return true;
jbradshaw 0:e4a10ed6eb92 134 }
jbradshaw 0:e4a10ed6eb92 135 if (loggingTrigger == eTriggerLog_RPC_FLASH) {
jbradshaw 0:e4a10ed6eb92 136 loggingOutput = eLogToFlash;
jbradshaw 0:e4a10ed6eb92 137 startEvent = eStartEvent_RPC_TO_FLASH;
jbradshaw 0:e4a10ed6eb92 138 return true;
jbradshaw 0:e4a10ed6eb92 139 }
jbradshaw 0:e4a10ed6eb92 140 if (Peripherals::hspBLE()->getStartDataLogging()) {
jbradshaw 0:e4a10ed6eb92 141 loggingTrigger = eTriggerLog_BLE;
jbradshaw 0:e4a10ed6eb92 142 loggingOutput = eLogToFlash;
jbradshaw 0:e4a10ed6eb92 143 startEvent = eStartEvent_BLE;
jbradshaw 0:e4a10ed6eb92 144 return true;
jbradshaw 0:e4a10ed6eb92 145 }
jbradshaw 0:e4a10ed6eb92 146 // check if start is from RPC call for USB streaming
jbradshaw 0:e4a10ed6eb92 147 if (loggingTrigger == eTriggerLog_RPC_USB) {
jbradshaw 0:e4a10ed6eb92 148 loggingOutput = eLogtoUsb;
jbradshaw 0:e4a10ed6eb92 149 startEvent = eStartEvent_RPC_TO_USB;
jbradshaw 0:e4a10ed6eb92 150 return true;
jbradshaw 0:e4a10ed6eb92 151 }
jbradshaw 0:e4a10ed6eb92 152 return false;
jbradshaw 0:e4a10ed6eb92 153 }
jbradshaw 0:e4a10ed6eb92 154
jbradshaw 0:e4a10ed6eb92 155 /**
jbradshaw 0:e4a10ed6eb92 156 * @brief Read the mission string from flash into a buffer
jbradshaw 0:e4a10ed6eb92 157 * @return false if a mission was not defined, true if mission was read and
jbradshaw 0:e4a10ed6eb92 158 * buffered
jbradshaw 0:e4a10ed6eb92 159 */
jbradshaw 0:e4a10ed6eb92 160 static bool _LoggingService_ReadMissionFromFlash(void) {
jbradshaw 0:e4a10ed6eb92 161 // get mission from flash
jbradshaw 0:e4a10ed6eb92 162 Logging_ReadMissionFromFlash((uint8_t *)loggingMissionCmds);
jbradshaw 0:e4a10ed6eb92 163 if (Logging_IsMissionDefined((uint8_t *)loggingMissionCmds) == 0) {
jbradshaw 0:e4a10ed6eb92 164 return false;
jbradshaw 0:e4a10ed6eb92 165 }
jbradshaw 0:e4a10ed6eb92 166 printf(loggingMissionCmds);
jbradshaw 0:e4a10ed6eb92 167 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 168 RPC_ProcessCmds(loggingMissionCmds);
jbradshaw 0:e4a10ed6eb92 169 return true;
jbradshaw 0:e4a10ed6eb92 170 }
jbradshaw 0:e4a10ed6eb92 171
jbradshaw 0:e4a10ed6eb92 172 /**
jbradshaw 0:e4a10ed6eb92 173 * @brief Process a RPC command that is pointed to.
jbradshaw 0:e4a10ed6eb92 174 * @param cmd RPC string to process
jbradshaw 0:e4a10ed6eb92 175 */
jbradshaw 0:e4a10ed6eb92 176 void ProcessCmd(char *cmd) {
jbradshaw 0:e4a10ed6eb92 177 char cmd_[256];
jbradshaw 0:e4a10ed6eb92 178 char reply[512];
jbradshaw 0:e4a10ed6eb92 179 strcpy(cmd_, cmd);
jbradshaw 0:e4a10ed6eb92 180 RPC_call(cmd_, reply);
jbradshaw 0:e4a10ed6eb92 181 }
jbradshaw 0:e4a10ed6eb92 182
jbradshaw 0:e4a10ed6eb92 183 /**
jbradshaw 0:e4a10ed6eb92 184 * @brief Buffer sensor fifo data in ram buffers, when a ram buffer is full (a
jbradshaw 0:e4a10ed6eb92 185 * flash page worth of data is accumulated) then flash that buffer.
jbradshaw 0:e4a10ed6eb92 186 * A buffer ping pong method is used so that one buffer can be flashing as
jbradshaw 0:e4a10ed6eb92 187 * the other buffer fills with sensor fifo data.
jbradshaw 0:e4a10ed6eb92 188 * @param fifoData Sensor data taken from the fifo to be stored into flash
jbradshaw 0:e4a10ed6eb92 189 */
jbradshaw 0:e4a10ed6eb92 190 static void _LoggingServer_OutputToFlash(uint32_t fifoData) {
jbradshaw 0:e4a10ed6eb92 191 uint32_t index;
jbradshaw 0:e4a10ed6eb92 192 char str[128];
jbradshaw 0:e4a10ed6eb92 193 uint8_t *ptr;
jbradshaw 0:e4a10ed6eb92 194 //
jbradshaw 0:e4a10ed6eb92 195 // Log To Flash
jbradshaw 0:e4a10ed6eb92 196 //
jbradshaw 0:e4a10ed6eb92 197 // i.e. there is data, read one 32-bit size data at a time.
jbradshaw 0:e4a10ed6eb92 198 // put the fifo data into the ping-pong SRAM
jbradshaw 0:e4a10ed6eb92 199 PingPong_SRAM[sramIndex++] = fifoData & 0xFF; // LSByte goes into index N
jbradshaw 0:e4a10ed6eb92 200 PingPong_SRAM[sramIndex++] = (fifoData >> 8) & 0xFF;
jbradshaw 0:e4a10ed6eb92 201 PingPong_SRAM[sramIndex++] = (fifoData >> 16) & 0xFF;
jbradshaw 0:e4a10ed6eb92 202 PingPong_SRAM[sramIndex++] = (fifoData >> 24) & 0xFF; // MSByte goes into index N+3
jbradshaw 0:e4a10ed6eb92 203
jbradshaw 0:e4a10ed6eb92 204 // flag this buffer as dirty
jbradshaw 0:e4a10ed6eb92 205 if (sramIndex <= 256)
jbradshaw 0:e4a10ed6eb92 206 sram_buffer_0_dirty = 1;
jbradshaw 0:e4a10ed6eb92 207 else
jbradshaw 0:e4a10ed6eb92 208 sram_buffer_1_dirty = 1;
jbradshaw 0:e4a10ed6eb92 209
jbradshaw 0:e4a10ed6eb92 210 if (sramIndex == 256 ||
jbradshaw 0:e4a10ed6eb92 211 sramIndex == 512) // Either Ping SRAM or Pong SRAM location is full
jbradshaw 0:e4a10ed6eb92 212 { // therefore write to Flash
jbradshaw 0:e4a10ed6eb92 213
jbradshaw 0:e4a10ed6eb92 214 index = sramIndex - 256;
jbradshaw 0:e4a10ed6eb92 215 ptr = &PingPong_SRAM[index];
jbradshaw 0:e4a10ed6eb92 216 sprintf(str, "currentPage=%d", currentPage);
jbradshaw 0:e4a10ed6eb92 217 Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0);
jbradshaw 0:e4a10ed6eb92 218
jbradshaw 0:e4a10ed6eb92 219 // this page is no longer dirty
jbradshaw 0:e4a10ed6eb92 220 if (index == 0)
jbradshaw 0:e4a10ed6eb92 221 sram_buffer_0_dirty = 0;
jbradshaw 0:e4a10ed6eb92 222 if (index == 256)
jbradshaw 0:e4a10ed6eb92 223 sram_buffer_1_dirty = 0;
jbradshaw 0:e4a10ed6eb92 224
jbradshaw 0:e4a10ed6eb92 225 currentPage++;
jbradshaw 0:e4a10ed6eb92 226 }
jbradshaw 0:e4a10ed6eb92 227 sramIndex = sramIndex % 512; // Wrap around the index
jbradshaw 0:e4a10ed6eb92 228 }
jbradshaw 0:e4a10ed6eb92 229
jbradshaw 0:e4a10ed6eb92 230 /**
jbradshaw 0:e4a10ed6eb92 231 * @brief If flash ram buffers are flagged as dirty, flush to flash
jbradshaw 0:e4a10ed6eb92 232 */
jbradshaw 0:e4a10ed6eb92 233 static void _LoggingServer_WriteDirtySramBufferToFlash(void) {
jbradshaw 0:e4a10ed6eb92 234 uint8_t *ptr = PingPong_SRAM;
jbradshaw 0:e4a10ed6eb92 235 if (sram_buffer_0_dirty == 0 && sram_buffer_1_dirty == 0)
jbradshaw 0:e4a10ed6eb92 236 return;
jbradshaw 0:e4a10ed6eb92 237 if (sram_buffer_0_dirty == 1) {
jbradshaw 0:e4a10ed6eb92 238 ptr += 0;
jbradshaw 0:e4a10ed6eb92 239 }
jbradshaw 0:e4a10ed6eb92 240 if (sram_buffer_1_dirty == 1) {
jbradshaw 0:e4a10ed6eb92 241 ptr += 256;
jbradshaw 0:e4a10ed6eb92 242 }
jbradshaw 0:e4a10ed6eb92 243 printf("_LoggingServer_WriteDirtySramBufferToFlash:%d,%d\n",
jbradshaw 0:e4a10ed6eb92 244 sram_buffer_0_dirty, sram_buffer_1_dirty);
jbradshaw 0:e4a10ed6eb92 245 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 246 // s25fs512_WritePage_Helper(currentPage, ptr, 0);
jbradshaw 0:e4a10ed6eb92 247 Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0);
jbradshaw 0:e4a10ed6eb92 248 }
jbradshaw 0:e4a10ed6eb92 249
jbradshaw 0:e4a10ed6eb92 250 /**
jbradshaw 0:e4a10ed6eb92 251 * @brief Initialize the USB block running index
jbradshaw 0:e4a10ed6eb92 252 * @param fifoData Sensor data taken from the fifo to be sent out USB
jbradshaw 0:e4a10ed6eb92 253 */
jbradshaw 0:e4a10ed6eb92 254 static void _LoggingServer_OutputToCdcAcm(uint32_t fifoData) {
jbradshaw 0:e4a10ed6eb92 255 uint8_t *ptr;
jbradshaw 0:e4a10ed6eb92 256 uint8_t str[16];
jbradshaw 0:e4a10ed6eb92 257 sprintf((char *)str, "%X ", fifoData);
jbradshaw 0:e4a10ed6eb92 258 ptr = str;
jbradshaw 0:e4a10ed6eb92 259 usb_block_index = 0;
jbradshaw 0:e4a10ed6eb92 260 while (*ptr != 0) {
jbradshaw 0:e4a10ed6eb92 261 usb_block[usb_block_index] = *ptr;
jbradshaw 0:e4a10ed6eb92 262 ptr++;
jbradshaw 0:e4a10ed6eb92 263 usb_block_index++;
jbradshaw 0:e4a10ed6eb92 264 }
jbradshaw 0:e4a10ed6eb92 265 Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index);
jbradshaw 0:e4a10ed6eb92 266 }
jbradshaw 0:e4a10ed6eb92 267
jbradshaw 0:e4a10ed6eb92 268 /**
jbradshaw 0:e4a10ed6eb92 269 * @brief Initialize the USB block running index
jbradshaw 0:e4a10ed6eb92 270 */
jbradshaw 0:e4a10ed6eb92 271 static void _LoggingServer_OutputToCdcAcm_Start(void) { usb_block_index = 0; }
jbradshaw 0:e4a10ed6eb92 272
jbradshaw 0:e4a10ed6eb92 273 /**
jbradshaw 0:e4a10ed6eb92 274 * @brief Buffer up fifoData from sensors, do a USB block transfer if buffer is
jbradshaw 0:e4a10ed6eb92 275 * full
jbradshaw 0:e4a10ed6eb92 276 * @param fifoData Sensor data taken from the fifo to be send out USB within a
jbradshaw 0:e4a10ed6eb92 277 * bulk block transfer
jbradshaw 0:e4a10ed6eb92 278 * @return Return the success status of the writeblock operation
jbradshaw 0:e4a10ed6eb92 279 */
jbradshaw 0:e4a10ed6eb92 280 static bool _LoggingServer_OutputToCdcAcm_Block(uint32_t fifoData) {
jbradshaw 0:e4a10ed6eb92 281 uint8_t str[64];
jbradshaw 0:e4a10ed6eb92 282 uint8_t *ptr;
jbradshaw 0:e4a10ed6eb92 283 bool result;
jbradshaw 0:e4a10ed6eb92 284 //
jbradshaw 0:e4a10ed6eb92 285 // Log to CDCACM
jbradshaw 0:e4a10ed6eb92 286 //
jbradshaw 0:e4a10ed6eb92 287 result = true;
jbradshaw 0:e4a10ed6eb92 288 sprintf((char *)str, "%X ", fifoData);
jbradshaw 0:e4a10ed6eb92 289 ptr = str;
jbradshaw 0:e4a10ed6eb92 290 while (*ptr != 0) {
jbradshaw 0:e4a10ed6eb92 291 usb_block[usb_block_index] = *ptr;
jbradshaw 0:e4a10ed6eb92 292 ptr++;
jbradshaw 0:e4a10ed6eb92 293 usb_block_index++;
jbradshaw 0:e4a10ed6eb92 294 if (usb_block_index >= 64) {
jbradshaw 0:e4a10ed6eb92 295 result = Peripherals::usbSerial()->writeBlock(usb_block, 64);
jbradshaw 0:e4a10ed6eb92 296 usb_block_index = 0;
jbradshaw 0:e4a10ed6eb92 297 }
jbradshaw 0:e4a10ed6eb92 298 }
jbradshaw 0:e4a10ed6eb92 299 return result;
jbradshaw 0:e4a10ed6eb92 300 }
jbradshaw 0:e4a10ed6eb92 301
jbradshaw 0:e4a10ed6eb92 302 /**
jbradshaw 0:e4a10ed6eb92 303 * @brief Output a full USB block via bulk transfer
jbradshaw 0:e4a10ed6eb92 304 */
jbradshaw 0:e4a10ed6eb92 305 static void _LoggingServer_OutputToCdcAcm_End(void) {
jbradshaw 0:e4a10ed6eb92 306 if (usb_block_index == 0)
jbradshaw 0:e4a10ed6eb92 307 return;
jbradshaw 0:e4a10ed6eb92 308 Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index - 1);
jbradshaw 0:e4a10ed6eb92 309 }
jbradshaw 0:e4a10ed6eb92 310
jbradshaw 0:e4a10ed6eb92 311 /**
jbradshaw 0:e4a10ed6eb92 312 * @brief Blink LED pattern that indicates that the flash end boundary has been
jbradshaw 0:e4a10ed6eb92 313 * reached
jbradshaw 0:e4a10ed6eb92 314 */
jbradshaw 0:e4a10ed6eb92 315 static void BlinkEndOfDatalogging(void) {
jbradshaw 0:e4a10ed6eb92 316 // blink to signal end of logging
jbradshaw 0:e4a10ed6eb92 317 Peripherals::hspLed()->pattern(0x55555555, 20);
jbradshaw 0:e4a10ed6eb92 318 wait(2);
jbradshaw 0:e4a10ed6eb92 319 }
jbradshaw 0:e4a10ed6eb92 320
jbradshaw 0:e4a10ed6eb92 321 /**
jbradshaw 0:e4a10ed6eb92 322 * @brief Reads the first data page of flash, if all FF's then the page is empty
jbradshaw 0:e4a10ed6eb92 323 * @return 1 if the flash is empty as indicated by the first data page of the
jbradshaw 0:e4a10ed6eb92 324 * flash, 0 if not
jbradshaw 0:e4a10ed6eb92 325 */
jbradshaw 0:e4a10ed6eb92 326 int isFlashEmpty(void) {
jbradshaw 0:e4a10ed6eb92 327 int i;
jbradshaw 0:e4a10ed6eb92 328 uint8_t data[256];
jbradshaw 0:e4a10ed6eb92 329 int firstDataPage = Logging_GetLoggingStartPage();
jbradshaw 0:e4a10ed6eb92 330 Peripherals::s25FS512()->readPages_Helper(firstDataPage, firstDataPage, data, 0);
jbradshaw 0:e4a10ed6eb92 331 for (i = 0; i < 256; i++) {
jbradshaw 0:e4a10ed6eb92 332 if (data[i] != 0xFF)
jbradshaw 0:e4a10ed6eb92 333 return 0;
jbradshaw 0:e4a10ed6eb92 334 }
jbradshaw 0:e4a10ed6eb92 335 return 1;
jbradshaw 0:e4a10ed6eb92 336 }
jbradshaw 0:e4a10ed6eb92 337
jbradshaw 0:e4a10ed6eb92 338 /**
jbradshaw 0:e4a10ed6eb92 339 * @brief Blink LED pattern that indicates that the flash is not empty and a new
jbradshaw 0:e4a10ed6eb92 340 * flash logging session can not occur
jbradshaw 0:e4a10ed6eb92 341 */
jbradshaw 0:e4a10ed6eb92 342 void BlinkFlashNotEmpty(void) {
jbradshaw 0:e4a10ed6eb92 343 Peripherals::hspLed()->pattern(0x55555555, 20);
jbradshaw 0:e4a10ed6eb92 344 wait(1);
jbradshaw 0:e4a10ed6eb92 345 }
jbradshaw 0:e4a10ed6eb92 346
jbradshaw 0:e4a10ed6eb92 347 void ExecuteDefaultMission(void) {
jbradshaw 0:e4a10ed6eb92 348 ProcessCmd("/MAX30001/CAL_InitStart 01 01 01 03 7FF 00");
jbradshaw 0:e4a10ed6eb92 349 ProcessCmd("/MAX30001/ECG_InitStart 01 01 01 00 02 03 1F 0 00 00 01");
jbradshaw 0:e4a10ed6eb92 350 ProcessCmd("/MAX30001/RtoR_InitStart 01 03 0F 00 03 01 00 00 01");
jbradshaw 0:e4a10ed6eb92 351 ProcessCmd("/MAX30001/Rbias_FMSTR_Init 01 02 01 01 00");
jbradshaw 0:e4a10ed6eb92 352 ProcessCmd("/LIS2DH/InitStart 02 01");
jbradshaw 0:e4a10ed6eb92 353 }
jbradshaw 0:e4a10ed6eb92 354
jbradshaw 0:e4a10ed6eb92 355 void LoggingService_Init(void) { loggingTrigger = eTriggerLog_NULL; }
jbradshaw 0:e4a10ed6eb92 356
jbradshaw 0:e4a10ed6eb92 357 /**
jbradshaw 0:e4a10ed6eb92 358 * @brief This routine checks to see if a USB or flash logging action needs to be taken
jbradshaw 0:e4a10ed6eb92 359 * The routine checks for a start condition via button press, USB command, or BLE command
jbradshaw 0:e4a10ed6eb92 360 * Once one of these start conditions is present, the logging begins until stopped or memory is full
jbradshaw 0:e4a10ed6eb92 361 * @return 1 if successful, 0 if error or logging was aborted and no logging occurred
jbradshaw 0:e4a10ed6eb92 362 */
jbradshaw 0:e4a10ed6eb92 363 uint8_t LoggingService_ServiceRoutine(void) {
jbradshaw 0:e4a10ed6eb92 364 uint32_t fifoData;
jbradshaw 0:e4a10ed6eb92 365 uint32_t endPage;
jbradshaw 0:e4a10ed6eb92 366 USBSerial *usbSerial = Peripherals::usbSerial();
jbradshaw 0:e4a10ed6eb92 367 // BMP280 *bmp280 = Peripherals::bmp280();
jbradshaw 0:e4a10ed6eb92 368 bool buttonPressed;
jbradshaw 0:e4a10ed6eb92 369 int packetBurstCount = 0;
jbradshaw 0:e4a10ed6eb92 370 HspLed *hspLed = Peripherals::hspLed();
jbradshaw 0:e4a10ed6eb92 371
jbradshaw 0:e4a10ed6eb92 372 sramIndex = 0;
jbradshaw 0:e4a10ed6eb92 373 // only start logging if conditions exist
jbradshaw 0:e4a10ed6eb92 374
jbradshaw 0:e4a10ed6eb92 375 if (_LoggingService_CheckStartCondition() == false) return 0;
jbradshaw 0:e4a10ed6eb92 376 printf("Begin Logging...");
jbradshaw 0:e4a10ed6eb92 377 if (startEvent == eStartEvent_NULL) printf("eStartEvent_NULL...");
jbradshaw 0:e4a10ed6eb92 378 if (startEvent == eStartEvent_BLE) printf("eStartEvent_BLE...");
jbradshaw 0:e4a10ed6eb92 379 if (startEvent == eStartEvent_BUTTON) printf("eStartEvent_BUTTON...");
jbradshaw 0:e4a10ed6eb92 380 if (startEvent == eStartEvent_RPC_TO_USB) printf("eStartEvent_RPC_TO_USB...");
jbradshaw 0:e4a10ed6eb92 381 if (startEvent == eStartEvent_RPC_TO_FLASH) printf("eStartEvent_RPC_TO_FLASH...");
jbradshaw 0:e4a10ed6eb92 382 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 383
jbradshaw 0:e4a10ed6eb92 384 // start logging stuttered blink pattern
jbradshaw 0:e4a10ed6eb92 385 hspLed->pattern(0xA0F3813, 20);
jbradshaw 0:e4a10ed6eb92 386
jbradshaw 0:e4a10ed6eb92 387 if (startEvent == eStartEvent_RPC_TO_FLASH ||
jbradshaw 0:e4a10ed6eb92 388 startEvent == eStartEvent_BUTTON) {
jbradshaw 0:e4a10ed6eb92 389 // check to see if datalog already in flash... abort and force user to erase
jbradshaw 0:e4a10ed6eb92 390 // flash if needed
jbradshaw 0:e4a10ed6eb92 391 if (loggingOutput == eLogToFlash) {
jbradshaw 0:e4a10ed6eb92 392 if (isFlashEmpty() == 0) {
jbradshaw 0:e4a10ed6eb92 393 Logging_SetStart(false);
jbradshaw 0:e4a10ed6eb92 394 // bleStartCommand = 0x00;
jbradshaw 0:e4a10ed6eb92 395 BlinkFlashNotEmpty();
jbradshaw 0:e4a10ed6eb92 396 hspLed->blink(1000);
jbradshaw 0:e4a10ed6eb92 397 printf("Abort Logging, flash log exists. ");
jbradshaw 0:e4a10ed6eb92 398 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 399 return 0;
jbradshaw 0:e4a10ed6eb92 400 }
jbradshaw 0:e4a10ed6eb92 401 }
jbradshaw 0:e4a10ed6eb92 402 }
jbradshaw 0:e4a10ed6eb92 403
jbradshaw 0:e4a10ed6eb92 404 if (startEvent == eStartEvent_BLE) {
jbradshaw 0:e4a10ed6eb92 405 // check for mission in flash
jbradshaw 0:e4a10ed6eb92 406 if (_LoggingService_ReadMissionFromFlash() == false) {
jbradshaw 0:e4a10ed6eb92 407 // if there is no mission in flash then do a default mission for the sake
jbradshaw 0:e4a10ed6eb92 408 // of ble Android app working "out-of-the-box" and stream RtoR and Accel
jbradshaw 0:e4a10ed6eb92 409 printf("No Mission in Flash...ExecuteDefaultMission...");
jbradshaw 0:e4a10ed6eb92 410 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 411 ExecuteDefaultMission();
jbradshaw 0:e4a10ed6eb92 412 // do not log this data
jbradshaw 0:e4a10ed6eb92 413 loggingOutput = eLogToNothing;
jbradshaw 0:e4a10ed6eb92 414 } else {
jbradshaw 0:e4a10ed6eb92 415 // there is a mission in flash check if there is already logged data
jbradshaw 0:e4a10ed6eb92 416 if (isFlashEmpty() == 0) {
jbradshaw 0:e4a10ed6eb92 417 // just do default mission
jbradshaw 0:e4a10ed6eb92 418 printf("Logged Data Detected...ExecuteDefaultMission...");
jbradshaw 0:e4a10ed6eb92 419 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 420 ExecuteDefaultMission();
jbradshaw 0:e4a10ed6eb92 421 // do not log this data
jbradshaw 0:e4a10ed6eb92 422 loggingOutput = eLogToNothing;
jbradshaw 0:e4a10ed6eb92 423 } else {
jbradshaw 0:e4a10ed6eb92 424 // flag that we are logging to flash
jbradshaw 0:e4a10ed6eb92 425 loggingOutput = eLogToFlash;
jbradshaw 0:e4a10ed6eb92 426 }
jbradshaw 0:e4a10ed6eb92 427 }
jbradshaw 0:e4a10ed6eb92 428 }
jbradshaw 0:e4a10ed6eb92 429
jbradshaw 0:e4a10ed6eb92 430 // if we are logging to flash then read mission in flash
jbradshaw 0:e4a10ed6eb92 431 if (loggingOutput == eLogToFlash) {
jbradshaw 0:e4a10ed6eb92 432 if (_LoggingService_ReadMissionFromFlash() ==
jbradshaw 0:e4a10ed6eb92 433 false) { // if there is no mission in flash then get out
jbradshaw 0:e4a10ed6eb92 434 Logging_SetStart(false);
jbradshaw 0:e4a10ed6eb92 435 Peripherals::hspLed()->pattern(0xC3C3C3C3, 20);
jbradshaw 0:e4a10ed6eb92 436 wait(2);
jbradshaw 0:e4a10ed6eb92 437 printf("Abort Logging, Mission does not exist. ");
jbradshaw 0:e4a10ed6eb92 438 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 439 return 0;
jbradshaw 0:e4a10ed6eb92 440 }
jbradshaw 0:e4a10ed6eb92 441 currentPage = Logging_GetLoggingStartPage();
jbradshaw 0:e4a10ed6eb92 442 endPage = Logging_GetLoggingEndPage();
jbradshaw 0:e4a10ed6eb92 443 }
jbradshaw 0:e4a10ed6eb92 444
jbradshaw 0:e4a10ed6eb92 445 MAX30001_Helper_SetupInterrupts();
jbradshaw 0:e4a10ed6eb92 446 if (MAX30001_AnyStreamingSet() == 1) {
jbradshaw 0:e4a10ed6eb92 447 MAX30001_Helper_StartSync();
jbradshaw 0:e4a10ed6eb92 448 }
jbradshaw 0:e4a10ed6eb92 449
jbradshaw 0:e4a10ed6eb92 450 SetDataLoggingStream(TRUE);
jbradshaw 0:e4a10ed6eb92 451 ServiceNonInterrupt_Init();
jbradshaw 0:e4a10ed6eb92 452 ServiceNonInterrupt_StartTimer();
jbradshaw 0:e4a10ed6eb92 453
jbradshaw 0:e4a10ed6eb92 454 while (usbSerial->readable()) {
jbradshaw 0:e4a10ed6eb92 455 usbSerial->_getc();
jbradshaw 0:e4a10ed6eb92 456 }
jbradshaw 0:e4a10ed6eb92 457 fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo
jbradshaw 0:e4a10ed6eb92 458 fifo_clear(GetStreamOutFifo());
jbradshaw 0:e4a10ed6eb92 459
jbradshaw 0:e4a10ed6eb92 460 sram_buffer_0_dirty = 0;
jbradshaw 0:e4a10ed6eb92 461 sram_buffer_1_dirty = 0;
jbradshaw 0:e4a10ed6eb92 462
jbradshaw 0:e4a10ed6eb92 463
jbradshaw 0:e4a10ed6eb92 464 if (loggingOutput == eLogToNothing) printf("eLogToNothing..."); fflush(stdout);
jbradshaw 0:e4a10ed6eb92 465 if (loggingOutput == eLogToFlash) printf("eLogToFlash..."); fflush(stdout);
jbradshaw 0:e4a10ed6eb92 466 if (loggingOutput == eLogtoUsb) printf("eLogtoUsb..."); fflush(stdout);
jbradshaw 0:e4a10ed6eb92 467 printf("highDataRate=%d...",highDataRate); fflush(stdout);
jbradshaw 0:e4a10ed6eb92 468
jbradshaw 0:e4a10ed6eb92 469
jbradshaw 0:e4a10ed6eb92 470 Peripherals::timestampTimer()->reset();
jbradshaw 0:e4a10ed6eb92 471 Peripherals::timestampTimer()->start();
jbradshaw 0:e4a10ed6eb92 472
jbradshaw 0:e4a10ed6eb92 473 _LoggingServer_OutputToCdcAcm_Start();
jbradshaw 0:e4a10ed6eb92 474 while (1) {
jbradshaw 0:e4a10ed6eb92 475 if (loggingOutput == eLogToFlash) {
jbradshaw 0:e4a10ed6eb92 476 // check if we are at the end of flash
jbradshaw 0:e4a10ed6eb92 477 if (currentPage >= endPage) {
jbradshaw 0:e4a10ed6eb92 478 BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging
jbradshaw 0:e4a10ed6eb92 479 break;
jbradshaw 0:e4a10ed6eb92 480 }
jbradshaw 0:e4a10ed6eb92 481 }
jbradshaw 0:e4a10ed6eb92 482
jbradshaw 0:e4a10ed6eb92 483 if (startEvent == eStartEvent_BUTTON) {
jbradshaw 0:e4a10ed6eb92 484 buttonPressed = Peripherals::pushButton()->GetButtonFallState();
jbradshaw 0:e4a10ed6eb92 485 if (buttonPressed) {
jbradshaw 0:e4a10ed6eb92 486 Peripherals::pushButton()->clearButtonFallState();
jbradshaw 0:e4a10ed6eb92 487 // if there is a dirty sram buffer... flush it to flash
jbradshaw 0:e4a10ed6eb92 488 _LoggingServer_WriteDirtySramBufferToFlash();
jbradshaw 0:e4a10ed6eb92 489 BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging
jbradshaw 0:e4a10ed6eb92 490 break;
jbradshaw 0:e4a10ed6eb92 491 }
jbradshaw 0:e4a10ed6eb92 492 }
jbradshaw 0:e4a10ed6eb92 493
jbradshaw 0:e4a10ed6eb92 494 if (loggingTrigger == eTriggerLog_BLE) {
jbradshaw 0:e4a10ed6eb92 495 if (Peripherals::hspBLE()->getStartDataLogging() == false) {
jbradshaw 0:e4a10ed6eb92 496 // if there is a dirty sram buffer... flush it to flash
jbradshaw 0:e4a10ed6eb92 497 _LoggingServer_WriteDirtySramBufferToFlash();
jbradshaw 0:e4a10ed6eb92 498 BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging
jbradshaw 0:e4a10ed6eb92 499 break;
jbradshaw 0:e4a10ed6eb92 500 }
jbradshaw 0:e4a10ed6eb92 501 }
jbradshaw 0:e4a10ed6eb92 502
jbradshaw 0:e4a10ed6eb92 503 if (startEvent == eStartEvent_RPC_TO_USB ||
jbradshaw 0:e4a10ed6eb92 504 startEvent == eStartEvent_RPC_TO_FLASH) {
jbradshaw 0:e4a10ed6eb92 505 if (usbSerial->available()) {
jbradshaw 0:e4a10ed6eb92 506 if (loggingOutput == eLogToFlash) {
jbradshaw 0:e4a10ed6eb92 507 _LoggingServer_WriteDirtySramBufferToFlash();
jbradshaw 0:e4a10ed6eb92 508 }
jbradshaw 0:e4a10ed6eb92 509 wait(0.2f);
jbradshaw 0:e4a10ed6eb92 510 while (usbSerial->available()) {
jbradshaw 0:e4a10ed6eb92 511 usbSerial->_getc();
jbradshaw 0:e4a10ed6eb92 512 }
jbradshaw 0:e4a10ed6eb92 513 fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo
jbradshaw 0:e4a10ed6eb92 514 fifo_clear(GetStreamOutFifo());
jbradshaw 0:e4a10ed6eb92 515 break;
jbradshaw 0:e4a10ed6eb92 516 }
jbradshaw 0:e4a10ed6eb92 517 }
jbradshaw 0:e4a10ed6eb92 518
jbradshaw 0:e4a10ed6eb92 519 // check to see if data is available
jbradshaw 0:e4a10ed6eb92 520 packetBurstCount = 0;
jbradshaw 0:e4a10ed6eb92 521 while (PacketFifo_Empty() == 0) {
jbradshaw 0:e4a10ed6eb92 522 if (packetBurstCount >= 100)
jbradshaw 0:e4a10ed6eb92 523 break;
jbradshaw 0:e4a10ed6eb92 524 fifoData = PacketFifo_GetUint32();
jbradshaw 0:e4a10ed6eb92 525 if (loggingOutput == eLogToFlash) {
jbradshaw 0:e4a10ed6eb92 526 _LoggingServer_OutputToFlash(fifoData);
jbradshaw 0:e4a10ed6eb92 527 }
jbradshaw 0:e4a10ed6eb92 528 if (loggingOutput == eLogtoUsb) {
jbradshaw 0:e4a10ed6eb92 529 if (highDataRate == 0)
jbradshaw 0:e4a10ed6eb92 530 _LoggingServer_OutputToCdcAcm(fifoData);
jbradshaw 0:e4a10ed6eb92 531 else
jbradshaw 0:e4a10ed6eb92 532 _LoggingServer_OutputToCdcAcm_Block(fifoData);
jbradshaw 0:e4a10ed6eb92 533 }
jbradshaw 0:e4a10ed6eb92 534 packetBurstCount++;
jbradshaw 0:e4a10ed6eb92 535 }
jbradshaw 0:e4a10ed6eb92 536
jbradshaw 0:e4a10ed6eb92 537 if (PacketFifo_Empty() != 0) {
jbradshaw 0:e4a10ed6eb92 538 Peripherals::ble()->waitForEvent();
jbradshaw 0:e4a10ed6eb92 539 }
jbradshaw 0:e4a10ed6eb92 540 ServiceNonInterrupt_BMP280(bmp280_Logging);
jbradshaw 0:e4a10ed6eb92 541 ServiceNonInterrupt_MAX30205(MAX30205_0_Logging,
jbradshaw 0:e4a10ed6eb92 542 Peripherals::max30205_top(),
jbradshaw 0:e4a10ed6eb92 543 PACKET_MAX30205_TEMP_TOP);
jbradshaw 0:e4a10ed6eb92 544 ServiceNonInterrupt_MAX30205(MAX30205_1_Logging,
jbradshaw 0:e4a10ed6eb92 545 Peripherals::max30205_bottom(),
jbradshaw 0:e4a10ed6eb92 546 PACKET_MAX30205_TEMP_BOTTOM);
jbradshaw 0:e4a10ed6eb92 547 }
jbradshaw 0:e4a10ed6eb92 548 _LoggingServer_OutputToCdcAcm_End();
jbradshaw 0:e4a10ed6eb92 549 printf("End Logging.\n");
jbradshaw 0:e4a10ed6eb92 550 fflush(stdout);
jbradshaw 0:e4a10ed6eb92 551
jbradshaw 0:e4a10ed6eb92 552 bmp280_Logging->stop();
jbradshaw 0:e4a10ed6eb92 553 MAX30205_0_Logging->stop();
jbradshaw 0:e4a10ed6eb92 554 MAX30205_1_Logging->stop();
jbradshaw 0:e4a10ed6eb92 555 MAX30001_Helper_Stop(); // if any MAX30001 streams have been started, stop
jbradshaw 0:e4a10ed6eb92 556 // them
jbradshaw 0:e4a10ed6eb92 557 MAX30101_Helper_Stop(); // if any MAX30101 streams have been started, stop
jbradshaw 0:e4a10ed6eb92 558 // them
jbradshaw 0:e4a10ed6eb92 559 Peripherals::lis2dh()->stop();
jbradshaw 0:e4a10ed6eb92 560 SetDataLoggingStream(FALSE);
jbradshaw 0:e4a10ed6eb92 561 Peripherals::timestampTimer()->stop();
jbradshaw 0:e4a10ed6eb92 562 hspLed->blink(1000);
jbradshaw 0:e4a10ed6eb92 563 // default to non-usb packet speed optimizing
jbradshaw 0:e4a10ed6eb92 564 highDataRate = 0;
jbradshaw 0:e4a10ed6eb92 565 loggingTrigger = eTriggerLog_NULL;
jbradshaw 0:e4a10ed6eb92 566 return 1;
jbradshaw 0:e4a10ed6eb92 567 }