Host software for the MAX30001 ECG, PACE, biopotential, bioimpedance, R-to-R peak sensor. Hosted on the MAX32630FTHR.

Dependencies:   SDFileSystem USBDevice max32630fthr

Fork of MAX30001 SYS EvKit by Emre Eken

MAX30001-MAX32630FTHR ECG Evaluation System

The MAX30001 EVKIT SYS-MBED Evaluation System (EV System) is used to evaluates the MAX30001 sensor, which is an ECG (electrocardiogram), biopotential and bioimpedance analog front end solution for wearable applications. The full evaluation system consists of the MAX32630FTHR board, MAX30001 EVKIT sensor board and the evaluation software. The evaluation kit features ECG, PACE, R-to-R (R-peak timing) detection; bioimpedance (BioZ) AFE; and raw data logging.

The MAX30001 EVKIT evaluation system is assembled, tested and contains the necessary circuitry and connections to evaluate the MAX30001 ECG sensor.

When evaluated as an evaluation system, the MAX32630FTHR board provides the necessary logic rails, master clock, SPI, USB-to-Serial interfaces that are needed to evaluate the MAX30001 sensor board. MAX32630FTHR can be used as an independent development platform.

Communication between the PC and the MAX32630FTHR board is facilitated by a Windows 7, Windows 8 and Windows 10 compatible software that provides a simple and intuitive graphical user interface (GUI).

For more information, visit the wiki pages by clicking the wiki tab above and MAX30001EVSYS product page.

C++ source code, library for the MAX30001 ECG drivers are in the links at the bottom of this page. The sample code includes the ability to log data to the SD card of the MAX32630FTHR.

MAX30001 EVKIT Pinout Connections

/media/uploads/EmreE/max30001_sensor_board_connector_pinout.png

Where to Buy

MAX30001EVSYS-Buy

