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:
Thu Apr 12 13:38:23 2018 +0300
Revision:
1:4e530e89b68f
main.cpp path is changed

Who changed what in which revision?

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