/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : max30102.c
* @brief : 血氧传感器
******************************************************************************
* @attention
* 1.要宏定义 ARM_MATH_CM7,__FPU_PRESENT
* 2.打开DSP
* 3.main函数定义如下全局变量
* uint8_t max30102_int_flag = 0; // 中断标志
* float ppg_data_cache_RED[CACHE_NUMS] = {0}; // 缓存区
* float ppg_data_cache_IR[CACHE_NUMS] = {0}; // 缓存区
* uint16_t cache_counter = 0; // 缓存计数器
*
******************************************************************************
*/
/* USER CODE END Header */
#include "./max30102/max30102.h"
#include "./max30102/max30102_fir.h"
#include "algorithm.h"
#include "cmsis_os.h"
extern uint8_t max30102_int_flag;
extern uint8_t max30102_int_flag2;
extern float ppg_data_cache_RED[CACHE_NUMS] ; // 缓存区
extern float ppg_data_cache_IR[CACHE_NUMS] ; // 缓存区
extern float ppg_data_cache_RED2[CACHE_NUMS] ; // 缓存区
extern float ppg_data_cache_IR2[CACHE_NUMS] ; // 缓存区
extern uint16_t cache_counter;
extern uint16_t cache_counter2;
extern osMutexId displayMutex01Handle;
extern osSemaphoreId myBinarySem01Handle;
uint8_t maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
/**
* \brief Write a value to a MAX30102 register
* \par Details
* This function writes a value to a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[in] uch_data - register data
*
* \retval true on success
*/
{
// char ach_i2c_data[2];
// ach_i2c_data[0]=uch_addr;
// ach_i2c_data[1]=uch_data;
//HAL_i2c_write(I2C_WRITE_ADDR, uch_addr, 1, &uch_data);
HAL_I2C_GetState(&hi2c1);
//DMP库驱动 slave_addr 地址 发送时需要左移1位最后一位或上读写位
HAL_I2C_Mem_Write(&hi2c1, I2C_WRITE_ADDR, uch_addr, 1, &uch_data, 1, HAL_MAX_DELAY);
return 1;
}
uint8_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
/**
* \brief Read a MAX30102 register
* \par Details
* This function reads a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[out] puch_data - pointer that stores the register data
*
* \retval true on success
*/
{
HAL_I2C_GetState(&hi2c1);
//DMP库驱动 slave_addr 地址 发送时需要左移1位最后一位或上读写位
HAL_I2C_Mem_Read(&hi2c1, I2C_READ_ADDR, uch_addr, 1, puch_data, 1, HAL_MAX_DELAY);
// HAL_i2c_read(I2C_READ_ADDR, uch_addr, 1, puch_data);
// char ch_i2c_data;
// ch_i2c_data=uch_addr;
// if(i2c.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0)
// return 0;
// if(i2c.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0)
// {
// *puch_data=(uint8_t) ch_i2c_data;
// return 1;
// }
// else
return 1;
}
uint8_t maxim_max30102_init()
/**
* \brief Initialize the MAX30102
* \par Details
* This function initializes the MAX30102
*
* \param None
*
* \retval true on success
*/
{
uint8_t data;
if(!maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xC0)) // INTR setting
return 0;
if(!maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00))
return 0;
if(!maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00)) //FIFO_WR_PTR[4:0]
return 0;
if(!maxim_max30102_write_reg(REG_OVF_COUNTER,0x00)) //OVF_COUNTER[4:0]
return 0;
if(!maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00)) //FIFO_RD_PTR[4:0]
return 0;
if(!maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f)) //sample avg = 1, fifo rollover=false, fifo almost full = 17
return 0;
if(!maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)) //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
return 0;
if(!maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27)) // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
return 0;
if(!maxim_max30102_write_reg(REG_LED1_PA,0x24)) //Choose value for ~ 7mA for LED1
return 0;
if(!maxim_max30102_write_reg(REG_LED2_PA,0x24)) // Choose value for ~ 7mA for LED2
return 0;
if(!maxim_max30102_write_reg(REG_PILOT_PA,0x7f)) // Choose value for ~ 25mA for Pilot LED
return 0;
//maxim_max30102_read_reg(INTERRUPT_STATUS1, &data);
//maxim_max30102_read_reg(INTERRUPT_STATUS2, &data); // clear status
return 1;
}
uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
/**
* \brief Read a set of samples from the MAX30102 FIFO register
* \par Details
* This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out] *pun_red_led - pointer that stores the red LED reading data
* \param[out] *pun_ir_led - pointer that stores the IR LED reading data
*
* \retval true on success
*/
{
uint32_t un_temp;
unsigned char uch_temp;
*pun_red_led=0;
*pun_ir_led=0;
unsigned char ach_i2c_data[6];
//read and clear status register
maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
ach_i2c_data[0]=REG_FIFO_DATA;
HAL_I2C_GetState(&hi2c1);
//DMP库驱动 slave_addr 地址 发送时需要左移1位最后一位或上读写位
HAL_I2C_Mem_Read(&hi2c1, I2C_READ_ADDR, REG_FIFO_DATA, 1, ach_i2c_data, 6, HAL_MAX_DELAY);
un_temp=(unsigned char) ach_i2c_data[0];
un_temp<<=16;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[1];
un_temp<<=8;
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[2];
*pun_red_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[3];
un_temp<<=16;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[4];
un_temp<<=8;
*pun_ir_led+=un_temp;
un_temp=(unsigned char) ach_i2c_data[5];
*pun_ir_led+=un_temp;
*pun_red_led&=0x03FFFF; //Mask MSB [23:18]
*pun_ir_led&=0x03FFFF; //Mask MSB [23:18]
return 1;
}
uint8_t maxim_max30102_reset()
/**
* \brief Reset the MAX30102
* \par Details
* This function resets the MAX30102
*
* \param None
*
* \retval true on success
*/
{
if(!maxim_max30102_write_reg(REG_MODE_CONFIG,0x40))
return 0;
else
return 1;
}
///IIC 2 function start here
uint8_t maxim_max30102_write_reg2(uint8_t uch_addr, uint8_t uch_data)
/**
* \brief Write a value to a MAX30102 register
* \par Details
* This function writes a value to a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[in] uch_data - register data
*
* \retval true on success
*/
{
// char ach_i2c_data[2];
// ach_i2c_data[0]=uch_addr;
// ach_i2c_data[1]=uch_data;
//HAL_i2c_write(I2C_WRITE_ADDR, uch_addr, 1, &uch_data);
HAL_I2C_GetState(&hi2c2);
//DMP?????? slave_addr ??? ????????????1?f?????f???????f
HAL_I2C_Mem_Write(&hi2c2, I2C_WRITE_ADDR, uch_addr, 1, &uch_data, 1, HAL_MAX_DELAY);
return 1;
}
uint8_t maxim_max30102_read_reg2(uint8_t uch_addr, uint8_t *puch_data)
/**
* \brief Read a MAX30102 register
* \par Details
* This function reads a MAX30102 register
*
* \param[in] uch_addr - register address
* \param[out] puch_data - pointer that stores the register data
*
* \retval true on success
*/
{
HAL_I2C_GetState(&hi2c2);
//DMP?????? slave_addr ??? ????????????1?f?????f???????f
HAL_I2C_Mem_Read(&hi2c2, I2C_READ_ADDR, uch_addr, 1, puch_data, 1, HAL_MAX_DELAY);
// HAL_i2c_read(I2C_READ_ADDR, uch_addr, 1, puch_data);
// char ch_i2c_data;
// ch_i2c_data=uch_addr;
// if(i2c.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0)
// return 0;
// if(i2c.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0)
// {
// *puch_data=(uint8_t) ch_i2c_data;
// return 1;
// }
// else
return 1;
}
uint8_t maxim_max301