652 lines
21 KiB
C
652 lines
21 KiB
C
/*----------------------------------------------------------------------------
|
||
* Copyright (c) TJD Technologies Co., Ltd. 2020. All rights reserved.
|
||
*
|
||
* Description: hr_drv_HX3602.c
|
||
*
|
||
* Author: liangjianfei
|
||
*
|
||
* Create: 2024-4-26
|
||
*--------------------------------------------------------------------------*/
|
||
#include <stdio.h>
|
||
#include <stdbool.h>
|
||
#include <stdint.h>
|
||
#include <stdlib.h>
|
||
#include <math.h>
|
||
#include "hr_drv_HX3602.h"
|
||
#include "hrs3602_reg_init.h"
|
||
#include "hr_port.h"
|
||
#include "tyhx_hrs_alg.h"
|
||
#include "sys_config.h"
|
||
|
||
#define ENABLE_PRINT_INFO 1
|
||
#if ENABLE_PRINT_INFO
|
||
#define static_print_info(...) sys_hr_log_i(__VA_ARGS__) //一般信息打印宏控制
|
||
#define static_print_warn(...) sys_hr_log_w(__VA_ARGS__) //警告信息打印一般常开
|
||
#define static_print_error(...) sys_hr_log_e(__VA_ARGS__) //错误信息打印一般常开
|
||
#else
|
||
#define static_print_info(...)
|
||
#define static_print_warn(...)
|
||
#define static_print_error(...)
|
||
#endif
|
||
|
||
static hr_wear_status_t wear_status = MSG_CHECK_INIT;
|
||
static hr_wear_status_t wear_status_pre = MSG_CHECK_INIT;
|
||
|
||
const uint32_t hx3602_wear_thre_high = 5000;
|
||
const uint32_t hx3602_wear_thre_low = 4000;
|
||
const uint32_t hx3602_agc_adj_thre_high = 450000;
|
||
const uint32_t hx3602_agc_adj_thre_low = 150000;
|
||
|
||
static int32_t check_touch_data_min = 300000;
|
||
static int32_t check_touch_data_max = 0;
|
||
static int32_t check_touch_data_fifo[8] = {0};
|
||
|
||
static uint8_t agc_cnt = 0;
|
||
static uint8_t agc_offset = 0;
|
||
static uint8_t check_touch_cnt = 0;
|
||
|
||
/**********************************************************************************************************************
|
||
* LOCAL FUNCTIONS
|
||
*/
|
||
static bool Hrs3602_write_reg(uint8_t addr, uint8_t data)
|
||
{
|
||
if(hrsensor_write_reg(addr, data) != 0){
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static bool Hrs3602_read_reg(uint8_t addr, uint8_t *recvbuf)
|
||
{
|
||
if(hrsensor_read_reg(addr, recvbuf, 1) != 0){
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static bool Hrs3602_brust_read_reg(uint8_t addr, uint8_t *buf, uint8_t length)
|
||
{
|
||
if(hrsensor_read_reg(addr, buf, length) != 0){
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static void Hrs3602_driv_init(void)
|
||
{
|
||
wear_status = MSG_CHECK_INIT;
|
||
wear_status_pre = MSG_CHECK_INIT;
|
||
agc_cnt = 0;
|
||
agc_offset = 0;
|
||
check_touch_cnt = 10;
|
||
}
|
||
|
||
static void Hrs3602_read_data_packet(void)
|
||
{
|
||
uint8_t databuf1[6] = {0};
|
||
uint8_t databuf2[6] = {0};
|
||
int32_t P0 = 0, P1 = 0, P2 = 0, P3 = 0;
|
||
Hrs3602_brust_read_reg(0xa0, databuf1, 6);
|
||
Hrs3602_brust_read_reg(0xa6, databuf2, 6);
|
||
|
||
P0 = ((databuf1[0]) | (databuf1[1] << 8) | (databuf1[2] << 16));
|
||
P1 = ((databuf1[3]) | (databuf1[4] << 8) | (databuf1[5] << 16));
|
||
P2 = ((databuf2[0]) | (databuf2[1] << 8) | (databuf2[2] << 16));
|
||
P3 = ((databuf2[3]) | (databuf2[4] << 8) | (databuf2[5] << 16));
|
||
Hrs3602_brust_read_reg(0xa0, databuf1, 6);
|
||
Hrs3602_brust_read_reg(0xa6, databuf2, 6);
|
||
// DEBUG_PRINTF("%d %d %d %d" ,P0,P1,P2,P3);
|
||
}
|
||
|
||
static bool Hrs3602_read_hrs(int32_t *hrm_data, int32_t *als_data)
|
||
{
|
||
uint8_t databuf[6] = {0};
|
||
int32_t P0 = 0, P1 = 0;
|
||
Hrs3602_brust_read_reg(0xa0, databuf, 6);
|
||
|
||
P0 = ((databuf[0]) | (databuf[1] << 8) | (databuf[2] << 16));
|
||
P1 = ((databuf[3]) | (databuf[4] << 8) | (databuf[5] << 16));
|
||
// DEBUG_PRINTF(0," %d %d " , P0, P1);
|
||
if (P0 > P1)
|
||
{
|
||
*hrm_data = P0 - P1;
|
||
}
|
||
else
|
||
{
|
||
*hrm_data = 0;
|
||
}
|
||
*als_data = P0;
|
||
|
||
return 0;
|
||
}
|
||
|
||
static bool Hrs3602_read_ps1(int32_t *infrared_data)
|
||
{
|
||
uint8_t databuf[6] = {0};
|
||
int32_t P0 = 0, P1 = 0;
|
||
Hrs3602_brust_read_reg(0xa6, databuf, 6);
|
||
P0 = ((databuf[0]) | (databuf[1] << 8) | (databuf[2] << 16));
|
||
P1 = ((databuf[3]) | (databuf[4] << 8) | (databuf[5] << 16));
|
||
if (P0 > P1)
|
||
{
|
||
*infrared_data = P0 - P1;
|
||
}
|
||
else
|
||
{
|
||
*infrared_data = 0;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static bool Hrs3602_chip_init(void)
|
||
{
|
||
int i = 0;
|
||
uint8_t chip_id = 0;
|
||
|
||
Hrs3602_read_reg(0x00, &chip_id);
|
||
if (chip_id != 0x22)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
for (i = 0; i < INIT_ARRAY_SIZE; i++)
|
||
{
|
||
if (Hrs3602_write_reg(init_register_array[i][0], init_register_array[i][1]) != 0)
|
||
{
|
||
return -2;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
static void Hrs3602_check_touch(int32_t infrared_data)
|
||
{
|
||
if (infrared_data > hx3602_wear_thre_high)
|
||
{
|
||
if (check_touch_cnt >= 20)
|
||
{
|
||
check_touch_cnt = 20;
|
||
wear_status = MSG_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_normal_power();
|
||
tyhx_hrs_alg_open_deep();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt++;
|
||
}
|
||
}
|
||
else if (infrared_data < hx3602_wear_thre_low)
|
||
{
|
||
if (check_touch_cnt <= 0)
|
||
{
|
||
check_touch_cnt = 0;
|
||
wear_status = MSG_NO_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_low_power();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt--;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void Hrs3602_check_touch_diff(int32_t infrared_data)
|
||
{
|
||
uint8_t ii = 0, jj = 0;
|
||
int32_t ir_data_temp = 0;
|
||
int32_t check_fifo[8];
|
||
int32_t check_data_sum = 0;
|
||
int32_t check_data_ave = 0;
|
||
|
||
for (ii = 0; ii < 7; ii++)
|
||
{
|
||
check_touch_data_fifo[ii] = check_touch_data_fifo[ii + 1];
|
||
check_fifo[ii] = check_touch_data_fifo[ii];
|
||
check_data_sum = check_data_sum + check_touch_data_fifo[ii];
|
||
}
|
||
check_touch_data_fifo[7] = infrared_data;
|
||
check_fifo[7] = check_touch_data_fifo[7];
|
||
check_data_sum = check_data_sum + check_touch_data_fifo[7];
|
||
|
||
for (ii = 0; ii < 7; ii++)
|
||
{
|
||
for (jj = 0; jj < 7 - ii; jj++)
|
||
{
|
||
if (check_fifo[jj] > check_fifo[jj + 1])
|
||
{
|
||
ir_data_temp = check_fifo[jj];
|
||
check_fifo[jj] = check_fifo[jj + 1];
|
||
check_fifo[jj + 1] = ir_data_temp;
|
||
}
|
||
}
|
||
}
|
||
if (abs(check_fifo[7] - check_fifo[0]) < 4000 && check_fifo[0] > 0)
|
||
{
|
||
check_data_ave = check_data_sum >> 3;
|
||
}
|
||
|
||
if (check_data_ave < check_touch_data_min && check_data_ave > 0)
|
||
{
|
||
check_touch_data_min = check_data_ave;
|
||
}
|
||
if (check_data_ave > check_touch_data_max && check_data_ave > 0)
|
||
{
|
||
check_touch_data_max = check_data_ave;
|
||
}
|
||
|
||
if (check_touch_data_max > 0 && check_touch_data_min > 0 && check_touch_data_max > check_touch_data_min + hx3602_wear_thre_high)
|
||
{
|
||
if (infrared_data > check_touch_data_min + hx3602_wear_thre_high)
|
||
{
|
||
if (check_touch_cnt >= 20)
|
||
{
|
||
check_touch_cnt = 20;
|
||
wear_status = MSG_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_normal_power();
|
||
tyhx_hrs_alg_open_deep();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt++;
|
||
}
|
||
}
|
||
else if (infrared_data < check_touch_data_min + hx3602_wear_thre_low)
|
||
{
|
||
if (check_touch_cnt <= 0)
|
||
{
|
||
check_touch_cnt = 0;
|
||
wear_status = MSG_NO_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_low_power();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt--;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (infrared_data > hx3602_wear_thre_high)
|
||
{
|
||
if (check_touch_cnt >= 20)
|
||
{
|
||
check_touch_cnt = 20;
|
||
wear_status = MSG_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_normal_power();
|
||
tyhx_hrs_alg_open_deep();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt++;
|
||
}
|
||
}
|
||
else if (infrared_data < hx3602_wear_thre_low)
|
||
{
|
||
if (check_touch_cnt <= 0)
|
||
{
|
||
check_touch_cnt = 0;
|
||
wear_status = MSG_NO_TOUCH;
|
||
if (wear_status != wear_status_pre)
|
||
{
|
||
Hrs3602_low_power();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
check_touch_cnt--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void Hrs3602_alg_config(void)
|
||
{
|
||
/*para init begin ....*/
|
||
uint32_t prf_temp_clk_num = 0; /*temperatrue phase clk num in each prf */
|
||
uint32_t prf_hrs_clk_num = 0; /*hrs phase clk num in each prf */
|
||
uint32_t prf_ps_clk_num =0; /*ps phase clk num in each prf */
|
||
uint32_t prf_wait_clk_num =0; /*wait time clk num in each prf */
|
||
uint32_t en2rst_delay_clk_num =0; /*en signal to first reset delay time clk num in each prf */
|
||
uint16_t rst_clk_num = 0;
|
||
uint16_t hrs_ckafe_clk_num = 0;
|
||
uint16_t ps_ckafe_clk_num = 0;
|
||
|
||
|
||
/*para init end ....*/
|
||
|
||
/*chip config begin ....*/
|
||
uint16_t sample_rate = 25; /*config the data rate of chip frog2 ,uint is Hz*/
|
||
uint32_t prf_clk_num = 2620000/sample_rate; /*period in clk num, num = Fclk/fs */
|
||
|
||
uint8_t temperature_enable = 0; /*temperature test function enable , 1 mean enable ; 0 mean disable */
|
||
uint8_t hrs_enable = 1; /*hrs function enable , 1 mean enable ; 0 mean disable */
|
||
uint8_t ps_enable = 1; /*ps function enable , 1 mean enable ; 0 mean disable */
|
||
|
||
uint8_t temperature_adc_osr = 0; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
uint8_t hrs_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
uint8_t ps_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
|
||
uint8_t led_dr_cfg = 3 ; /* 0 = 12.5mA ; 1 = 25mA ; 2 =50mA(default) 3 = 100mA*/
|
||
uint8_t tia_res = 2 ; /* 0 = 54k(default) ; 1 = 108k ; 2 =216k 3 = 432k */
|
||
|
||
en2rst_delay_clk_num = 64 ; /* 0 ~ 127 clk num config */
|
||
rst_clk_num = 6 ; /* range from 0 to 7 ; 0=1 , 1=3, 2=7,....,7=255 */
|
||
hrs_ckafe_clk_num = 128 ; /* hrm phase led on time : 0~ 255 , 实际宽度10位,低两位默认为0*/
|
||
ps_ckafe_clk_num = 10 ; /* ps phase led on time : 0~ 255 , 实际宽度10位,低两位默认为0*/
|
||
/*红外离pd远的要适当调大, 比如苹果结构距离9mm的, 可以设置到96以上*/
|
||
|
||
/*计算PRF_WAIT的时间*/
|
||
if(temperature_enable == 1)
|
||
{
|
||
prf_temp_clk_num = (en2rst_delay_clk_num + 10) + 2*((2<<rst_clk_num) - 1) + 2*(128<<temperature_adc_osr);
|
||
}
|
||
|
||
if(hrs_enable == 1)
|
||
{
|
||
prf_hrs_clk_num = (en2rst_delay_clk_num + 10) +
|
||
2*(2*((2<<rst_clk_num) - 1) + (hrs_ckafe_clk_num<<4) + 10 + (128<<hrs_adc_osr));
|
||
}
|
||
|
||
if(ps_enable == 1)
|
||
{
|
||
prf_ps_clk_num = (en2rst_delay_clk_num + 10) +
|
||
2*(2*((2<<rst_clk_num) - 1) + (ps_ckafe_clk_num<<4) + 10 + (128<<ps_adc_osr));
|
||
}
|
||
|
||
prf_wait_clk_num = prf_clk_num - prf_temp_clk_num - prf_hrs_clk_num - prf_ps_clk_num ;
|
||
/*计算PRF_WAIT的时间*/
|
||
|
||
Hrs3602_write_reg(0xc1, 0x08); // config external pd as input and cap mode enable
|
||
Hrs3602_write_reg(0x03, 0x8f); // all phase use same external pd
|
||
|
||
/*register configration begin ....*/
|
||
|
||
Hrs3602_write_reg(0x01, (temperature_enable<<2)|temperature_adc_osr);
|
||
Hrs3602_write_reg(0x02, (hrs_enable<<2)|(hrs_adc_osr)|(ps_adc_osr<<4)|(ps_enable<<6));
|
||
|
||
|
||
Hrs3602_write_reg(0x04, hrs_ckafe_clk_num);
|
||
Hrs3602_write_reg(0x05, ps_ckafe_clk_num);
|
||
|
||
|
||
Hrs3602_write_reg(0x0a, prf_wait_clk_num);
|
||
Hrs3602_write_reg(0x0b, prf_wait_clk_num>>8);
|
||
Hrs3602_write_reg(0x0c, prf_wait_clk_num>>16);
|
||
|
||
Hrs3602_write_reg(0x11, rst_clk_num);
|
||
Hrs3602_write_reg(0x12, en2rst_delay_clk_num);
|
||
|
||
//GPIO config
|
||
Hrs3602_write_reg(0xc0, (0x84 | led_dr_cfg)); /* led dr config , 0x84 = 12.5mA , 0x85 = 25mA ,0x86 = 50 mA ,0x87 = 100mA */
|
||
Hrs3602_write_reg(0xc2, (0x00 | tia_res)); /* tia res config , 0x00 = 54K , 0x01 = 108K ,0x02 = 216K ,0x03 = 432K */
|
||
/*register configration end ....*/
|
||
Hrs3602_write_reg(0x09, 0x02 );
|
||
|
||
#ifdef IR_CHECK_TOUCH
|
||
Hrs3602_write_reg(0X14, 0x80);
|
||
Hrs3602_write_reg(0X15, 0x40);
|
||
#else
|
||
Hrs3602_write_reg(0X14, 0x40);
|
||
Hrs3602_write_reg(0X15, 0x40);
|
||
#endif
|
||
|
||
#ifdef TIMER_READ_MODE
|
||
Hrs3602_write_reg( 0x07, 0x00 );
|
||
Hrs3602_write_reg( 0x08, 0x00 ); // self clear int
|
||
|
||
#else //int mode
|
||
Hrs3602_write_reg( 0x07, 0x01 );
|
||
Hrs3602_write_reg( 0x08, 0x00 ); // self clear int
|
||
#endif
|
||
return ;
|
||
}
|
||
|
||
static hr_wear_status_t Hrs3602_agc(int32_t als_raw_data, int32_t infrared_data)
|
||
{
|
||
#ifdef CHECK_TOUCH_DIFF
|
||
Hrs3602_check_touch_diff(infrared_data);
|
||
#else
|
||
Hrs3602_check_touch(infrared_data);
|
||
#endif
|
||
|
||
if (wear_status == MSG_TOUCH)
|
||
{
|
||
if (als_raw_data > hx3602_agc_adj_thre_high)
|
||
{
|
||
if (agc_cnt == 3)
|
||
{
|
||
agc_cnt = 0;
|
||
if (agc_offset < 32)
|
||
{
|
||
agc_offset++;
|
||
Hrs3602_write_reg(0x15, (0x40 | agc_offset));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
agc_cnt++;
|
||
}
|
||
}
|
||
else if (als_raw_data < hx3602_agc_adj_thre_low)
|
||
{
|
||
if (agc_cnt == 3)
|
||
{
|
||
agc_cnt = 0;
|
||
if (agc_offset > 0)
|
||
{
|
||
agc_offset--;
|
||
Hrs3602_write_reg(0x15, (0x40 | agc_offset));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
agc_cnt++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
agc_cnt = 0;
|
||
agc_offset = 0;
|
||
}
|
||
wear_status_pre = wear_status;
|
||
// DEBUG_PRINTF("min=%d ir=%d status=%d offset=%d" ,check_touch_data_min, infrared_data, wear_status, agc_offset);
|
||
return wear_status;
|
||
}
|
||
|
||
/**********************************************************************************************************************
|
||
* PUBLIC FUNCTIONS
|
||
*/
|
||
void Hrs3602_wear_config(void)
|
||
{
|
||
/*para init begin ....*/
|
||
uint32_t prf_temp_clk_num = 0; /*temperatrue phase clk num in each prf */
|
||
uint32_t prf_hrs_clk_num = 0; /*hrs phase clk num in each prf */
|
||
uint32_t prf_ps_clk_num =0; /*ps phase clk num in each prf */
|
||
uint32_t prf_wait_clk_num =0; /*wait time clk num in each prf */
|
||
uint32_t en2rst_delay_clk_num =0; /*en signal to first reset delay time clk num in each prf */
|
||
uint16_t rst_clk_num = 0;
|
||
uint16_t hrs_ckafe_clk_num = 0;
|
||
uint16_t ps_ckafe_clk_num = 0;
|
||
|
||
uint16_t sample_rate = 25; /*config the data rate of chip frog2 ,uint is Hz*/
|
||
uint32_t prf_clk_num = 2620000/sample_rate; /*period in clk num, num = Fclk/fs */
|
||
|
||
uint8_t temperature_enable = 0; /*temperature test function enable , 1 mean enable ; 0 mean disable */
|
||
uint8_t hrs_enable = 0; /*hrs function enable , 1 mean enable ; 0 mean disable */
|
||
uint8_t ps_enable = 1; /*ps function enable , 1 mean enable ; 0 mean disable */
|
||
|
||
uint8_t temperature_adc_osr = 0; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
uint8_t hrs_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
uint8_t ps_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ;*/
|
||
|
||
uint8_t led_dr_cfg = 3 ; /* 0 = 12.5mA ; 1 = 25mA ; 2 =50mA(default) 3 = 100mA*/
|
||
uint8_t tia_res = 2 ; /* 0 = 54k(default) ; 1 = 108k ; 2 =216k 3 = 432k */
|
||
|
||
en2rst_delay_clk_num = 64 ; /* 0 ~ 127 clk num config */
|
||
rst_clk_num = 6 ; /* range from 0 to 7 ; 0=1 , 1=3, 2=7,....,7=255 */
|
||
hrs_ckafe_clk_num = 4 ; /* hrm phase led on time : 0~ 255 , 实际宽度10位,低两位默认为0*/
|
||
ps_ckafe_clk_num = 16 ; /* ps phase led on time : 0~ 255 , 实际宽度10位,低两位默认为0*/
|
||
|
||
|
||
/*计算PRF_WAIT的时间*/
|
||
if(temperature_enable == 1)
|
||
{
|
||
prf_temp_clk_num = (en2rst_delay_clk_num + 10) + 2*((2<<rst_clk_num) - 1) + 2*(128<<temperature_adc_osr);
|
||
}
|
||
|
||
if(hrs_enable == 1)
|
||
{
|
||
prf_hrs_clk_num = (en2rst_delay_clk_num + 10) +
|
||
2*(2*((2<<rst_clk_num) - 1) + (hrs_ckafe_clk_num<<4) + 10 + (128<<hrs_adc_osr));
|
||
}
|
||
|
||
if(ps_enable == 1)
|
||
{
|
||
prf_ps_clk_num = (en2rst_delay_clk_num + 10) +
|
||
2*(2*((2<<rst_clk_num) - 1) + (ps_ckafe_clk_num<<4) + 10 + (128<<ps_adc_osr));
|
||
}
|
||
|
||
prf_wait_clk_num = prf_clk_num - prf_temp_clk_num - prf_hrs_clk_num - prf_ps_clk_num ;
|
||
/*计算PRF_WAIT的时间*/
|
||
|
||
Hrs3602_write_reg(0xc1, 0x08); // config external pd as input and cap mode enable
|
||
Hrs3602_write_reg(0x03, 0x8f); // all phase use same external pd
|
||
|
||
/*register configration begin ....*/
|
||
|
||
Hrs3602_write_reg(0x01, (temperature_enable<<2)|temperature_adc_osr);
|
||
Hrs3602_write_reg(0x02, (hrs_enable<<2)|(hrs_adc_osr)|(ps_adc_osr<<4)|(ps_enable<<6));
|
||
|
||
Hrs3602_write_reg(0x04, hrs_ckafe_clk_num);
|
||
Hrs3602_write_reg(0x05, ps_ckafe_clk_num);
|
||
|
||
Hrs3602_write_reg(0x0a, prf_wait_clk_num);
|
||
Hrs3602_write_reg(0x0b, prf_wait_clk_num>>8);
|
||
Hrs3602_write_reg(0x0c, prf_wait_clk_num>>16);
|
||
|
||
Hrs3602_write_reg(0x11, rst_clk_num);
|
||
Hrs3602_write_reg(0x12, en2rst_delay_clk_num);
|
||
|
||
//GPIO config
|
||
Hrs3602_write_reg(0xc0, (0x84 | led_dr_cfg)); /* led dr config , 0x84 = 12.5mA , 0x85 = 25mA ,0x86 = 50 mA ,0x87 = 100mA */
|
||
Hrs3602_write_reg(0xc2, (0x00 | tia_res)); /* tia res config , 0x00 = 54K , 0x01 = 108K ,0x02 = 216K ,0x03 = 432K */
|
||
/*register configration end ....*/
|
||
Hrs3602_write_reg(0x09, 0x02);
|
||
|
||
#ifdef IR_CHECK_TOUCH
|
||
Hrs3602_write_reg(0X14, 0x80);
|
||
Hrs3602_write_reg(0X15, 0x40);
|
||
#else
|
||
Hrs3602_write_reg(0X14, 0x40);
|
||
Hrs3602_write_reg(0X15, 0x40);
|
||
#endif
|
||
Hrs3602_write_reg(0x16, 0x04);
|
||
Hrs3602_write_reg(0x07, 0x00);
|
||
Hrs3602_write_reg(0x08, 0x00);
|
||
|
||
return ;
|
||
}
|
||
|
||
void Hrs3602_write_efuse(void)
|
||
{
|
||
Hrs3602_write_reg(0x85, 0x20);
|
||
Hrs3602_write_reg(0x7f, 0x10);
|
||
Hrs3602_write_reg(0x80, 0x08);
|
||
Hrs3602_write_reg(0x81, 0x44);
|
||
Hrs3602_write_reg(0x82, 0x40);
|
||
Hrs3602_write_reg(0x85, 0x00);
|
||
}
|
||
|
||
void Hrs3602_chip_disable(void)
|
||
{
|
||
Hrs3602_write_reg(0x09, 0x03);
|
||
}
|
||
|
||
void Hrs3602_low_power(void)
|
||
{
|
||
Hrs3602_write_reg(0x02, 0x70);
|
||
Hrs3602_write_reg(0x15, 0x40);
|
||
// Hrs3602_write_reg(0xc0, 0x87); /* led dr config , 0x84 = 12.5mA , 0x85 = 25mA ,0x86 = 50 mA ,0x87 = 100mA */
|
||
Hrs3602_write_reg(0x16, 0x31); // detect interval is 1s when loss
|
||
}
|
||
|
||
void Hrs3602_normal_power(void)
|
||
{
|
||
Hrs3602_write_reg(0x02, 0x77);
|
||
// Hrs3602_write_reg(0xc0, 0x87);
|
||
Hrs3602_write_reg(0x16, 0x00); // detect interval is 40mS
|
||
}
|
||
|
||
void Hrs3602_int_clear(void)
|
||
{
|
||
Hrs3602_write_reg(0x06, 0x7f);
|
||
return;
|
||
}
|
||
|
||
int tjd_hrx3602_init(void)
|
||
{
|
||
int ret;
|
||
|
||
if((ret = Hrs3602_chip_init()) != 0){
|
||
static_print_info("Hrs3602_chip_init fail");
|
||
return -1;
|
||
}else{
|
||
static_print_info("Hrs3602_chip_init succ");
|
||
}
|
||
Hrs3602_alg_config();
|
||
Hrs3602_driv_init();
|
||
tyhx_hrs_alg_open(); //算法初始化
|
||
return 0;
|
||
}
|
||
|
||
hrsensor_data_t tjd_hrx3602_processing_handle(int16_t *gsensor_data)
|
||
{
|
||
int32_t hrm_raw_data;
|
||
int32_t als_raw_data;
|
||
int32_t infrared_data;
|
||
|
||
hrsensor_data_t hrsensor_data;
|
||
hr_wear_status_t wear_status = MSG_NO_TOUCH;
|
||
hrs_results_t hr_alg_results = {MSG_HRS_ALG_NOT_OPEN, 0, 0, 0, 0, 0, 0, 0};
|
||
bp_results_t bp_alg_results = {MSG_BP_ALG_NOT_OPEN, 0, 0, 0, 0, false};
|
||
|
||
Hrs3602_read_hrs(&hrm_raw_data, &als_raw_data);
|
||
Hrs3602_read_ps1(&infrared_data);
|
||
|
||
// static_print_info("hrm_raw_data:%d als_raw_data:%d", hrm_raw_data, als_raw_data);
|
||
// static_print_info("gsensor_data:%d %d %d\n", gsensor_data[0], gsensor_data[1], gsensor_data[2]);
|
||
|
||
wear_status = Hrs3602_agc(als_raw_data, infrared_data);
|
||
if (wear_status == MSG_TOUCH)
|
||
{
|
||
tyhx_hrs_alg_send_data(&hrm_raw_data, 1, gsensor_data+0,gsensor_data+1,gsensor_data+2);
|
||
hr_alg_results = tyhx_hrs_alg_get_results();
|
||
bp_alg_results = tyhx_alg_get_bp_results();
|
||
}
|
||
// static_print_info("HR=%d, wear_status=%d", hr_alg_results.hr_result, wear_status);
|
||
hrsensor_data.wear_status = wear_status;
|
||
hrsensor_data.hr_result = hr_alg_results.hr_result;
|
||
hrsensor_data.sbp_result = bp_alg_results.sbp;
|
||
hrsensor_data.dbp_result = bp_alg_results.dbp;
|
||
|
||
return hrsensor_data;
|
||
}
|
||
|