PSoC-MAX30101
PSoC MAX30101 Library
MAX30101.c
1 
5 #include "I2C_Interface.h"
6 #include "I2C_Master.h"
7 #include "MAX30101.h"
8 #include "string.h"
9 #include "stdio.h"
10 
11 //==============================================
12 // MACROS
13 //==============================================
14 
18 #define MAX30101_INT_PWR_RDY_MASK 0xFE
19 
23 #define MAX30101_INT_FIFO_A_FULL_MASK 0x7F
24 
28 #define MAX30101_INT_FIFO_A_FULL_ENABLE 0x80
29 
33 #define MAX30101_INT_FIFO_A_FULL_DISABLE 0x00
34 
38 #define MAX30101_INT_PPG_RDY_MASK 0xBF
39 
43 #define MAX30101_INT_PPG_RDY_ENABLE 0x40
44 
48 #define MAX30101_INT_PPG_RDY_DISABLE 0x00
49 
53 #define MAX30101_INT_ALC_OVF_MASK 0xDF
54 
58 #define MAX30101_INT_ALC_OVF_ENABLE 0x20
59 
63 #define MAX30101_INT_ALC_OVF_DISABLE 0x00
64 
68 #define MAX30101_INT_TMP_RDY_MASK 0xFD
69 
73 #define MAX30101_INT_TMP_RDY_ENABLE 0x02
74 
78 #define MAX30101_INT_TMP_RDY_DISABLE 0x00
79 
83 #define MAX30101_SMP_AVG_MASK 0x1F
84 
88 #define MAX30101_FIFO_ROLLOVER_MASK 0xEF
89 
93 #define MAX30101_FIFO_ROLLOVER_ENABLE 0x10
94 
98 #define MAX30101_FIFO_ROLLOVER_DISABLE 0x00
99 
103 #define MAX30101_FIFO_A_FULL_MASK 0xF0
104 
108 #define MAX30101_SHUTDOWN_MASK 0x7F
109 
113 #define MAX30101_SHUTDOWN_ENABLE 0x80
114 
118 #define MAX30101_SHUTDOWN_DISABLE 0x00
119 
123 #define MAX30101_RESET_MASK 0xBF
124 
128 #define MAX30101_RESET_ENABLE 0x40
129 
133 #define MAX30101_MODE_MASK 0xF8
134 
138 #define MAX30101_SPO2_ADC_RANGE_MASK 0x9F
139 
143 #define MAX30101_SPO2_SAMPLE_RATE_MASK 0xE3
144 
148 #define MAX30101_SPO2_PULSEWIDTH_MASK 0xFC
149 
153 #define MAX30101_SLOT1_MASK 0xF8
154 
158 #define MAX30101_SLOT2_MASK 0x8F
159 
163 #define MAX30101_SLOT3_MASK 0xF8
164 
168 #define MAX30101_SLOT4_MASK 0x8F
169 
170 #define MAX30101_SHIFT(resolution) 4-resolution
171 
172 //==============================================
173 // FUNCTION PROTOTYPESS
174 //==============================================
175 
176 static uint8_t MAX30101_BitMask(uint8_t reg_addr, uint8_t mask, uint8_t thing);
177 
178 static uint8_t MAX30101_WriteRegister(uint8_t reg_addr, uint8_t reg_data);
179 
180 
181 // Start the device
182 uint8_t MAX30101_Start(void)
183 {
184  I2C_Peripheral_Start();
185  return MAX30101_Reset();
186 }
187 
188 // Check if device is present on I2C bus
189 uint8_t MAX30101_IsDevicePresent(void)
190 {
191  if (I2C_Peripheral_IsDeviceConnected(MAX30101_I2C_ADDRESS) == I2C_NO_ERROR)
192  {
193  return MAX30101_OK;
194  }
195 
196  return MAX30101_DEV_NOT_FOUND;
197 }
198 
199 //==============================================
200 // INTERRUPT RELATED FUNCTIONS
201 //==============================================
202 
203 // Check interrupt status
204 uint8_t MAX30101_IsFIFOAFull(uint8_t* flag)
205 {
206  // Read register
207  uint8_t temp;
208  uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
209  *flag = temp & (~MAX30101_INT_FIFO_A_FULL_MASK);
210  return error;
211 
212 }
213 
214 uint8_t MAX30101_IsPPGReady(uint8_t* flag)
215 {
216  // Read register
217  uint8_t temp;
218  uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
219  *flag = temp & (~MAX30101_INT_PPG_RDY_MASK);
220  return error;
221 }
222 uint8_t MAX30101_IsALCOverflow(uint8_t* flag)
223 {
224  // Read register
225  uint8_t temp;
226  uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
227  *flag = temp & (~MAX30101_INT_ALC_OVF_MASK);
228  return error;
229 }
230 uint8_t MAX30101_IsPowerReady(uint8_t* flag)
231 {
232  // Read register
233  uint8_t temp;
234  uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_1, &temp);
235  *flag = temp & (~MAX30101_INT_PWR_RDY_MASK);
236  return error;
237 }
238 uint8_t MAX30101_IsTempReady(uint8_t* flag)
239 {
240  // Read register
241  uint8_t temp;
242  uint8_t error = MAX30101_ReadRegister(MAX30101_INT_ST_2, &temp);
243  *flag = temp & (~MAX30101_INT_TMP_RDY_MASK);
244  return error;
245 }
246 
247 // Enable interrupts
248 uint8_t MAX30101_EnableFIFOAFullInt(void)
249 {
250  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_FIFO_A_FULL_MASK, MAX30101_INT_FIFO_A_FULL_ENABLE);
251 }
252 uint8_t MAX30101_EnablePPGReadyInt(void)
253 {
254  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_PPG_RDY_MASK, MAX30101_INT_PPG_RDY_ENABLE);
255 }
256 uint8_t MAX30101_EnableALCOverflowInt(void)
257 {
258  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_ALC_OVF_MASK, MAX30101_INT_ALC_OVF_ENABLE);
259 }
260 
261 uint8_t MAX30101_EnableTempReadyInt(void)
262 {
263  return MAX30101_BitMask(MAX30101_INT_EN_2, MAX30101_INT_TMP_RDY_MASK, MAX30101_INT_TMP_RDY_ENABLE);
264 }
265 
266 // Disable interrupts
267 uint8_t MAX30101_DisableFIFOAFullInt(void)
268 {
269  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_FIFO_A_FULL_MASK, MAX30101_INT_FIFO_A_FULL_DISABLE);
270 }
271 
272 uint8_t MAX30101_DisablePPGReadyInt(void)
273 {
274  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_PPG_RDY_MASK, MAX30101_INT_PPG_RDY_DISABLE);
275 }
276 
277 uint8_t MAX30101_DisableALCOverflowInt(void)
278 {
279  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_ALC_OVF_MASK, MAX30101_INT_ALC_OVF_DISABLE);
280 }
281 
282 uint8_t MAX30101_DisableTempReadyInt(void)
283 {
284  return MAX30101_BitMask(MAX30101_INT_EN_1, MAX30101_INT_TMP_RDY_MASK, MAX30101_INT_TMP_RDY_DISABLE);
285 }
286 
287 //==============================================
288 // FIFO FUNCTIONS
289 //==============================================
290 // Read Write pointer
291 uint8_t MAX30101_ReadWritePointer(uint8_t* wr)
292 {
293  return MAX30101_ReadRegister(MAX30101_FIFO_WP, wr);
294 }
295 
296 // Read Overflow counter
297 uint8_t MAX30101_ReadOverflowCounter(uint8_t* oc)
298 {
299  return MAX30101_ReadRegister(MAX30101_FIFO_OVF_CNT, oc);
300 }
301 
302 // Read Read Pointer
303 uint8_t MAX30101_ReadReadPointer(uint8_t* rr)
304 {
305  return MAX30101_ReadRegister(MAX30101_FIFO_RP, rr);
306 }
307 
308 // Clear FIFO
309 uint8_t MAX30101_ClearFIFO(void)
310 {
311  uint8_t error = MAX30101_WriteRegister(MAX30101_FIFO_WP, 0x00);
312  if ( error == MAX30101_OK)
313  {
314  error = MAX30101_WriteRegister(MAX30101_FIFO_RP, 0x00);
315  if ( error == MAX30101_OK)
316  {
317  // Read current mode to determine number of active leds
318  uint8_t temp_value;
319  error = MAX30101_ReadRegister(MAX30101_MODE_CONF, &temp_value);
320  uint8_t current_mode = temp_value & 0x07;
321  uint8_t active_leds;
322  switch(current_mode)
323  {
324  case MAX30101_HR_MODE:
325  active_leds = 1;
326  break;
327  case MAX30101_SPO2_MODE:
328  active_leds = 2;
329  break;
330  case MAX30101_MULTI_MODE:
331  active_leds = 3;
332  break;
333  }
334  uint8_t fifo_values[active_leds*3];
335  // Read 1 from FIFO to clear the overflow counter
336  error = MAX30101_ReadRawFIFOBytes(1, active_leds, fifo_values);
337  }
338  }
339  return error;
340 }
341 
342 uint8_t MAX30101_ReadRawFIFOBytes(uint8_t num_samples, uint8_t active_leds, uint8_t* data)
343 {
344  // We need to read a number of bytes equal to num_samples + 3 * active_leds
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)
347  {
348  return MAX30101_OK;
349  }
350  else
351  {
352  return MAX30101_DEV_NOT_FOUND;
353  }
354 }
355 
356 // Read FIFO Data
357 uint8_t MAX30101_ReadRawFIFO(uint8_t num_samples, uint8_t active_leds, uint32_t* data)
358 {
359  // We need to read a number of bytes equal to num_samples + 3 * active_leds
360  uint16_t bytes_left_ro_read = num_samples * 3 * active_leds;
361  uint8_t error;
362  //uint8_t error = I2C_Peripheral_WriteRegisterNoData(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA);
363  //if ( error == I2C_NO_ERROR)
364  //{
365  uint8_t sample_counter = 0;
366  while(bytes_left_ro_read > 0)
367  {
368  uint16_t bytes_to_get = active_leds * 3;
369 
370  bytes_left_ro_read -= bytes_to_get;
371 
372  uint8_t temp[sizeof(uint32_t)];
373  uint8_t temp_bytes[3];
374  uint32_t tempLong;
375 
376  error = I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA, 3, temp_bytes);
377 
378  //Burst read three bytes - RED
379  temp[3] = 0;
380  temp[2] = temp_bytes[0];
381  temp[1] = temp_bytes[1];
382  temp[0] = temp_bytes[2];
383 
384  //Convert array to long
385  memcpy(&tempLong, temp, sizeof(tempLong));
386 
387  //Zero out all but 18 bits
388  tempLong &= 0x3FFFF;
389  data[sample_counter] = tempLong;
390 
391  if (active_leds > 1)
392  {
393  I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA, 3, temp_bytes);
394 
395  //Burst read three bytes - IR
396  temp[3] = 0;
397  temp[2] = temp_bytes[0];
398  temp[1] = temp_bytes[1];
399  temp[0] = temp_bytes[2];
400 
401  //Convert array to long
402  memcpy(&tempLong, temp, sizeof(tempLong));
403 
404  //Zero out all but 18 bits
405  tempLong &= 0x3FFFF;
406  sample_counter += 1;
407  data[sample_counter] = tempLong;
408  }
409  if (active_leds > 2)
410  {
411  I2C_Peripheral_ReadRegisterMulti(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA,3, temp_bytes);
412 
413  //Burst read three bytes - GREEN
414  temp[3] = 0;
415  temp[2] = temp_bytes[0];
416  temp[1] = temp_bytes[1];
417  temp[0] = temp_bytes[2];
418 
419  //Convert array to long
420  memcpy(&tempLong, temp, sizeof(tempLong));
421 
422  //Zero out all but 18 bits
423  tempLong &= 0x3FFFF;
424  sample_counter += 1;
425  data[sample_counter] = tempLong;
426  }
427  sample_counter += 1;
428 
429  }
430  //}
431  return error;
432 }
433 
434 // Read FIFO Data
435 uint8_t MAX30101_ReadFIFO(uint8_t num_samples, uint8_t active_leds, MAX30101_Data* data)
436 {
437  // We need to read a number of bytes equal to num_samples + 3 * active_leds
438  uint16_t bytes_left_ro_read = num_samples * 3 * active_leds;
439  uint8_t error = MAX30101_OK;
440 
441  // Read current resolution so that we know how much shift to apply
442  uint8_t resolution = 0;
443  I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, MAX30101_SPO2_CONF, &resolution);
444  resolution &= (~MAX30101_SPO2_PULSEWIDTH_MASK);
445 
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);
449 
450  //I2C_Peripheral_WriteRegisterNoData(MAX30101_I2C_ADDRESS, MAX30101_FIFO_DATA);
451  //I2C_Peripheral_StartReadNoAddress(MAX30101_I2C_ADDRESS);
452 
453  while(bytes_left_ro_read > 0)
454  {
455  uint16_t bytes_to_get = active_leds * 3;
456 
457  bytes_left_ro_read -= bytes_to_get;
458 
459  data->head++; //Advance the head of the storage struct
460  data->head %= BUFFER_STORAGE_SIZE; //Wrap condition
461 
462  uint8_t temp[sizeof(uint32_t)];
463  uint32_t tempLong;
464 
465  //error = I2C_Peripheral_ReadBytes(temp_bytes, 3);
466 
467  //Burst read three bytes - RED
468  temp[3] = 0;
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);
472 
473  //Convert array to long
474  memcpy(&tempLong, temp, sizeof(tempLong));
475 
476  //Zero out all but 18 bits
477  tempLong &= 0x3FFFF;
478 
479  // Shift according to resolution
480  tempLong = tempLong >> (MAX30101_SHIFT(resolution));
481 
482  data->red[data->head] = tempLong; //Store this reading into the sense array
483 
484  if (active_leds > 1)
485  {
486  //error = I2C_Peripheral_ReadBytes(temp_bytes, 3);
487 
488  //Burst read three bytes - IR
489  temp[3] = 0;
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);
493 
494  //Convert array to long
495  memcpy(&tempLong, temp, sizeof(tempLong));
496 
497  //Zero out all but 18 bits
498  tempLong &= 0x3FFFF;
499  tempLong = tempLong >> (MAX30101_SHIFT(resolution));
500 
501  data->IR[data->head] = tempLong; //Store this reading into the sense array
502  }
503  if (active_leds > 2)
504  {
505  //error = I2C_Peripheral_ReadBytes(temp_bytes, 3);
506 
507  //Burst read three bytes - GREEN
508  temp[3] = 0;
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);
512 
513  //Convert array to long
514  memcpy(&tempLong, temp, sizeof(tempLong));
515 
516  //Zero out all but 18 bits
517  tempLong &= 0x3FFFF;
518 
519  tempLong = tempLong >> (MAX30101_SHIFT(resolution));
520 
521  data->green[data->head] = tempLong; //Store this reading into the sense array
522  }
523  }
524 
525  I2C_Master_MasterSendStop();
526  return error;
527 }
528 
529 //==============================================
530 // MAX30101 FIFO CONFIGURATION FUNCTIONS
531 //==============================================
532 
534 uint8_t MAX30101_SetSampleAverage(uint8_t samples)
535 {
536  return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_SMP_AVG_MASK, samples);
537 }
538 
539 // Enable FIFO rollover
540 uint8_t MAX30101_EnableFIFORollover(void)
541 {
542  return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_ROLLOVER_MASK, MAX30101_FIFO_ROLLOVER_ENABLE);
543 }
544 
545 // Disable FIFO rollover
546 uint8_t MAX30101_DisableFIFORollover(void)
547 {
548  return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_ROLLOVER_MASK, MAX30101_FIFO_ROLLOVER_DISABLE);
549 }
550 
551 // Set number of samples for FIFO Almost Full
552 uint8_t MAX30101_SetFIFOAlmostFull(uint8_t samples)
553 {
554  return MAX30101_BitMask(MAX30101_FIFO_CONF, MAX30101_FIFO_A_FULL_MASK, 32-samples);
555 }
556 
557 //==============================================
558 // MAX30101 MODE CONFIGURATION FUNCTIONS
559 //==============================================
560 
561 // Shutdown the MAX30101
562 uint8_t MAX30101_Shutdown(void)
563 {
564  return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_SHUTDOWN_MASK, MAX30101_SHUTDOWN_ENABLE);
565 }
566 
567 // Wake Up the MAX30101
568 uint8_t MAX30101_WakeUp(void)
569 {
570  return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_SHUTDOWN_MASK, MAX30101_SHUTDOWN_DISABLE);
571 }
572 
573 // Reset the MAX30101
574 uint8_t MAX30101_Reset(void)
575 {
576  return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_RESET_MASK, MAX30101_RESET_ENABLE);
577 }
578 
579 // Set current mode of operation
580 uint8_t MAX30101_SetMode(uint8_t mode)
581 {
582  return MAX30101_BitMask(MAX30101_MODE_CONF, MAX30101_MODE_MASK, mode);
583 }
584 
585 //==============================================
586 // MAX30101 SPO2 CONFIGURATION FUNCTIONS
587 //==============================================
588 // Set SpO2 ADC Range
589 uint8_t MAX30101_SetSpO2ADCRange(uint8_t range)
590 {
591  return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_ADC_RANGE_MASK, range);
592 }
593 
594 // Set SpO2 Sample Rate
595 uint8_t MAX30101_SetSpO2SampleRate(uint8_t sr)
596 {
597  return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_SAMPLE_RATE_MASK, sr);
598 }
599 
600 // Set SpO2 Pulse Widht
601 uint8_t MAX30101_SetSpO2PulseWidth(uint8_t pw)
602 {
603  return MAX30101_BitMask(MAX30101_SPO2_CONF, MAX30101_SPO2_PULSEWIDTH_MASK, pw);
604 }
605 
606 // Set pulse amplitude for a channel
607 uint8_t MAX30101_SetLEDPulseAmplitude(uint8_t led_channel, uint8_t pa)
608 {
609  // Read register
610  uint8_t error = MAX30101_OK;
611  uint8_t reg_data;
612  error = I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, MAX30101_LED1_PA + led_channel, &reg_data);
613  if (error == I2C_NO_ERROR)
614  {
615  reg_data |= pa;
616  if(I2C_Peripheral_WriteRegister(MAX30101_I2C_ADDRESS, MAX30101_LED1_PA + led_channel, reg_data) != I2C_NO_ERROR)
617  {
618  error = MAX30101_ERROR;
619  }
620  }
621  else
622  {
623  error = MAX30101_DEV_NOT_FOUND;
624  }
625  return error;
626 }
627 
628 //======================================================
629 // MAX30101 MULTI LED MODE CONFIGURATION FUNCTIONS
630 //======================================================
631 // Enable given slot
632 uint8_t MAX30101_EnableSlot(uint8_t slot, uint8_t led)
633 {
634  switch(slot)
635  {
636  case 1:
637  return MAX30101_BitMask(MAX30101_MULTI_LED_1, MAX30101_SLOT1_MASK, led);
638  break;
639  case 2:
640  return MAX30101_BitMask(MAX30101_MULTI_LED_1, MAX30101_SLOT2_MASK, led << 4);
641  break;
642  case 3:
643  return MAX30101_BitMask(MAX30101_MULTI_LED_2, MAX30101_SLOT3_MASK, led);
644  break;
645  case 4:
646  return MAX30101_BitMask(MAX30101_MULTI_LED_2, MAX30101_SLOT4_MASK, led << 4);
647  break;
648  default:
649  return MAX30101_ERROR;
650  break;
651  }
652 }
653 
654 // Disable all slots configurations
655 uint8_t MAX30101_DisableSlots(void)
656 {
657  uint8_t error = MAX30101_WriteRegister(MAX30101_MULTI_LED_1, 0x00);
658  if ( error == MAX30101_OK)
659  {
660  error = MAX30101_WriteRegister(MAX30101_MULTI_LED_2, 0x00);
661  }
662 
663  return error;
664 }
665 
666 //======================================================
667 // MAX30101 DIE TEMPERATURE FUNCTIONS
668 //======================================================
669 uint8_t MAX30101_ReadTemperature(float* temperature)
670 {
671  uint8_t integer, frac = 0;
672  uint8_t error = MAX30101_ReadRegister(MAX30101_TEMP_INT, &integer);
673  if ( error == MAX30101_OK)
674  {
675  error = MAX30101_ReadRegister(MAX30101_TEMP_FRACT, &frac);
676  if ( error == MAX30101_OK)
677  {
678  *temperature = ((float)(integer)) + frac * 0.0625;
679  }
680  }
681 
682  return error;
683 }
684 
685 uint8_t MAX30101_ReadRawTemperature(int8_t* integer, uint8_t* frac)
686 {
687  uint8_t temp;
688  uint8_t error = MAX30101_ReadRegister(MAX30101_TEMP_INT, &temp);
689  if ( error == MAX30101_OK)
690  {
691  *integer = (int8_t)temp;
692  error = MAX30101_ReadRegister(MAX30101_TEMP_FRACT, frac);
693  }
694 
695  return error;
696 }
697 
698 uint8_t MAX30101_StartTemperatureConversion(void)
699 {
700  return MAX30101_WriteRegister(MAX30101_TEMP_CONF, 0x01);
701 }
702 
703 //======================================================
704 // MAX30101 PART/REVISION ID FUNCTIONS
705 //======================================================
706 // Read part ID number
707 uint8_t MAX30101_ReadPartID(uint8_t* part_id)
708 {
709  return MAX30101_ReadRegister(MAX30101_PART_ID, part_id);
710 
711 }
712 
713 // Read revision ID number
714 uint8_t MAX30101_ReadRevisionID(uint8_t* revision_id)
715 {
716  return MAX30101_ReadRegister(MAX30101_REVISION_ID, revision_id);
717 }
718 
719 //======================================================
720 // MAX30101 HELPER FUNCTIONS
721 //======================================================
722 // Simple helper function to read a register from the MAX30101
723 uint8_t MAX30101_ReadRegister(uint8_t reg_addr, uint8_t* reg_value)
724 {
725  uint8_t error = MAX30101_OK;
726  uint8_t reg_data;
727  if(I2C_Peripheral_ReadRegister(MAX30101_I2C_ADDRESS, reg_addr, &reg_data) == I2C_NO_ERROR)
728  {
729  *reg_value = reg_data;
730  }
731  else
732  {
733  error = MAX30101_DEV_NOT_FOUND;
734  }
735  return error;
736 }
737 
738 // Log all registers
739 uint8_t MAX30101_LogRegisters(void (*print_fun)(const char*))
740 {
741  uint8_t reg_list[] = {MAX30101_INT_ST_1,
742  MAX30101_INT_ST_2,
743  MAX30101_INT_EN_1,
744  MAX30101_INT_EN_2,
745  MAX30101_FIFO_WP,
746  MAX30101_FIFO_OVF_CNT,
747  MAX30101_FIFO_RP,
748  MAX30101_FIFO_DATA,
749  MAX30101_FIFO_CONF,
750  MAX30101_MODE_CONF,
751  MAX30101_SPO2_CONF,
752  MAX30101_LED1_PA,
753  MAX30101_LED2_PA,
754  MAX30101_LED3_PA,
755  MAX30101_LED4_PA,
756  MAX30101_MULTI_LED_1,
757  MAX30101_MULTI_LED_2,
758  MAX30101_TEMP_INT,
759  MAX30101_TEMP_FRACT,
760  MAX30101_TEMP_CONF,
761  MAX30101_REVISION_ID,
762  MAX30101_PART_ID};
763  uint8_t error = MAX30101_OK;
764  for (uint8_t i = 0; i < 22; i++)
765  {
766  error = MAX30101_PrintRegister(print_fun, reg_list[i]);
767  if (error != MAX30101_OK)
768  break;
769  }
770  return error;
771 }
772 
773 uint8_t MAX30101_PrintRegister(void (*print_fun)(const char*), uint8_t reg_addr)
774 {
775  uint8_t value;
776  uint8_t error = MAX30101_ReadRegister(reg_addr, &value);
777  if (error == MAX30101_OK)
778  {
779  char msg[20];
780  sprintf(msg, "[0x%02X] - 0x%02X\r\n", reg_addr, value);
781  print_fun(msg);
782  }
783  return error;
784 }
785 
786 // Simple helper function to write a register to the MAX30101
787 static uint8_t MAX30101_WriteRegister(uint8_t reg_addr, uint8_t reg_data)
788 {
789  uint8_t error = MAX30101_OK;
790  if(I2C_Peripheral_WriteRegister(MAX30101_I2C_ADDRESS, reg_addr, reg_data) != I2C_NO_ERROR)
791  {
792  error = MAX30101_DEV_NOT_FOUND;
793  }
794  return error;
795 }
796 
797 // Simple helper function to perform bit mask operations
798 static uint8_t MAX30101_BitMask(uint8_t reg_addr, uint8_t mask, uint8_t thing)
799 {
800  uint8_t reg_data;
801  uint8_t error = MAX30101_ReadRegister(reg_addr, &reg_data);
802  if (error == MAX30101_OK)
803  {
804  reg_data = reg_data & mask;
805  error = MAX30101_WriteRegister(reg_addr, reg_data | thing);
806  }
807  return error;
808 }
809 
810 /* [] END OF FILE */
uint32_t red[BUFFER_STORAGE_SIZE]
Data from RED channel.
Definition: MAX30101.h:29
uint32_t IR[BUFFER_STORAGE_SIZE]
Data from IR channel.
Definition: MAX30101.h:30
Circular buffer for MAX30101 data.
Definition: MAX30101.h:27
uint8_t head
Current head of the circular buffer.
Definition: MAX30101.h:32
uint32_t green[BUFFER_STORAGE_SIZE]
Data from GREEN channel.
Definition: MAX30101.h:31