RTL00_WEB/USDK/example_sources/i2c_epl2197_heartrate/src/main.c
2017-06-21 03:00:20 +03:00

165 lines
4.6 KiB
C

/*******************************************************************************
* HRM.c - Eminent Heart Rate Module (HRM) routines via I2C
*******************************************************************************/
#include "HRM_2197.h"
#include <stdio.h>
#include <time.h>
//#include <windows.h>
#include "heart_interface.h"
#include "device.h"
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include "osdep_api.h"
#include "i2c_api.h"
#include "pinmap.h"
//#include "rtl_lib.h"
#include "gpio_api.h" // mbed
#include "main.h"
#define MBED_I2C_SLAVE_ADDR0 0x41
#define HR_MODE 0x001b
#define LED_ENABLE 0x3081
#define FRAME_ENABLE 0x4804
#define CHIP_RESET 0x4000
#define CHIP_RUN 0x4004
#define DATA_LOCK 0x4005
#define DATA_UNLOCK 0x4004
#define I2C_DATA_MAX_LENGTH 20
#define CLOCK_SET 0x3800
#define MBED_I2C_MTR_SDA PB_3
#define MBED_I2C_MTR_SCL PB_2
#define MBED_I2C_INTB PA_5
#define MBED_I2C_BUS_CLK 100000 //hz
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
uint16_t cmd;
i2c_t i2cmaster;
uint8_t integ_time = HR_INTEG_MIN;
int integ_time_array[] = { 4, 6, 8, 10, 15, 20, 25, 30, 40, 55, 70, 90, 110, 150, 200, 250, 350, 450, 550 };
//Step1. define the callback to handle event of heart rate update
/*******************************************************************************
* report heart rate every 1 second
*******************************************************************************/
void on_heartrate_update(int heartrate) {
printf("heart rate %d\n", heartrate);
//fflush(stdout);
}
char i2cdatasrc[3] = {0x68, 0x90, 0x98};
static void ePL_WriteCommand(uint16_t cmd)
{
i2cdata_write[0] = (uint8_t)(cmd >>8);
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
}
uint16_t read_hrm(void) {
uint32_t raw, normalized_raw;
int integ_time_changed = 0;
ePL_WriteCommand(DATA_LOCK);
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1);
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1);
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1);
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1);
raw = i2cdata_read[1];
raw |= (uint16_t) i2cdata_read[2] << 8;
normalized_raw = raw >> 4;
normalized_raw = normalized_raw * integ_time_array[HR_INTEG_BASE];
normalized_raw = normalized_raw / integ_time_array[integ_time];
if (raw > HR_TH_HIGH && integ_time > HR_INTEG_MIN) {
integ_time -= 1;
integ_time_changed = 1;
} else if (raw < HR_TH_LOW && integ_time < HR_INTEG_MAX) {
integ_time += 1;
integ_time_changed = 1;
}
if (integ_time_changed == 1) {
ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time));
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET));
}
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RUN));
return normalized_raw;
}
/*******************************************************************************
* main function to read data, input to library,
* and calculate heart rate
*******************************************************************************/
void main(void) {
int i, length;
int *data;
int should_stop = 0;
uint16_t result;
data = (int*) calloc(3000, sizeof(int));
//load_ppg_signal(data, &length); //Load Test Data From File
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
//Step2. delegate the event of heart rate update
register_callback(on_heartrate_update);
//Step3. Set the data length of heart rate calculation= 2^9 = 512
ePL_WriteCommand(((0x00<<3)<<8) | ( HR_MODE_HRS | HR_OSR_1024 | HR_GAIN_MID));
ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time));
ePL_WriteCommand(((0x09<<3)<<8) | ( HR_PDRIVE_70MA));
ePL_WriteCommand(((0x06<<3)<<8) | ( HR_IR_ENABLE | HR_INT_FRAME));
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET));
while(1) {
//Step4. Add ppg data continuously, and the Lib will return the Heart Rate 1 time/sec
result = read_hrm();
if(result>100)
add_PPG_XYZ(result, 0, 0, 0);
Mdelay(40); //Simulate the ppg input time interval = 40ms
if(should_stop)
break;
}
//Step5. Stop
stop();
free(data);
}
/*******************************************************************************
* initialize ic parameters
*******************************************************************************/
/*******************************************************************************
* read rawdata
*******************************************************************************/