Test program for MAX30101 Barely working.

Dependencies:   MAX30101 mbed vt100

Committer:
Rhyme
Date:
Fri May 12 00:15:20 2017 +0000
Revision:
4:4b1763d399a0
Parent:
3:f3d19ad49aee
Document cleaned up a little

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rhyme 0:74347dd8a032 1 #include "mbed.h"
Rhyme 0:74347dd8a032 2 #include "vt100.h"
Rhyme 0:74347dd8a032 3 #include "MSS.h"
Rhyme 0:74347dd8a032 4 #include "MAX30101.h"
Rhyme 0:74347dd8a032 5 /**
Rhyme 0:74347dd8a032 6 * MAX30101 I2C addresss
Rhyme 0:74347dd8a032 7 * Write 0xAE 0b1010_1110
Rhyme 0:74347dd8a032 8 * Read 0xAF 0b1010_1111
Rhyme 0:74347dd8a032 9 * 7bit address = 0b101_0111 = 0x57
Rhyme 0:74347dd8a032 10 */
Rhyme 0:74347dd8a032 11 #define MAX30101_I2C_ADDRESS (0x57)
Rhyme 0:74347dd8a032 12
Rhyme 0:74347dd8a032 13 #ifndef FIFO_DEPTH
Rhyme 0:74347dd8a032 14 #define FIFO_DEPTH 32
Rhyme 0:74347dd8a032 15 #endif
Rhyme 0:74347dd8a032 16
Rhyme 0:74347dd8a032 17 vt100 *tty = 0 ;
Rhyme 0:74347dd8a032 18 MAX30101 *max30101 = 0 ;
Rhyme 0:74347dd8a032 19 InterruptIn *int0 ;
Rhyme 0:74347dd8a032 20
Rhyme 3:f3d19ad49aee 21 /* data read test following the pseudo code
Rhyme 3:f3d19ad49aee 22 * written in the datasheet
Rhyme 3:f3d19ad49aee 23 */
Rhyme 3:f3d19ad49aee 24 void doPseudo(void)
Rhyme 3:f3d19ad49aee 25 {
Rhyme 3:f3d19ad49aee 26 uint32_t data[3] ;
Rhyme 3:f3d19ad49aee 27 uint8_t fifo_wr_ptr, fifo_rd_ptr ;
Rhyme 3:f3d19ad49aee 28 int num_available_samples = 0 ;
Rhyme 3:f3d19ad49aee 29 // int num_samples_to_read = 0 ;
Rhyme 3:f3d19ad49aee 30 int i ;
Rhyme 3:f3d19ad49aee 31
Rhyme 3:f3d19ad49aee 32 fifo_wr_ptr = max30101->getFIFO_WR_PTR() ;
Rhyme 3:f3d19ad49aee 33 fifo_rd_ptr = max30101->getFIFO_RD_PTR() ;
Rhyme 3:f3d19ad49aee 34 num_available_samples = (fifo_wr_ptr + FIFO_DEPTH - fifo_rd_ptr) % FIFO_DEPTH ;
Rhyme 3:f3d19ad49aee 35 printf("=== %d data ===\n", num_available_samples) ;
Rhyme 3:f3d19ad49aee 36 for (i = 0 ; i < num_available_samples ; i++ ) {
Rhyme 3:f3d19ad49aee 37 data[0] = max30101->readFIFO() ; /* LED1 */
Rhyme 3:f3d19ad49aee 38 data[1] = max30101->readFIFO() ; /* LED2 */
Rhyme 3:f3d19ad49aee 39 data[2] = max30101->readFIFO() ; /* LED3 */
Rhyme 3:f3d19ad49aee 40 printf("LED1: 0x%05X, LED2: 0x%05X, LED3: 0x%05X\n",
Rhyme 3:f3d19ad49aee 41 data[0], data[1], data[2]) ;
Rhyme 3:f3d19ad49aee 42 }
Rhyme 3:f3d19ad49aee 43 }
Rhyme 3:f3d19ad49aee 44
Rhyme 0:74347dd8a032 45 void initSPO2(void)
Rhyme 0:74347dd8a032 46 {
Rhyme 0:74347dd8a032 47 uint8_t config_byte = 0 ;
Rhyme 0:74347dd8a032 48 uint16_t slot_config = 0 ;
Rhyme 0:74347dd8a032 49
Rhyme 0:74347dd8a032 50 /* config for SPO2 (0x0A) */
Rhyme 0:74347dd8a032 51 config_byte =
Rhyme 0:74347dd8a032 52 (0x01 << 5) /* SPO2_ADC_RGE */
Rhyme 0:74347dd8a032 53 // | (0x05 << 3) /* SPO2_SR 101 = 1000 samples/sec */
Rhyme 0:74347dd8a032 54 | (0x00 << 3) /* SPO2_SR 000 = 50 samples/sec */
Rhyme 0:74347dd8a032 55 | (0x00) /* LED_PW 00 = 69us */
Rhyme 0:74347dd8a032 56 ;
Rhyme 0:74347dd8a032 57 max30101->setSPO2_CONFIG(config_byte) ;
Rhyme 0:74347dd8a032 58
Rhyme 0:74347dd8a032 59 /* slot configuration */
Rhyme 0:74347dd8a032 60 slot_config =
Rhyme 0:74347dd8a032 61 (0x02 << 12) /* SLOT2 LED2(IR) */
Rhyme 0:74347dd8a032 62 | (0x01 << 8) /* SLOT1 LED1(RED) */
Rhyme 0:74347dd8a032 63 | (0x00 << 4) /* SLOT4 none */
Rhyme 0:74347dd8a032 64 | (0x00) /* SLOT3 none */
Rhyme 0:74347dd8a032 65 ;
Rhyme 0:74347dd8a032 66 max30101->setSLOT(slot_config) ;
Rhyme 0:74347dd8a032 67
Rhyme 0:74347dd8a032 68 /* Inititalize FIFO */
Rhyme 0:74347dd8a032 69 /* config for FIFO Configuration (0x08) */
Rhyme 0:74347dd8a032 70 config_byte =
Rhyme 0:74347dd8a032 71 (0x02 << 5) /* SMP_AVE = 2 -> avarage of 4 data */
Rhyme 0:74347dd8a032 72 | (0x01 << 4) /* FIFO_ROLLOVER_EN = 1 */
Rhyme 0:74347dd8a032 73 // | (0x0C) /* FIFO ALMOST FULL at 12 (0x0C) */
Rhyme 0:74347dd8a032 74 | (0x09) /* FIFO ALMOST FULL at 9 */
Rhyme 0:74347dd8a032 75 ;
Rhyme 0:74347dd8a032 76 max30101->setFIFO_CONFIG(config_byte) ;
Rhyme 0:74347dd8a032 77
Rhyme 0:74347dd8a032 78
Rhyme 0:74347dd8a032 79 }
Rhyme 0:74347dd8a032 80
Rhyme 0:74347dd8a032 81 void readSPO2_FIFO(void)
Rhyme 0:74347dd8a032 82 {
Rhyme 0:74347dd8a032 83 uint32_t data[2] ;
Rhyme 0:74347dd8a032 84 uint8_t fifo_wr_ptr, fifo_rd_ptr ;
Rhyme 0:74347dd8a032 85 int num_available_samples = 0 ;
Rhyme 0:74347dd8a032 86 int num_samples_to_read = 6 ;
Rhyme 0:74347dd8a032 87 int i ;
Rhyme 0:74347dd8a032 88
Rhyme 0:74347dd8a032 89 fifo_wr_ptr = max30101->getFIFO_WR_PTR() ;
Rhyme 0:74347dd8a032 90 fifo_rd_ptr = max30101->getFIFO_RD_PTR() ;
Rhyme 0:74347dd8a032 91 num_available_samples = (fifo_wr_ptr + FIFO_DEPTH - fifo_rd_ptr) % FIFO_DEPTH ;
Rhyme 0:74347dd8a032 92
Rhyme 0:74347dd8a032 93 if (num_available_samples < num_samples_to_read) {
Rhyme 0:74347dd8a032 94 num_samples_to_read = num_available_samples / 2 ;
Rhyme 0:74347dd8a032 95 } else {
Rhyme 0:74347dd8a032 96 num_samples_to_read = num_available_samples ;
Rhyme 0:74347dd8a032 97 }
Rhyme 0:74347dd8a032 98 printf("=== %d data %d to read===\n",
Rhyme 0:74347dd8a032 99 num_available_samples, num_samples_to_read) ;
Rhyme 0:74347dd8a032 100 for (i = 0 ; i < num_samples_to_read ; i++ ) {
Rhyme 0:74347dd8a032 101 data[0] = max30101->readFIFO() ; /* LED1 */
Rhyme 0:74347dd8a032 102 data[1] = max30101->readFIFO() ; /* IR */
Rhyme 0:74347dd8a032 103 // printf("LED1: 0x%05X, IR: 0x%05X\n", data[0], data[1]) ;
Rhyme 0:74347dd8a032 104 }
Rhyme 0:74347dd8a032 105 // max30101->setFIFO_WR_PTR(0) ;
Rhyme 0:74347dd8a032 106 // max30101->setFIFO_RD_PTR(0) ;
Rhyme 0:74347dd8a032 107 }
Rhyme 0:74347dd8a032 108
Rhyme 0:74347dd8a032 109 void SPO2_isr(void)
Rhyme 0:74347dd8a032 110 {
Rhyme 0:74347dd8a032 111 uint16_t flag, config ;
Rhyme 0:74347dd8a032 112 float temp ;
Rhyme 0:74347dd8a032 113 int temp_int, temp_frac ;
Rhyme 0:74347dd8a032 114
Rhyme 0:74347dd8a032 115 flag = max30101->getIntStatus() ;
Rhyme 0:74347dd8a032 116 config = max30101->getIntEnable() ;
Rhyme 0:74347dd8a032 117 // printf("Int: 0x%04X Enable: 0x%04X\n", flag, config) ;
Rhyme 0:74347dd8a032 118 if (flag & INT_ST_A_FULL) { /* A_FULL_EN */
Rhyme 0:74347dd8a032 119 // printf("FIFO almost full!\n") ;
Rhyme 0:74347dd8a032 120 readSPO2_FIFO() ;
Rhyme 0:74347dd8a032 121 }
Rhyme 0:74347dd8a032 122 if (flag & INT_ST_PPG_RGY) { /* New FIFO Data Ready */
Rhyme 0:74347dd8a032 123 printf("New FIFO Data Ready\n") ;
Rhyme 3:f3d19ad49aee 124 doPseudo() ;
Rhyme 0:74347dd8a032 125 }
Rhyme 0:74347dd8a032 126 if (flag & INT_ST_ALC_OVF) { /* Ambient Light Cancellaration Overflow */
Rhyme 0:74347dd8a032 127 printf("Ambient Light Cancellaration Overflow\n") ;
Rhyme 0:74347dd8a032 128 }
Rhyme 0:74347dd8a032 129 if (flag & INT_ST_PROX_INT) {/* Proximity Threshold Triggered */
Rhyme 0:74347dd8a032 130 printf("Proximity Threshold Triggered\n") ;
Rhyme 0:74347dd8a032 131 }
Rhyme 0:74347dd8a032 132 if (flag & INT_ST_PWR_RDY) {/* Power Ready Flag */
Rhyme 0:74347dd8a032 133 printf("Power Ready!\n") ;
Rhyme 0:74347dd8a032 134 }
Rhyme 0:74347dd8a032 135 if (flag & INT_ST_DIE_TEMP_RDY) {/* Internal Temperature Ready Flag */
Rhyme 0:74347dd8a032 136 printf("DIE Temperature Ready!\n") ;
Rhyme 0:74347dd8a032 137 temp_int = max30101->getTEMP_INT() ;
Rhyme 0:74347dd8a032 138 temp_frac = max30101->getTEMP_FRAC() ;
Rhyme 0:74347dd8a032 139 temp = ((float)temp_int)+(((float)temp_frac)/16.0) ;
Rhyme 0:74347dd8a032 140 printf("Temp: %.2f\n", temp) ;
Rhyme 0:74347dd8a032 141 }
Rhyme 0:74347dd8a032 142 }
Rhyme 0:74347dd8a032 143
Rhyme 0:74347dd8a032 144 void doSPO2(void)
Rhyme 0:74347dd8a032 145 {
Rhyme 0:74347dd8a032 146 uint8_t config_byte = 0 ;
Rhyme 0:74347dd8a032 147 uint16_t slot_config = 0 ;
Rhyme 0:74347dd8a032 148 uint16_t init_config = 0 ;
Rhyme 0:74347dd8a032 149
Rhyme 0:74347dd8a032 150 int0->fall(&SPO2_isr) ;
Rhyme 0:74347dd8a032 151 /* Enter into SpO2 Mode. Initiate a Temperature measurement */
Rhyme 0:74347dd8a032 152 /* I2C Write Command sets MODE[2:0] = 0x03 */
Rhyme 0:74347dd8a032 153 config_byte = 0x03 ; /* SpO2 mode */
Rhyme 0:74347dd8a032 154 max30101->setMODE_CONFIG(config_byte) ;
Rhyme 0:74347dd8a032 155
Rhyme 0:74347dd8a032 156 /* Mask the SPO2_RDY Interrupt */
Rhyme 0:74347dd8a032 157 /* Temperature Measurement Complete, Interrupt Generated */
Rhyme 0:74347dd8a032 158 /* TEMP_RDY interrupt triggers */
Rhyme 0:74347dd8a032 159 /* alerting the central to read the data */
Rhyme 0:74347dd8a032 160 /* Temp Data is Read, Interrupt Cleared */
Rhyme 0:74347dd8a032 161 /* FIFO is Almost Full, Interrupt Generated */
Rhyme 0:74347dd8a032 162 /* FIFO Data is read, Interrupt Cleared */
Rhyme 0:74347dd8a032 163 /* Next Sample is Stored. */
Rhyme 0:74347dd8a032 164
Rhyme 0:74347dd8a032 165 }
Rhyme 0:74347dd8a032 166
Rhyme 0:74347dd8a032 167 void initHR(void)
Rhyme 0:74347dd8a032 168 {
Rhyme 0:74347dd8a032 169
Rhyme 0:74347dd8a032 170 }
Rhyme 0:74347dd8a032 171
Rhyme 0:74347dd8a032 172 void init(void)
Rhyme 0:74347dd8a032 173 {
Rhyme 0:74347dd8a032 174 uint32_t slot_config = 0 ;
Rhyme 0:74347dd8a032 175 uint8_t mode ;
Rhyme 0:74347dd8a032 176 int0 = new InterruptIn(PIN_INT1) ;
Rhyme 0:74347dd8a032 177 tty = new vt100() ;
Rhyme 0:74347dd8a032 178 tty->cls() ;
Rhyme 0:74347dd8a032 179 max30101 = new MAX30101(PIN_SDA, PIN_SCL, MAX30101_I2C_ADDRESS) ;
Rhyme 0:74347dd8a032 180 max30101->reset() ;
Rhyme 0:74347dd8a032 181
Rhyme 0:74347dd8a032 182 /* config for Mode Configuration (0x09) */
Rhyme 0:74347dd8a032 183
Rhyme 0:74347dd8a032 184 mode = 0x07 ; /* Green, Red, and/or IR */
Rhyme 0:74347dd8a032 185 // mode = 0x03 ; /* SpO2 mode */
Rhyme 0:74347dd8a032 186 max30101->setMODE_CONFIG(mode) ;
Rhyme 0:74347dd8a032 187
Rhyme 0:74347dd8a032 188 /* config for FIFO Configuration (0x08) */
Rhyme 0:74347dd8a032 189 mode =
Rhyme 0:74347dd8a032 190 // (0x02 << 5) /* SMP_AVE = 2 -> avarage of 4 data */
Rhyme 0:74347dd8a032 191 (0x05 << 5) /* SMP_AVE = 5 -> avarage of 32 data */
Rhyme 3:f3d19ad49aee 192 | (0x01 << 4) /* FIFO_ROLLOVER_EN = 1 */
Rhyme 3:f3d19ad49aee 193 // | (0x00 << 4) /* FIFO_ROLLOVER_EN = 0 */
Rhyme 0:74347dd8a032 194 | (0x0C) /* FIFO ALMOST FULL at 12 (0x0C) */
Rhyme 0:74347dd8a032 195 ;
Rhyme 0:74347dd8a032 196 max30101->setFIFO_CONFIG(mode) ;
Rhyme 0:74347dd8a032 197
Rhyme 0:74347dd8a032 198 max30101->setLED1_PA(0x80) ;
Rhyme 0:74347dd8a032 199 max30101->setLED2_PA(0x80) ;
Rhyme 3:f3d19ad49aee 200 max30101->setLED3_PA(0x80) ;
Rhyme 3:f3d19ad49aee 201 max30101->setPILOT_PA(0x80) ;
Rhyme 3:f3d19ad49aee 202 #if 1
Rhyme 0:74347dd8a032 203 slot_config =
Rhyme 0:74347dd8a032 204 (0x02 << 24) /* SLOT2 LED2(IR) */
Rhyme 0:74347dd8a032 205 | (0x01 << 16) /* SLOT1 LED1(RED) */
Rhyme 0:74347dd8a032 206 | (0x00 << 8) /* SLOT4 none */
Rhyme 0:74347dd8a032 207 | (0x03) /* SLOT3 LED3(GREEN) */
Rhyme 0:74347dd8a032 208 ;
Rhyme 0:74347dd8a032 209 max30101->setSLOT(slot_config) ;
Rhyme 0:74347dd8a032 210 #endif
Rhyme 0:74347dd8a032 211 mode = 0x01 ;
Rhyme 0:74347dd8a032 212 max30101->setPROX_INT_THR(mode) ;
Rhyme 0:74347dd8a032 213
Rhyme 0:74347dd8a032 214 // max30101->setIntEnable(0xF002) ;
Rhyme 0:74347dd8a032 215 }
Rhyme 0:74347dd8a032 216
Rhyme 0:74347dd8a032 217 void reportID(void)
Rhyme 0:74347dd8a032 218 {
Rhyme 0:74347dd8a032 219 uint8_t id, rev ;
Rhyme 0:74347dd8a032 220 id = max30101->getID() ;
Rhyme 0:74347dd8a032 221 rev = max30101->getRev() ;
Rhyme 0:74347dd8a032 222 printf("MAX30101 ID: 0x%02X, Rev: 0x%02X\n", id, rev) ;
Rhyme 0:74347dd8a032 223 }
Rhyme 0:74347dd8a032 224
Rhyme 0:74347dd8a032 225 void doInt(void)
Rhyme 0:74347dd8a032 226 {
Rhyme 0:74347dd8a032 227 uint16_t flag ;
Rhyme 0:74347dd8a032 228 flag = max30101->getIntStatus() ;
Rhyme 0:74347dd8a032 229 printf("Int: 0x%04X\n", flag) ;
Rhyme 0:74347dd8a032 230 if (flag & INT_ST_A_FULL) { /* A_FULL_EN */
Rhyme 0:74347dd8a032 231 printf("FIFO almost full!\n") ;
Rhyme 0:74347dd8a032 232 }
Rhyme 0:74347dd8a032 233 if (flag & INT_ST_PPG_RGY) { /* New FIFO Data Ready */
Rhyme 0:74347dd8a032 234 doPseudo() ;
Rhyme 0:74347dd8a032 235 }
Rhyme 0:74347dd8a032 236 if (flag & INT_ST_ALC_OVF) { /* Ambient Light Cancellaration Overflow */
Rhyme 0:74347dd8a032 237 printf("Ambient Light Cancellaration Overflow\n") ;
Rhyme 0:74347dd8a032 238 }
Rhyme 0:74347dd8a032 239 if (flag & INT_ST_PROX_INT) {/* Proximity Threshold Triggered */
Rhyme 0:74347dd8a032 240 doPseudo() ;
Rhyme 0:74347dd8a032 241 }
Rhyme 0:74347dd8a032 242 if (flag & INT_ST_PWR_RDY) {/* Power Ready Flag */
Rhyme 0:74347dd8a032 243 printf("Power Ready!\n") ;
Rhyme 0:74347dd8a032 244 }
Rhyme 0:74347dd8a032 245 if (flag & INT_ST_DIE_TEMP_RDY) {/* Internal Temperature Ready Flag */
Rhyme 0:74347dd8a032 246 printf("DIE Temperature Ready!\n") ;
Rhyme 0:74347dd8a032 247 }
Rhyme 0:74347dd8a032 248 max30101->setIntEnable(0xE002) ;
Rhyme 0:74347dd8a032 249 }
Rhyme 0:74347dd8a032 250
Rhyme 0:74347dd8a032 251 void doHR(void)
Rhyme 0:74347dd8a032 252 {
Rhyme 0:74347dd8a032 253 }
Rhyme 0:74347dd8a032 254
Rhyme 0:74347dd8a032 255 int main() {
Rhyme 0:74347dd8a032 256 uint16_t int_config = 0 ;
Rhyme 0:74347dd8a032 257 uint8_t flag = 0 ;
Rhyme 0:74347dd8a032 258 float temp = 0.0 ;
Rhyme 0:74347dd8a032 259
Rhyme 0:74347dd8a032 260 init() ;
Rhyme 0:74347dd8a032 261
Rhyme 3:f3d19ad49aee 262 printf("test MAX30101 for %s (%s)\n", BOARD_NAME, __DATE__) ;
Rhyme 0:74347dd8a032 263 reportID() ;
Rhyme 0:74347dd8a032 264
Rhyme 0:74347dd8a032 265 initSPO2() ;
Rhyme 0:74347dd8a032 266 int0->fall(&SPO2_isr) ;
Rhyme 0:74347dd8a032 267 max30101->setMODE_CONFIG(MODE_SPO2) ;
Rhyme 3:f3d19ad49aee 268 max30101->setIntEnable( INT_EN_A_FULL | INT_EN_DIE_TEMP_RDY | INT_ST_PPG_RGY ) ;
Rhyme 0:74347dd8a032 269 int_config = max30101->getIntEnable() ;
Rhyme 0:74347dd8a032 270 printf("Int enable: 0x%04X\n", int_config) ;
Rhyme 3:f3d19ad49aee 271 printf("Temperature, Interrupt flags\n") ;
Rhyme 0:74347dd8a032 272
Rhyme 0:74347dd8a032 273 while(1) {
Rhyme 0:74347dd8a032 274 max30101->setTEMP_EN() ; /* trigger temperature read */
Rhyme 1:fd8bee9b3647 275 temp = max30101->getTEMP() ;
Rhyme 1:fd8bee9b3647 276 flag = max30101->getIntStatus() ;
Rhyme 3:f3d19ad49aee 277 printf("%.2f, 0x%02X\n", temp, flag) ;
Rhyme 0:74347dd8a032 278 wait(1) ;
Rhyme 0:74347dd8a032 279 }
Rhyme 0:74347dd8a032 280 }