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:
Fri Apr 13 15:44:58 2018 +0300
Revision:
5:3e44c4c7a9ec
Parent:
4:10d2c2a56c2a
Child:
11:1dde68750ed1
MAX30001EVSYS.lib is added and all the files except main.cpp and version.h are put inside it.

Who changed what in which revision?

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