MAX32620HSP ECG with lead off detection
Dependencies: mbed HSP_ECG MAX14720 USBDevice
main.cpp@0:9ead5978d784, 2019-03-28 (annotated)
- Committer:
- douqan93
- Date:
- Thu Mar 28 08:10:23 2019 +0000
- Revision:
- 0:9ead5978d784
- Child:
- 1:8b09f627a713
MAX32620HSP raw ECG data on serial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
douqan93 | 0:9ead5978d784 | 1 | #include "mbed.h" |
douqan93 | 0:9ead5978d784 | 2 | #include "MAX14720.h" |
douqan93 | 0:9ead5978d784 | 3 | #include "MAX30001.h" |
douqan93 | 0:9ead5978d784 | 4 | #include "MAX30101.h" |
douqan93 | 0:9ead5978d784 | 5 | #include "System.h" |
douqan93 | 0:9ead5978d784 | 6 | #include "USBSerial.h" |
douqan93 | 0:9ead5978d784 | 7 | |
douqan93 | 0:9ead5978d784 | 8 | /************************************************************************************************************************************/ |
douqan93 | 0:9ead5978d784 | 9 | /// define the HVOUT Boost Voltage default for the MAX14720 PMIC |
douqan93 | 0:9ead5978d784 | 10 | #define HVOUT_VOLTAGE 4500 // set to 4500 mV |
douqan93 | 0:9ead5978d784 | 11 | |
douqan93 | 0:9ead5978d784 | 12 | /// define all I2C addresses |
douqan93 | 0:9ead5978d784 | 13 | #define MAX14720_I2C_SLAVE_ADDR (0x54) |
douqan93 | 0:9ead5978d784 | 14 | #define MAX30101_I2C_SLAVE_ADDR (0xAE) |
douqan93 | 0:9ead5978d784 | 15 | |
douqan93 | 0:9ead5978d784 | 16 | // Settings for ECG Initialization |
douqan93 | 0:9ead5978d784 | 17 | #define En_ecg 0x01 |
douqan93 | 0:9ead5978d784 | 18 | #define Openp 0x00 |
douqan93 | 0:9ead5978d784 | 19 | #define Openn 0x00 |
douqan93 | 0:9ead5978d784 | 20 | #define Pol 0x00 |
douqan93 | 0:9ead5978d784 | 21 | #define Calp_sel 0x00 |
douqan93 | 0:9ead5978d784 | 22 | #define Caln_sel 0x00 |
douqan93 | 0:9ead5978d784 | 23 | #define E_fit 0x0F |
douqan93 | 0:9ead5978d784 | 24 | #define Rate 0x02 |
douqan93 | 0:9ead5978d784 | 25 | #define Gain 0x00 |
douqan93 | 0:9ead5978d784 | 26 | #define Dhpf 0x01 |
douqan93 | 0:9ead5978d784 | 27 | #define Dlpf 0x01 |
douqan93 | 0:9ead5978d784 | 28 | |
douqan93 | 0:9ead5978d784 | 29 | // Settings for ECG RtoR |
douqan93 | 0:9ead5978d784 | 30 | #define En_rtor 0x01 |
douqan93 | 0:9ead5978d784 | 31 | #define Wndw 0x03 |
douqan93 | 0:9ead5978d784 | 32 | #define Gain1 0x0f |
douqan93 | 0:9ead5978d784 | 33 | #define Pavg 0x02 |
douqan93 | 0:9ead5978d784 | 34 | #define Ptsf 0x03 |
douqan93 | 0:9ead5978d784 | 35 | #define Hoff 0x20 |
douqan93 | 0:9ead5978d784 | 36 | #define Ravg 0x02 |
douqan93 | 0:9ead5978d784 | 37 | #define Rhsf 0x04 |
douqan93 | 0:9ead5978d784 | 38 | #define Clr_rrint 0x01 |
douqan93 | 0:9ead5978d784 | 39 | |
douqan93 | 0:9ead5978d784 | 40 | // Settings for Lead Detection |
douqan93 | 0:9ead5978d784 | 41 | #define En_dcloff 0x01 |
douqan93 | 0:9ead5978d784 | 42 | #define Ipol 0x00 |
douqan93 | 0:9ead5978d784 | 43 | #define Imag 0x00 |
douqan93 | 0:9ead5978d784 | 44 | #define Vth 0x00 |
douqan93 | 0:9ead5978d784 | 45 | |
douqan93 | 0:9ead5978d784 | 46 | // Settings for the HR initialization |
douqan93 | 0:9ead5978d784 | 47 | #define FIFO_WATERLEVEL_MARK 15 |
douqan93 | 0:9ead5978d784 | 48 | #define SAMPLE_AVG 2 |
douqan93 | 0:9ead5978d784 | 49 | #define SAMPLE_RATE 1 |
douqan93 | 0:9ead5978d784 | 50 | #define PULSE_WIDTH 2 |
douqan93 | 0:9ead5978d784 | 51 | #define RED_LED_CURRENT 0x1F |
douqan93 | 0:9ead5978d784 | 52 | #define IR_LED_CURRENT 0X1F |
douqan93 | 0:9ead5978d784 | 53 | |
douqan93 | 0:9ead5978d784 | 54 | /// Define with Maxim VID and a Maxim assigned PID, set to version 0x0001 and non-blocking |
douqan93 | 0:9ead5978d784 | 55 | USBSerial usbSerial(0x0b6a, 0x0100, 0x0001, false); |
douqan93 | 0:9ead5978d784 | 56 | |
douqan93 | 0:9ead5978d784 | 57 | // I2C Master 2 |
douqan93 | 0:9ead5978d784 | 58 | I2C i2c2(I2C2_SDA, I2C2_SCL); // used by MAX14720, MAX30101, LIS2DH |
douqan93 | 0:9ead5978d784 | 59 | |
douqan93 | 0:9ead5978d784 | 60 | // SPI Master 0 with SPI0_SS for use with MAX30001 |
douqan93 | 0:9ead5978d784 | 61 | SPI spi(SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS); // used by MAX30001 |
douqan93 | 0:9ead5978d784 | 62 | |
douqan93 | 0:9ead5978d784 | 63 | // PMIC |
douqan93 | 0:9ead5978d784 | 64 | MAX14720 max14720(&i2c2, MAX14720_I2C_SLAVE_ADDR); |
douqan93 | 0:9ead5978d784 | 65 | |
douqan93 | 0:9ead5978d784 | 66 | // Optical Oximeter |
douqan93 | 0:9ead5978d784 | 67 | //MAX30101 max30101(&i2c2, MAX30101_I2C_SLAVE_ADDR); |
douqan93 | 0:9ead5978d784 | 68 | //InterruptIn max30101_Interrupt(P4_0); |
douqan93 | 0:9ead5978d784 | 69 | |
douqan93 | 0:9ead5978d784 | 70 | // ECG device |
douqan93 | 0:9ead5978d784 | 71 | MAX30001 max30001(&spi); |
douqan93 | 0:9ead5978d784 | 72 | InterruptIn max30001_InterruptB(P3_6); |
douqan93 | 0:9ead5978d784 | 73 | InterruptIn max30001_Interrupt2B(P4_5); |
douqan93 | 0:9ead5978d784 | 74 | |
douqan93 | 0:9ead5978d784 | 75 | /// PWM used as fclk for the MAX30001 |
douqan93 | 0:9ead5978d784 | 76 | PwmOut pwmout(P1_7); |
douqan93 | 0:9ead5978d784 | 77 | |
douqan93 | 0:9ead5978d784 | 78 | // Data of sensors |
douqan93 | 0:9ead5978d784 | 79 | int32_t ECG_Raw; |
douqan93 | 0:9ead5978d784 | 80 | //int32_t SpO_Raw; |
douqan93 | 0:9ead5978d784 | 81 | uint32_t index = 0; |
douqan93 | 0:9ead5978d784 | 82 | DigitalOut led(LED1); |
douqan93 | 0:9ead5978d784 | 83 | |
douqan93 | 0:9ead5978d784 | 84 | //@brief Creates a packet that will be streamed via USB Serial |
douqan93 | 0:9ead5978d784 | 85 | //@brief the packet created will be inserted into a fifo to be streamed at a later time |
douqan93 | 0:9ead5978d784 | 86 | //@param id Streaming ID |
douqan93 | 0:9ead5978d784 | 87 | //@param buffer Pointer to a uint32 array that contains the data to include in the packet |
douqan93 | 0:9ead5978d784 | 88 | //@param number Number of elements in the buffer |
douqan93 | 0:9ead5978d784 | 89 | // |
douqan93 | 0:9ead5978d784 | 90 | void StreamPacketUint32_ex(uint32_t id, uint32_t *buffer, uint32_t number) { |
douqan93 | 0:9ead5978d784 | 91 | int k; |
douqan93 | 0:9ead5978d784 | 92 | if(id == MAX30001_DATA_ECG) |
douqan93 | 0:9ead5978d784 | 93 | { |
douqan93 | 0:9ead5978d784 | 94 | for (k = 0; k < number; k++) |
douqan93 | 0:9ead5978d784 | 95 | { |
douqan93 | 0:9ead5978d784 | 96 | ECG_Raw = (int32_t)(buffer[k] << 8); |
douqan93 | 0:9ead5978d784 | 97 | ECG_Raw = ECG_Raw >> 14; |
douqan93 | 0:9ead5978d784 | 98 | usbSerial.printf("%d|" , index); |
douqan93 | 0:9ead5978d784 | 99 | usbSerial.printf("%d\r\n", ECG_Raw); |
douqan93 | 0:9ead5978d784 | 100 | index++; |
douqan93 | 0:9ead5978d784 | 101 | } |
douqan93 | 0:9ead5978d784 | 102 | } |
douqan93 | 0:9ead5978d784 | 103 | } |
douqan93 | 0:9ead5978d784 | 104 | /*void StreamPacketUint32_ex(uint32_t id, uint32_t *buffer, uint32_t number) { |
douqan93 | 0:9ead5978d784 | 105 | int i; |
douqan93 | 0:9ead5978d784 | 106 | if(id == MAX30101_OXIMETER_DATA + 2) |
douqan93 | 0:9ead5978d784 | 107 | { |
douqan93 | 0:9ead5978d784 | 108 | for (i = 0; i < number; i++) |
douqan93 | 0:9ead5978d784 | 109 | { |
douqan93 | 0:9ead5978d784 | 110 | SpO_Raw = (int32_t)(buffer[i]); |
douqan93 | 0:9ead5978d784 | 111 | } |
douqan93 | 0:9ead5978d784 | 112 | usbSerial.printf("%d\r\n", SpO_Raw); |
douqan93 | 0:9ead5978d784 | 113 | } |
douqan93 | 0:9ead5978d784 | 114 | }*/ |
douqan93 | 0:9ead5978d784 | 115 | //****************************************************************************** |
douqan93 | 0:9ead5978d784 | 116 | /*void MAX30101_OnInterrupt(void){ |
douqan93 | 0:9ead5978d784 | 117 | I2CM_Init_Reset(2, 1); |
douqan93 | 0:9ead5978d784 | 118 | }*/ |
douqan93 | 0:9ead5978d784 | 119 | //******************************************************************************* |
douqan93 | 0:9ead5978d784 | 120 | int main() { |
douqan93 | 0:9ead5978d784 | 121 | // hold results for returning functions |
douqan93 | 0:9ead5978d784 | 122 | int result; |
douqan93 | 0:9ead5978d784 | 123 | |
douqan93 | 0:9ead5978d784 | 124 | // initialize HVOUT on the MAX14720 PMIC |
douqan93 | 0:9ead5978d784 | 125 | result = max14720.init(); |
douqan93 | 0:9ead5978d784 | 126 | if (result == MAX14720_ERROR){ |
douqan93 | 0:9ead5978d784 | 127 | printf("Error initializing MAX14720"); |
douqan93 | 0:9ead5978d784 | 128 | } |
douqan93 | 0:9ead5978d784 | 129 | max14720.boostEn = MAX14720::BOOST_ENABLED; |
douqan93 | 0:9ead5978d784 | 130 | max14720.boostSetVoltage(HVOUT_VOLTAGE); |
douqan93 | 0:9ead5978d784 | 131 | |
douqan93 | 0:9ead5978d784 | 132 | |
douqan93 | 0:9ead5978d784 | 133 | // This is the SpO2 mode (IR&Red LED) |
douqan93 | 0:9ead5978d784 | 134 | /*max30101.SpO2mode_init(FIFO_WATERLEVEL_MARK, SAMPLE_AVG, SAMPLE_RATE,PULSE_WIDTH, RED_LED_CURRENT,IR_LED_CURRENT); |
douqan93 | 0:9ead5978d784 | 135 | |
douqan93 | 0:9ead5978d784 | 136 | // MAX30101 initialize interrupt |
douqan93 | 0:9ead5978d784 | 137 | max30101.onInterrupt(&MAX30101_OnInterrupt); |
douqan93 | 0:9ead5978d784 | 138 | max30101.onDataAvailable(&StreamPacketUint32_ex); |
douqan93 | 0:9ead5978d784 | 139 | max30101_Interrupt.fall(&MAX30101MidIntHandler);*/ |
douqan93 | 0:9ead5978d784 | 140 | |
douqan93 | 0:9ead5978d784 | 141 | // Interrupt priority |
douqan93 | 0:9ead5978d784 | 142 | NVIC_SetPriority(GPIO_P0_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 143 | NVIC_SetPriority(GPIO_P1_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 144 | NVIC_SetPriority(GPIO_P2_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 145 | NVIC_SetPriority(GPIO_P3_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 146 | NVIC_SetPriority(GPIO_P4_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 147 | NVIC_SetPriority(GPIO_P5_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 148 | NVIC_SetPriority(GPIO_P6_IRQn, 5); |
douqan93 | 0:9ead5978d784 | 149 | // used by the MAX30001 |
douqan93 | 0:9ead5978d784 | 150 | NVIC_SetPriority(SPI1_IRQn, 0); |
douqan93 | 0:9ead5978d784 | 151 | |
douqan93 | 0:9ead5978d784 | 152 | /* ECG Initialize */ |
douqan93 | 0:9ead5978d784 | 153 | max30001_InterruptB.disable_irq(); |
douqan93 | 0:9ead5978d784 | 154 | max30001_Interrupt2B.disable_irq(); |
douqan93 | 0:9ead5978d784 | 155 | max30001_InterruptB.mode(PullUp); |
douqan93 | 0:9ead5978d784 | 156 | max30001_InterruptB.fall(&MAX30001Mid_IntB_Handler); |
douqan93 | 0:9ead5978d784 | 157 | max30001_Interrupt2B.mode(PullUp); |
douqan93 | 0:9ead5978d784 | 158 | max30001_Interrupt2B.fall(&MAX30001Mid_Int2B_Handler); |
douqan93 | 0:9ead5978d784 | 159 | max30001_InterruptB.enable_irq(); |
douqan93 | 0:9ead5978d784 | 160 | max30001_Interrupt2B.enable_irq(); |
douqan93 | 0:9ead5978d784 | 161 | MAX30001_AllowInterrupts(1); |
douqan93 | 0:9ead5978d784 | 162 | // Configuring the FCLK for the ECG, set to 32.768KHZ |
douqan93 | 0:9ead5978d784 | 163 | pwmout.period_us(31); |
douqan93 | 0:9ead5978d784 | 164 | pwmout.write(0.5); // 0-1 is 0-100%, 0.5 = 50% duty cycle. |
douqan93 | 0:9ead5978d784 | 165 | //max30001.max30001_RtoR_InitStart(En_rtor, Wndw, Gain1, Pavg, Ptsf, Hoff, Ravg, Rhsf, Clr_rrint); |
douqan93 | 0:9ead5978d784 | 166 | max30001.max30001_sw_rst(); // Do a software reset of the MAX30001 |
douqan93 | 0:9ead5978d784 | 167 | max30001.max30001_INT_assignment( |
douqan93 | 0:9ead5978d784 | 168 | MAX30001::MAX30001_INT_B, // en_enint_loc |
douqan93 | 0:9ead5978d784 | 169 | MAX30001::MAX30001_NO_INT, // en_eovf_loc |
douqan93 | 0:9ead5978d784 | 170 | MAX30001::MAX30001_NO_INT, // en_fstint_loc |
douqan93 | 0:9ead5978d784 | 171 | |
douqan93 | 0:9ead5978d784 | 172 | MAX30001::MAX30001_INT_2B, // en_dcloffint_loc |
douqan93 | 0:9ead5978d784 | 173 | MAX30001::MAX30001_INT_B, // en_bint_loc |
douqan93 | 0:9ead5978d784 | 174 | MAX30001::MAX30001_NO_INT, // en_bovf_loc |
douqan93 | 0:9ead5978d784 | 175 | |
douqan93 | 0:9ead5978d784 | 176 | MAX30001::MAX30001_INT_2B, // en_bover_loc |
douqan93 | 0:9ead5978d784 | 177 | MAX30001::MAX30001_INT_2B, // en_bundr_loc |
douqan93 | 0:9ead5978d784 | 178 | MAX30001::MAX30001_NO_INT, // en_bcgmon_loc |
douqan93 | 0:9ead5978d784 | 179 | |
douqan93 | 0:9ead5978d784 | 180 | MAX30001::MAX30001_INT_B, // en_pint_loc |
douqan93 | 0:9ead5978d784 | 181 | MAX30001::MAX30001_NO_INT, // en_povf_loc, |
douqan93 | 0:9ead5978d784 | 182 | MAX30001::MAX30001_NO_INT, // en_pedge_loc |
douqan93 | 0:9ead5978d784 | 183 | |
douqan93 | 0:9ead5978d784 | 184 | MAX30001::MAX30001_INT_2B, // en_lonint_loc |
douqan93 | 0:9ead5978d784 | 185 | MAX30001::MAX30001_INT_B, // en_rrint_loc |
douqan93 | 0:9ead5978d784 | 186 | MAX30001::MAX30001_NO_INT, // en_samp_loc |
douqan93 | 0:9ead5978d784 | 187 | |
douqan93 | 0:9ead5978d784 | 188 | MAX30001::MAX30001_INT_ODNR, // intb_Type |
douqan93 | 0:9ead5978d784 | 189 | MAX30001::MAX30001_INT_ODNR); // int2b_Type |
douqan93 | 0:9ead5978d784 | 190 | |
douqan93 | 0:9ead5978d784 | 191 | // MAX30001 initialize interrupt |
douqan93 | 0:9ead5978d784 | 192 | max30001.max30001_ECG_InitStart(En_ecg, Openp, Openn, Pol, Calp_sel, Caln_sel, E_fit, Rate, Gain, Dhpf, Dlpf); |
douqan93 | 0:9ead5978d784 | 193 | //max30001.max30001_Enable_DcLeadOFF_Init(En_dcloff, Ipol, Imag, Vth); |
douqan93 | 0:9ead5978d784 | 194 | //max30001.max30001_FIFO_LeadONOff_Read(); |
douqan93 | 0:9ead5978d784 | 195 | max30001.max30001_synch(); |
douqan93 | 0:9ead5978d784 | 196 | max30001.onDataAvailable(&StreamPacketUint32_ex); |
douqan93 | 0:9ead5978d784 | 197 | int a; |
douqan93 | 0:9ead5978d784 | 198 | while (1) |
douqan93 | 0:9ead5978d784 | 199 | { |
douqan93 | 0:9ead5978d784 | 200 | a = usbSerial._getc(); |
douqan93 | 0:9ead5978d784 | 201 | if (a == 65) |
douqan93 | 0:9ead5978d784 | 202 | { |
douqan93 | 0:9ead5978d784 | 203 | max30001.max30001_Stop_ECG(); |
douqan93 | 0:9ead5978d784 | 204 | index = 0; |
douqan93 | 0:9ead5978d784 | 205 | } |
douqan93 | 0:9ead5978d784 | 206 | if (a == 97) |
douqan93 | 0:9ead5978d784 | 207 | { |
douqan93 | 0:9ead5978d784 | 208 | //max30001.max30001_sw_rst(); |
douqan93 | 0:9ead5978d784 | 209 | max30001.max30001_ECG_InitStart(En_ecg, Openp, Openn, Pol, Calp_sel, Caln_sel, E_fit, Rate, Gain, Dhpf, Dlpf); |
douqan93 | 0:9ead5978d784 | 210 | //max30001.max30001_synch(); |
douqan93 | 0:9ead5978d784 | 211 | //max30001.onDataAvailable(&StreamPacketUint32_ex); |
douqan93 | 0:9ead5978d784 | 212 | } |
douqan93 | 0:9ead5978d784 | 213 | } |
douqan93 | 0:9ead5978d784 | 214 | } |
douqan93 | 0:9ead5978d784 | 215 |