Committer:
Emre.Eken
Date:
Tue Jul 24 15:21:03 2018 +0300
Revision:
12:a2e4e8909300
Files' hierarchy is changed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Emre.Eken 12:a2e4e8909300 1 /*******************************************************************************
Emre.Eken 12:a2e4e8909300 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
Emre.Eken 12:a2e4e8909300 3 *
Emre.Eken 12:a2e4e8909300 4 * Permission is hereby granted, free of charge, to any person obtaining a
Emre.Eken 12:a2e4e8909300 5 * copy of this software and associated documentation files (the "Software"),
Emre.Eken 12:a2e4e8909300 6 * to deal in the Software without restriction, including without limitation
Emre.Eken 12:a2e4e8909300 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Emre.Eken 12:a2e4e8909300 8 * and/or sell copies of the Software, and to permit persons to whom the
Emre.Eken 12:a2e4e8909300 9 * Software is furnished to do so, subject to the following conditions:
Emre.Eken 12:a2e4e8909300 10 *
Emre.Eken 12:a2e4e8909300 11 * The above copyright notice and this permission notice shall be included
Emre.Eken 12:a2e4e8909300 12 * in all copies or substantial portions of the Software.
Emre.Eken 12:a2e4e8909300 13 *
Emre.Eken 12:a2e4e8909300 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Emre.Eken 12:a2e4e8909300 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Emre.Eken 12:a2e4e8909300 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Emre.Eken 12:a2e4e8909300 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Emre.Eken 12:a2e4e8909300 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Emre.Eken 12:a2e4e8909300 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Emre.Eken 12:a2e4e8909300 20 * OTHER DEALINGS IN THE SOFTWARE.
Emre.Eken 12:a2e4e8909300 21 *
Emre.Eken 12:a2e4e8909300 22 * Except as contained in this notice, the name of Maxim Integrated
Emre.Eken 12:a2e4e8909300 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Emre.Eken 12:a2e4e8909300 24 * Products, Inc. Branding Policy.
Emre.Eken 12:a2e4e8909300 25 *
Emre.Eken 12:a2e4e8909300 26 * The mere transfer of this software does not imply any licenses
Emre.Eken 12:a2e4e8909300 27 * of trade secrets, proprietary technology, copyrights, patents,
Emre.Eken 12:a2e4e8909300 28 * trademarks, maskwork rights, or any other form of intellectual
Emre.Eken 12:a2e4e8909300 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
Emre.Eken 12:a2e4e8909300 30 * ownership rights.
Emre.Eken 12:a2e4e8909300 31 *******************************************************************************
Emre.Eken 12:a2e4e8909300 32 */
Emre.Eken 12:a2e4e8909300 33 #include "mbed.h"
Emre.Eken 12:a2e4e8909300 34 #include "max32630fthr.h"
Emre.Eken 12:a2e4e8909300 35 #include "USBSerial.h"
Emre.Eken 12:a2e4e8909300 36 #include "RpcServer.h"
Emre.Eken 12:a2e4e8909300 37 #include "StringInOut.h"
Emre.Eken 12:a2e4e8909300 38 #include "Peripherals.h"
Emre.Eken 12:a2e4e8909300 39 #include "MAX30001.h"
Emre.Eken 12:a2e4e8909300 40 #include "DataLoggingService.h"
Emre.Eken 12:a2e4e8909300 41 #include "PushButton.h"
Emre.Eken 12:a2e4e8909300 42 #include "USBSerial.h"
Emre.Eken 12:a2e4e8909300 43 #include "Streaming.h"
Emre.Eken 12:a2e4e8909300 44 #include "SDFileSystem.h"
Emre.Eken 12:a2e4e8909300 45 #include "version.h"
Emre.Eken 12:a2e4e8909300 46
Emre.Eken 12:a2e4e8909300 47
Emre.Eken 12:a2e4e8909300 48 //Init PMIC on FTHR board and set logic thresholds to 3.3V
Emre.Eken 12:a2e4e8909300 49 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
Emre.Eken 12:a2e4e8909300 50
Emre.Eken 12:a2e4e8909300 51 SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd"); // mosi, miso, sclk, cs
Emre.Eken 12:a2e4e8909300 52
Emre.Eken 12:a2e4e8909300 53 ///
Emre.Eken 12:a2e4e8909300 54 /// wire Interfaces
Emre.Eken 12:a2e4e8909300 55 ///
Emre.Eken 12:a2e4e8909300 56 /// Define with Maxim VID and a Maxim assigned PID, set to version 0x0001 and non-blocking
Emre.Eken 12:a2e4e8909300 57 USBSerial usbSerial(0x0b6a, 0x7531, 0x0001, false);
Emre.Eken 12:a2e4e8909300 58
Emre.Eken 12:a2e4e8909300 59
Emre.Eken 12:a2e4e8909300 60 //SD card insertion detection pin
Emre.Eken 12:a2e4e8909300 61 DigitalIn SDDetect(P2_2, PullUp);
Emre.Eken 12:a2e4e8909300 62
Emre.Eken 12:a2e4e8909300 63
Emre.Eken 12:a2e4e8909300 64 /// DigitalOut for CS
Emre.Eken 12:a2e4e8909300 65 DigitalOut cs(P5_6);
Emre.Eken 12:a2e4e8909300 66 /// SPI Master 2 with SPI0_SS for use with MAX30001
Emre.Eken 12:a2e4e8909300 67 SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // used by MAX30001
Emre.Eken 12:a2e4e8909300 68 /// SPI Master 1
Emre.Eken 12:a2e4e8909300 69 QuadSpiInterface quadSpiInterface(SPI1_MOSI, SPI1_MISO, SPI1_SCK,
Emre.Eken 12:a2e4e8909300 70 SPI1_SS); // used by S25FS512
Emre.Eken 12:a2e4e8909300 71 ///Debug port
Emre.Eken 12:a2e4e8909300 72 Serial debug(USBTX, USBRX);
Emre.Eken 12:a2e4e8909300 73
Emre.Eken 12:a2e4e8909300 74 ///
Emre.Eken 12:a2e4e8909300 75 /// Devices
Emre.Eken 12:a2e4e8909300 76 ///
Emre.Eken 12:a2e4e8909300 77
Emre.Eken 12:a2e4e8909300 78 /// External Flash
Emre.Eken 12:a2e4e8909300 79 S25FS512 s25fs512(&quadSpiInterface);
Emre.Eken 12:a2e4e8909300 80 /// ECG device
Emre.Eken 12:a2e4e8909300 81 MAX30001 max30001(&spi, &cs);
Emre.Eken 12:a2e4e8909300 82 InterruptIn max30001_InterruptB(P5_5);
Emre.Eken 12:a2e4e8909300 83 InterruptIn max30001_Interrupt2B(P5_4);
Emre.Eken 12:a2e4e8909300 84
Emre.Eken 12:a2e4e8909300 85
Emre.Eken 12:a2e4e8909300 86 /// HSP platform LED
Emre.Eken 12:a2e4e8909300 87 HspLed hspLed(LED_RED);
Emre.Eken 12:a2e4e8909300 88 /// Packet TimeStamp Timer, set for 1uS
Emre.Eken 12:a2e4e8909300 89 Timer timestampTimer;
Emre.Eken 12:a2e4e8909300 90 /// HSP Platform push button
Emre.Eken 12:a2e4e8909300 91 PushButton pushButton(SW1);
Emre.Eken 12:a2e4e8909300 92
Emre.Eken 12:a2e4e8909300 93 int main() {
Emre.Eken 12:a2e4e8909300 94
Emre.Eken 12:a2e4e8909300 95 //boost baudrate so we can get messages while running gui
Emre.Eken 12:a2e4e8909300 96 debug.baud(115200);
Emre.Eken 12:a2e4e8909300 97
Emre.Eken 12:a2e4e8909300 98 // local input state of the RPC
Emre.Eken 12:a2e4e8909300 99 int inputState;
Emre.Eken 12:a2e4e8909300 100 // RPC request buffer
Emre.Eken 12:a2e4e8909300 101 char request[128];
Emre.Eken 12:a2e4e8909300 102 // RPC reply buffer
Emre.Eken 12:a2e4e8909300 103 char reply[128];
Emre.Eken 12:a2e4e8909300 104
Emre.Eken 12:a2e4e8909300 105 // display start banner
Emre.Eken 12:a2e4e8909300 106 debug.printf("Maxim Integrated mbed hSensor %d.%d.%d %02d/%02d/%02d\n",
Emre.Eken 12:a2e4e8909300 107 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
Emre.Eken 12:a2e4e8909300 108 VERSION_MONTH, VERSION_DAY, VERSION_SHORT_YEAR);
Emre.Eken 12:a2e4e8909300 109 fflush(stdout);
Emre.Eken 12:a2e4e8909300 110
Emre.Eken 12:a2e4e8909300 111 // turn on red led
Emre.Eken 12:a2e4e8909300 112 debug.printf("Init HSPLED...\n");
Emre.Eken 12:a2e4e8909300 113 fflush(stdout);
Emre.Eken 12:a2e4e8909300 114 hspLed.on();
Emre.Eken 12:a2e4e8909300 115
Emre.Eken 12:a2e4e8909300 116 // set NVIC priorities for GPIO to prevent priority inversion
Emre.Eken 12:a2e4e8909300 117 debug.printf("Init NVIC Priorities...\n");
Emre.Eken 12:a2e4e8909300 118 fflush(stdout);
Emre.Eken 12:a2e4e8909300 119 NVIC_SetPriority(GPIO_P0_IRQn, 5);
Emre.Eken 12:a2e4e8909300 120 NVIC_SetPriority(GPIO_P1_IRQn, 5);
Emre.Eken 12:a2e4e8909300 121 NVIC_SetPriority(GPIO_P2_IRQn, 5);
Emre.Eken 12:a2e4e8909300 122 NVIC_SetPriority(GPIO_P3_IRQn, 5);
Emre.Eken 12:a2e4e8909300 123 NVIC_SetPriority(GPIO_P4_IRQn, 5);
Emre.Eken 12:a2e4e8909300 124 NVIC_SetPriority(GPIO_P5_IRQn, 5);
Emre.Eken 12:a2e4e8909300 125 NVIC_SetPriority(GPIO_P6_IRQn, 5);
Emre.Eken 12:a2e4e8909300 126 // used by the MAX30001
Emre.Eken 12:a2e4e8909300 127 NVIC_SetPriority(SPIM2_IRQn, 0);
Emre.Eken 12:a2e4e8909300 128
Emre.Eken 12:a2e4e8909300 129 // Be able to statically reference these devices anywhere in the application
Emre.Eken 12:a2e4e8909300 130 Peripherals::setS25FS512(&s25fs512);
Emre.Eken 12:a2e4e8909300 131 Peripherals::setUSBSerial(&usbSerial);
Emre.Eken 12:a2e4e8909300 132 Peripherals::setTimestampTimer(&timestampTimer);
Emre.Eken 12:a2e4e8909300 133 Peripherals::setHspLed(&hspLed);
Emre.Eken 12:a2e4e8909300 134 Peripherals::setPushButton(&pushButton);
Emre.Eken 12:a2e4e8909300 135 Peripherals::setMAX30001(&max30001);
Emre.Eken 12:a2e4e8909300 136 Peripherals::setSdFS(&sd);
Emre.Eken 12:a2e4e8909300 137 Peripherals::setSDDetect(&SDDetect);
Emre.Eken 12:a2e4e8909300 138
Emre.Eken 12:a2e4e8909300 139 // init the S25FS256 external flash device
Emre.Eken 12:a2e4e8909300 140 debug.printf("Init S25FS512...\n");
Emre.Eken 12:a2e4e8909300 141 fflush(stdout);
Emre.Eken 12:a2e4e8909300 142 s25fs512.init();
Emre.Eken 12:a2e4e8909300 143
Emre.Eken 12:a2e4e8909300 144 // start blinking led1
Emre.Eken 12:a2e4e8909300 145 debug.printf("Init HSPLED Blink...\n");
Emre.Eken 12:a2e4e8909300 146 fflush(stdout);
Emre.Eken 12:a2e4e8909300 147 hspLed.blink(1000);
Emre.Eken 12:a2e4e8909300 148
Emre.Eken 12:a2e4e8909300 149 //
Emre.Eken 12:a2e4e8909300 150 // MAX30001
Emre.Eken 12:a2e4e8909300 151 //
Emre.Eken 12:a2e4e8909300 152 debug.printf("Init MAX30001 callbacks, interrupts...\n");
Emre.Eken 12:a2e4e8909300 153 fflush(stdout);
Emre.Eken 12:a2e4e8909300 154 max30001_InterruptB.disable_irq();
Emre.Eken 12:a2e4e8909300 155 max30001_Interrupt2B.disable_irq();
Emre.Eken 12:a2e4e8909300 156 max30001_InterruptB.mode(PullUp);
Emre.Eken 12:a2e4e8909300 157 max30001_InterruptB.fall(&MAX30001Mid_IntB_Handler);
Emre.Eken 12:a2e4e8909300 158 max30001_Interrupt2B.mode(PullUp);
Emre.Eken 12:a2e4e8909300 159 max30001_Interrupt2B.fall(&MAX30001Mid_Int2B_Handler);
Emre.Eken 12:a2e4e8909300 160 max30001_InterruptB.enable_irq();
Emre.Eken 12:a2e4e8909300 161 max30001_Interrupt2B.enable_irq();
Emre.Eken 12:a2e4e8909300 162 MAX30001_AllowInterrupts(1);
Emre.Eken 12:a2e4e8909300 163 max30001.max30001_sw_rst(); // Do a software reset of the MAX30001
Emre.Eken 12:a2e4e8909300 164 max30001.max30001_INT_assignment(MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_enint_loc, en_eovf_loc, en_fstint_loc,
Emre.Eken 12:a2e4e8909300 165 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_dcloffint_loc, en_bint_loc, en_bovf_loc,
Emre.Eken 12:a2e4e8909300 166 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_bover_loc, en_bundr_loc, en_bcgmon_loc,
Emre.Eken 12:a2e4e8909300 167 MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_pint_loc, en_povf_loc, en_pedge_loc,
Emre.Eken 12:a2e4e8909300 168 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, // en_lonint_loc, en_rrint_loc, en_samp_loc,
Emre.Eken 12:a2e4e8909300 169 MAX30001::MAX30001_INT_ODNR, MAX30001::MAX30001_INT_ODNR); // intb_Type, int2b_Type)
Emre.Eken 12:a2e4e8909300 170 max30001.onDataAvailable(&StreamPacketUint32);
Emre.Eken 12:a2e4e8909300 171
Emre.Eken 12:a2e4e8909300 172 // initialize the RPC server
Emre.Eken 12:a2e4e8909300 173 debug.printf("Init RPC Server...\n");
Emre.Eken 12:a2e4e8909300 174 fflush(stdout);
Emre.Eken 12:a2e4e8909300 175 RPC_init();
Emre.Eken 12:a2e4e8909300 176 // initialize the logging service
Emre.Eken 12:a2e4e8909300 177 debug.printf("Init LoggingService...\n");
Emre.Eken 12:a2e4e8909300 178 fflush(stdout);
Emre.Eken 12:a2e4e8909300 179 LoggingService_Init();
Emre.Eken 12:a2e4e8909300 180 // initialize the SD disk
Emre.Eken 12:a2e4e8909300 181 sd.disk_initialize();
Emre.Eken 12:a2e4e8909300 182
Emre.Eken 12:a2e4e8909300 183 // start main loop
Emre.Eken 12:a2e4e8909300 184 debug.printf("Start main loop...\n");
Emre.Eken 12:a2e4e8909300 185 fflush(stdout);
Emre.Eken 12:a2e4e8909300 186
Emre.Eken 12:a2e4e8909300 187 while (1)
Emre.Eken 12:a2e4e8909300 188 {
Emre.Eken 12:a2e4e8909300 189 // get a RPC string if one is available
Emre.Eken 12:a2e4e8909300 190 inputState = getLine(request, sizeof(request));
Emre.Eken 12:a2e4e8909300 191 // if a string has been captured, process string
Emre.Eken 12:a2e4e8909300 192 if (inputState == GETLINE_DONE)
Emre.Eken 12:a2e4e8909300 193 {
Emre.Eken 12:a2e4e8909300 194 //Send request to debug port
Emre.Eken 12:a2e4e8909300 195 debug.printf(request);
Emre.Eken 12:a2e4e8909300 196 // process the RPC string
Emre.Eken 12:a2e4e8909300 197 RPC_call(request, reply);
Emre.Eken 12:a2e4e8909300 198 //Send reply to debug port
Emre.Eken 12:a2e4e8909300 199 debug.printf(reply);
Emre.Eken 12:a2e4e8909300 200 // output the reply
Emre.Eken 12:a2e4e8909300 201 putStr(reply);
Emre.Eken 12:a2e4e8909300 202 }
Emre.Eken 12:a2e4e8909300 203
Emre.Eken 12:a2e4e8909300 204 // process any logging or streaming requests
Emre.Eken 12:a2e4e8909300 205 LoggingService_ServiceRoutine();
Emre.Eken 12:a2e4e8909300 206 }
Emre.Eken 12:a2e4e8909300 207 }
Emre.Eken 12:a2e4e8909300 208