5 #include "I2C_Interface.h" 6 #include "I2C_Master.h" 18 #define MAX30101_INT_PWR_RDY_MASK 0xFE 23 #define MAX30101_INT_FIFO_A_FULL_MASK 0x7F 28 #define MAX30101_INT_FIFO_A_FULL_ENABLE 0x80 33 #define MAX30101_INT_FIFO_A_FULL_DISABLE 0x00 38 #define MAX30101_INT_PPG_RDY_MASK 0xBF 43 #define MAX30101_INT_PPG_RDY_ENABLE 0x40 48 #define MAX30101_INT_PPG_RDY_DISABLE 0x00 53 #define MAX30101_INT_ALC_OVF_MASK 0xDF 58 #define MAX30101_INT_ALC_OVF_ENABLE 0x20 63 #define MAX30101_INT_ALC_OVF_DISABLE 0x00 68 #define MAX30101_INT_TMP_RDY_MASK 0xFD 73 #define MAX30101_INT_TMP_RDY_ENABLE 0x02 78 #define MAX30101_INT_TMP_RDY_DISABLE 0x00 83 #define MAX30101_SMP_AVG_MASK 0x1F 88 #define MAX30101_FIFO_ROLLOVER_MASK 0xEF 93 #define MAX30101_FIFO_ROLLOVER_ENABLE 0x10 98 #define MAX30101_FIFO_ROLLOVER_DISABLE 0x00 103 #define MAX30101_FIFO_A_FULL_MASK 0xF0 108 #define MAX30101_SHUTDOWN_MASK 0x7F 113 #define MAX30101_SHUTDOWN_ENABLE 0x80 118 #define MAX30101_SHUTDOWN_DISABLE 0x00 123 #define MAX30101_RESET_MASK 0xBF 128 #define MAX30101_RESET_ENABLE 0x40 133 #define MAX30101_MODE_MASK 0xF8 138 #define MAX30101_SPO2_ADC_RANGE_MASK 0x9F 143 #define MAX30101_SPO2_SAMPLE_RATE_MASK 0xE3 148 #define MAX30101_SPO2_PULSEWIDTH_MASK 0xFC 153 #define MAX30101_SLOT1_MASK 0xF8 158 #define MAX30101_SLOT2_MASK 0x8F 163 #define MAX30101_SLOT3_MASK 0xF8 168 #define MAX30101_SLOT4_MASK 0x8F 170 #define MAX30101_SHIFT(resolution) 4-resolution 176 static uint8_t MAX30101_BitMask(uint8_t reg_addr, uint8_t mask, uint8_t thing);
178 static uint8_t MAX30101_WriteRegister(uint8_t reg_addr, uint8_t reg_data);
182 uint8_t MAX30101_Start(
void)
184 I2C_Peripheral_Start();
185 return MAX30101_Reset();
189 uint8_t MAX30101_IsDevicePresent(
void)
191 if (I2C_Peripheral_IsDeviceConnected(MAX30101_I2C_ADDRESS) == I2C_NO_ERROR)
196 return MAX30101_DEV_NOT_FOUND;
204 uint8_t MAX30101_IsFIFOAFull(uint8_t* flag)
208 uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
209 *flag = temp & (~MAX30101_INT_FIFO_A_FULL_MASK);
214 uint8_t MAX30101_IsPPGReady(uint8_t* flag)
218 uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
219 *flag = temp & (~MAX30101_INT_PPG_RDY_MASK);
222 uint8_t MAX30101_IsALCOverflow(uint8_t* flag)
226 uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
227 *flag = temp & (~MAX30101_INT_ALC_OVF_MASK);
230 uint8_t MAX30101_IsPowerReady(uint8_t* flag)
234 uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
235 *flag = temp & (~MAX30101_INT_PWR_RDY_MASK);
238 uint8_t MAX30101_IsTempReady(uint8_t* flag)
242 uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_2, &temp);
243 *flag = temp & (~MAX30101_INT_TMP_RDY_MASK);
248 uint8_t MAX30101_EnableFIFOAFullInt(
void)
250 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_FIFO_A_FULL_MASK, MAX30101_INT_FIFO_A_FULL_ENABLE);
252 uint8_t MAX30101_EnablePPGReadyInt(
void)
254 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_PPG_RDY_MASK, MAX30101_INT_PPG_RDY_ENABLE);
256 uint8_t MAX30101_EnableALCOverflowInt(
void)
258 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_ALC_OVF_MASK, MAX30101_INT_ALC_OVF_ENABLE);
261 uint8_t MAX30101_EnableTempReadyInt(
void)
263 return MAX30101_BitMask(MAX30101_INT_EN_2, MAX30101_INT_TMP_RDY_MASK, MAX30101_INT_TMP_RDY_ENABLE);
267 uint8_t MAX30101_DisableFIFOAFullInt(
void)
269 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_FIFO_A_FULL_MASK, MAX30101_INT_FIFO_A_FULL_DISABLE);
272 uint8_t MAX30101_DisablePPGReadyInt(
void)
274 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_PPG_RDY_MASK, MAX30101_INT_PPG_RDY_DISABLE);
277 uint8_t MAX30101_DisableALCOverflowInt(
void)
279 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_ALC_OVF_MASK, MAX30101_INT_ALC_OVF_DISABLE);
282 uint8_t MAX30101_DisableTempReadyInt(
void)
284 return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_TMP_RDY_MASK, MAX30101_INT_TMP_RDY_DISABLE);
291 uint8_t MAX30101_ReadWritePointer(uint8_t* wr)
293 return MAX30101_ReadRegister(MAX30101_FIFO_WP, wr);
297 uint8_t MAX30101_ReadOverflowCounter(uint8_t* oc)
299 return MAX30101_ReadRegister(MAX30101_FIFO_OVF_CNT, oc);
303 uint8_t MAX30101_ReadReadPointer(uint8_t* rr)
305 return MAX30101_ReadRegister(MAX30101_FIFO_RP, rr);
309 uint8_t MAX30101_ClearFIFO(
void)
311 uint8_t error = MAX30101_WriteRegister(MAX30101_FIFO_WP, 0x00);
312 if ( error == MAX30101_OK)
314 error = MAX30101_WriteRegister(MAX30101_FIFO_RP, 0x00);
315 if ( error == MAX30101_OK)
319 error = MAX30101_ReadRegister(MAX30101_MODE_CONF, &temp_value);
320 uint8_t current_mode = temp_value & 0x07;
324 case MAX30101_HR_MODE:
327 case MAX30101_SPO2_MODE:
330 case MAX30101_MULTI_MODE:
334 uint8_t fifo_values[active_leds*3];
336 error = MAX30101_ReadRawFIFOBytes(1, active_leds, fifo_values);
342 uint8_t MAX30101_ReadRawFIFOBytes(uint8_t num_samples, uint8_t active_leds, uint8_t* data)
345 uint16_t bytes_left_ro_read = num_samples * 3 * active_leds;
346 if (I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA, bytes_left_ro_read, data) == I2C_NO_ERROR)
352 return MAX30101_DEV_NOT_FOUND;
357 uint8_t MAX30101_ReadRawFIFO(uint8_t num_samples, uint8_t active_leds, uint32_t* data)
360 uint16_t bytes_left_ro_read = num_samples * 3 * active_leds;
365 uint8_t sample_counter = 0;
366 while(bytes_left_ro_read > 0)
368 uint16_t bytes_to_get = active_leds * 3;
370 bytes_left_ro_read -= bytes_to_get;
372 uint8_t temp[
sizeof(uint32_t)];
373 uint8_t temp_bytes[3];
376 error = I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA, 3, temp_bytes);
380 temp[2] = temp_bytes[0];
381 temp[1] = temp_bytes[1];
382 temp[0] = temp_bytes[2];
385 memcpy(&tempLong, temp,
sizeof(tempLong));
389 data[sample_counter] = tempLong;
393 I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA, 3, temp_bytes);
397 temp[2] = temp_bytes[0];
398 temp[1] = temp_bytes[1];
399 temp[0] = temp_bytes[2];
402 memcpy(&tempLong, temp,
sizeof(tempLong));
407 data[sample_counter] = tempLong;
411 I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA,3, temp_bytes);
415 temp[2] = temp_bytes[0];
416 temp[1] = temp_bytes[1];
417 temp[0] = temp_bytes[2];
420 memcpy(&tempLong, temp,
sizeof(tempLong));
425 data[sample_counter] = tempLong;
435 uint8_t MAX30101_ReadFIFO(uint8_t num_samples, uint8_t active_leds,
MAX30101_Data* data)
438 uint16_t bytes_left_ro_read = num_samples * 3 * active_leds;
439 uint8_t error = MAX30101_OK;
442 uint8_t resolution = 0;
443 I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, MAX30101_SPO2_CONF, &resolution);
444 resolution &= (~MAX30101_SPO2_PULSEWIDTH_MASK);
446 I2C_Master_MasterSendStart(MAX30101_I2C_ADDRESS, I2C_Master_WRITE_XFER_MODE);
447 I2C_Master_MasterWriteByte(MAX30101_FIFO_DATA);
448 I2C_Master_MasterSendRestart(MAX30101_I2C_ADDRESS, I2C_Master_READ_XFER_MODE);
453 while(bytes_left_ro_read > 0)
455 uint16_t bytes_to_get = active_leds * 3;
457 bytes_left_ro_read -= bytes_to_get;
460 data->
head %= BUFFER_STORAGE_SIZE;
462 uint8_t temp[
sizeof(uint32_t)];
469 temp[2] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
470 temp[1] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
471 temp[0] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
474 memcpy(&tempLong, temp,
sizeof(tempLong));
480 tempLong = tempLong >> (MAX30101_SHIFT(resolution));
482 data->
red[data->
head] = tempLong;
490 temp[2] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
491 temp[1] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
492 temp[0] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
495 memcpy(&tempLong, temp,
sizeof(tempLong));
499 tempLong = tempLong >> (MAX30101_SHIFT(resolution));
501 data->
IR[data->
head] = tempLong;
509 temp[2] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
510 temp[1] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
511 temp[0] = I2C_Master_MasterReadByte(I2C_Master_ACK_DATA);
514 memcpy(&tempLong, temp,
sizeof(tempLong));
519 tempLong = tempLong >> (MAX30101_SHIFT(resolution));
525 I2C_Master_MasterSendStop();
534 uint8_t MAX30101_SetSampleAverage(uint8_t samples)
536 return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_SMP_AVG_MASK, samples);
540 uint8_t MAX30101_EnableFIFORollover(
void)
542 return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_ROLLOVER_MASK, MAX30101_FIFO_ROLLOVER_ENABLE);
546 uint8_t MAX30101_DisableFIFORollover(
void)
548 return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_ROLLOVER_MASK, MAX30101_FIFO_ROLLOVER_DISABLE);
552 uint8_t MAX30101_SetFIFOAlmostFull(uint8_t samples)
554 return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_A_FULL_MASK, 32-samples);
562 uint8_t MAX30101_Shutdown(
void)
564 return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_SHUTDOWN_MASK, MAX30101_SHUTDOWN_ENABLE);
568 uint8_t MAX30101_WakeUp(
void)
570 return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_SHUTDOWN_MASK, MAX30101_SHUTDOWN_DISABLE);
574 uint8_t MAX30101_Reset(
void)
576 return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_RESET_MASK, MAX30101_RESET_ENABLE);
580 uint8_t MAX30101_SetMode(uint8_t mode)
582 return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_MODE_MASK, mode);
589 uint8_t MAX30101_SetSpO2ADCRange(uint8_t range)
591 return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_ADC_RANGE_MASK, range);
595 uint8_t MAX30101_SetSpO2SampleRate(uint8_t sr)
597 return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_SAMPLE_RATE_MASK, sr);
601 uint8_t MAX30101_SetSpO2PulseWidth(uint8_t pw)
603 return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_PULSEWIDTH_MASK, pw);
607 uint8_t MAX30101_SetLEDPulseAmplitude(uint8_t led_channel, uint8_t pa)
610 uint8_t error = MAX30101_OK;
612 error = I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, MAX30101_LED1_PA + led_channel, ®_data);
613 if (error == I2C_NO_ERROR)
616 if(I2C_Peripheral_WriteRegister(MAX30101_I2C_ADDRESS, MAX30101_LED1_PA + led_channel, reg_data) != I2C_NO_ERROR)
618 error = MAX30101_ERROR;
623 error = MAX30101_DEV_NOT_FOUND;
632 uint8_t MAX30101_EnableSlot(uint8_t slot, uint8_t led)
637 return MAX30101_BitMask(MAX30101_MULTI_LED_1, MAX30101_SLOT1_MASK, led);
640 return MAX30101_BitMask(MAX30101_MULTI_LED_1, MAX30101_SLOT2_MASK, led << 4);
643 return MAX30101_BitMask(MAX30101_MULTI_LED_2, MAX30101_SLOT3_MASK, led);
646 return MAX30101_BitMask(MAX30101_MULTI_LED_2, MAX30101_SLOT4_MASK, led << 4);
649 return MAX30101_ERROR;
655 uint8_t MAX30101_DisableSlots(
void)
657 uint8_t error = MAX30101_WriteRegister(MAX30101_MULTI_LED_1, 0x00);
658 if ( error == MAX30101_OK)
660 error = MAX30101_WriteRegister(MAX30101_MULTI_LED_2, 0x00);
669 uint8_t MAX30101_ReadTemperature(
float* temperature)
671 uint8_t integer, frac = 0;
672 uint8_t error = MAX30101_ReadRegister(MAX30101_TEMP_INT, &integer);
673 if ( error == MAX30101_OK)
675 error = MAX30101_ReadRegister(MAX30101_TEMP_FRACT, &frac);
676 if ( error == MAX30101_OK)
678 *temperature = ((float)(integer)) + frac * 0.0625;
685 uint8_t MAX30101_ReadRawTemperature(int8_t* integer, uint8_t* frac)
688 uint8_t error = MAX30101_ReadRegister(MAX30101_TEMP_INT, &temp);
689 if ( error == MAX30101_OK)
691 *integer = (int8_t)temp;
692 error = MAX30101_ReadRegister(MAX30101_TEMP_FRACT, frac);
698 uint8_t MAX30101_StartTemperatureConversion(
void)
700 return MAX30101_WriteRegister(MAX30101_TEMP_CONF, 0x01);
707 uint8_t MAX30101_ReadPartID(uint8_t* part_id)
709 return MAX30101_ReadRegister(MAX30101_PART_ID, part_id);
714 uint8_t MAX30101_ReadRevisionID(uint8_t* revision_id)
716 return MAX30101_ReadRegister(MAX30101_REVISION_ID, revision_id);
723 uint8_t MAX30101_ReadRegister(uint8_t reg_addr, uint8_t* reg_value)
725 uint8_t error = MAX30101_OK;
727 if(I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, reg_addr, ®_data) == I2C_NO_ERROR)
729 *reg_value = reg_data;
733 error = MAX30101_DEV_NOT_FOUND;
739 uint8_t MAX30101_LogRegisters(
void (*print_fun)(
const char*))
741 uint8_t reg_list[] = {MAX30101_INT_ST_1,
746 MAX30101_FIFO_OVF_CNT,
756 MAX30101_MULTI_LED_1,
757 MAX30101_MULTI_LED_2,
761 MAX30101_REVISION_ID,
763 uint8_t error = MAX30101_OK;
764 for (uint8_t i = 0; i < 22; i++)
766 error = MAX30101_PrintRegister(print_fun, reg_list[i]);
767 if (error != MAX30101_OK)
773 uint8_t MAX30101_PrintRegister(
void (*print_fun)(
const char*), uint8_t reg_addr)
776 uint8_t error = MAX30101_ReadRegister(reg_addr, &value);
777 if (error == MAX30101_OK)
780 sprintf(msg,
"[0x%02X] - 0x%02X\r\n", reg_addr, value);
787 static uint8_t MAX30101_WriteRegister(uint8_t reg_addr, uint8_t reg_data)
789 uint8_t error = MAX30101_OK;
790 if(I2C_Peripheral_WriteRegister(MAX30101_I2C_ADDRESS, reg_addr, reg_data) != I2C_NO_ERROR)
792 error = MAX30101_DEV_NOT_FOUND;
798 static uint8_t MAX30101_BitMask(uint8_t reg_addr, uint8_t mask, uint8_t thing)
801 uint8_t error = MAX30101_ReadRegister(reg_addr, ®_data);
802 if (error == MAX30101_OK)
804 reg_data = reg_data & mask;
805 error = MAX30101_WriteRegister(reg_addr, reg_data | thing);
uint32_t red[BUFFER_STORAGE_SIZE]
Data from RED channel.
uint32_t IR[BUFFER_STORAGE_SIZE]
Data from IR channel.
Circular buffer for MAX30101 data.
uint8_t head
Current head of the circular buffer.
uint32_t green[BUFFER_STORAGE_SIZE]
Data from GREEN channel.