KT24-1110_65E-HA-651B/apps/common/device/gSensor/SC7A20.c

347 lines
9.7 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#include "gSensor/SC7A20.h"
#include "gSensor/gSensor_manage.h"
#include "app_config.h"
#include "gSensor/SC7A20.h"
#include "math.h"
#if TCFG_SC7A20_EN
u8 volatile sl_click_timer_en = 0;
#define SL_Sensor_Algo_Release_Enable 1
u8 Click_time = 0X00;
u8 Click_add_flag = 0X00;
u32 SL_MEMS_i2cRead(u8 addr, u8 reg, u8 len, u8 *buf)
{
return _gravity_sensor_get_ndata(addr, reg, buf, len);
}
u8 SL_MEMS_i2cWrite(u8 addr, u8 reg, u8 data)
{
gravity_sensor_command(addr, reg, data);
return 0;
}
char SC7A20_Check()
{
u8 reg_value = 0;
u8 i;
SL_MEMS_i2cRead(SC7A20_R_ADDR, SC7A20_WHO_AM_I, 1, &reg_value);
if (reg_value == 0x11) {
return 0x01;
} else {
return 0x00;
}
}
u8 SC7A20_Config(void)
{
u8 Check_Flag = 0;
u8 write_num = 0, i = 0;
u8 ODR = 0x7f; //400HZ/6f 200HZ
u8 HP = 0x0c; //开启高通滤波
u8 click_int = 0x82; //将Click中断映射到INT1 OVERRUN
u8 range = 0x90; //4g量程
u8 fifo_en = 0x40; //使能fifo
u8 fifo_mode = 0x9d; //Stream模式0-29(WTM30个)
u8 click_mode = 0x15; //单击3轴触发
Check_Flag = SC7A20_Check();
if (Check_Flag == 1) {
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG1, ODR);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG2, HP);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG3, click_int);// click int1
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG4, range);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG5, fifo_en);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_FIFO_CTRL_REG, fifo_mode);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CLICK_CFG, click_mode);//单Z轴
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CLICK_THS, SC7A20_CLICK_TH);//62.6mg(4g)*10
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_TIME_LIMIT, SC7A20_CLICK_WINDOWS);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_TIME_LATENCY, SC7A20_CLICK_LATENCY);
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG6, SC7A20_INT_LEVEL);
printf("check ok\n");
return 0;
} else {
printf("check fail\n");
return -1;
}
}
#if SL_Sensor_Algo_Release_Enable==0
extern signed short SL_DEBUG_DATA[10][128];
extern u8 SL_DEBUG_DATA_LEN;
#endif
u8 sl_pp_num = 0;
u8 SL_Get_CLICK_PP_CNT(u8 fun_flag)
{
if (fun_flag == 0) {
sl_pp_num = 0;
}
return sl_pp_num;
}
unsigned int SL_Click_Sqrt(unsigned int sqrt_data)
{
unsigned int SL_SQRT_LOW, SL_SQRT_UP, SL_SQRT_MID;
u8 sl_sqrt_num = 0;
SL_SQRT_LOW = 0;
SL_SQRT_UP = sqrt_data;
SL_SQRT_MID = (SL_SQRT_UP + SL_SQRT_LOW) / 2;
while (sl_sqrt_num < 200) {
if (SL_SQRT_MID * SL_SQRT_MID > sqrt_data) {
SL_SQRT_UP = SL_SQRT_MID;
} else {
SL_SQRT_LOW = SL_SQRT_MID;
}
if (SL_SQRT_UP - SL_SQRT_LOW == 1) {
if (SL_SQRT_UP * SL_SQRT_UP - sqrt_data > sqrt_data - SL_SQRT_LOW * SL_SQRT_LOW) {
return SL_SQRT_LOW;
} else {
return SL_SQRT_UP;
}
}
SL_SQRT_MID = (SL_SQRT_UP + SL_SQRT_LOW) / 2;
sl_sqrt_num++;
}
return 0;
}
char SC7A20_Click_Read(int TH1, int TH2)
{
u8 i = 0, j = 0, k = 0;
u8 click_num = 0;
u8 fifo_len;
unsigned int sc7a20_data = 0;
unsigned int fifo_data_xyz[32];
u8 click_result = 0x00;
unsigned int click_sum = 0;
u8 data1[6];
signed char data[6];
g_printf("INT_HAPPEN!\r\n");
SL_MEMS_i2cRead(SC7A20_R_ADDR, SC7A20_SRC_REG, 1, &fifo_len);
if ((fifo_len & 0x40) == 0x40) {
fifo_len = 32;
} else {
fifo_len = fifo_len & 0x1f;
}
for (i = 0; i < fifo_len; i++) {
SL_MEMS_i2cRead(SC7A20_R_ADDR, 0xA8, 6, &data1[0]);
data[1] = (signed char)data1[1];
data[3] = (signed char)data1[3];
data[5] = (signed char)data1[5];
sc7a20_data = (data[1]) * (data[1]) + (data[3]) * (data[3]) + (data[5]) * (data[5]);
sc7a20_data = SL_Click_Sqrt(sc7a20_data);
fifo_data_xyz[i] = sc7a20_data;
#if SL_Sensor_Algo_Release_Enable==0
SL_DEBUG_DATA[0][i] = data[1];
SL_DEBUG_DATA[1][i] = data[3];
SL_DEBUG_DATA[2][i] = data[5];
SL_DEBUG_DATA[3][i] = fifo_data_xyz[i];
SL_DEBUG_DATA_LEN = fifo_len;
#endif
}
k = 0;
for (i = 1; i < fifo_len - 1; i++) {
if ((fifo_data_xyz[i + 1] > TH1) && (fifo_data_xyz[i - 1] < 30)) {
g_printf("in_th\r\n");
if (click_num == 0) {
click_sum = 0; //first peak
for (j = 0; j < i - 1; j++) {
if (fifo_data_xyz[j] > fifo_data_xyz[j + 1]) {
click_sum += fifo_data_xyz[j] - fifo_data_xyz[j + 1];
} else {
click_sum += fifo_data_xyz[j + 1] - fifo_data_xyz[j];
}
}
#if SL_Sensor_Algo_Release_Enable==0
g_printf("click_sum:%d!\r\n", click_sum);
#endif
if (click_sum > TH2) {
sl_pp_num++;
break;
}
k = i;
} else {
k = i; //sencond peak
}
}
if (k != 0) {
if (fifo_data_xyz[i - 1] - fifo_data_xyz[i + 1] > TH1 - 10) {
if (i - k < 5) {
click_num = 1;
break;
}
}
}
}
if (click_num == 1) {
click_result = 1;
} else {
click_result = 0;
}
return click_result;
}
//GPIO?????,??INT2
//Service function in Int Function
//u8 sl_click_timer_en =0;
u8 sl_click_status = 0;
unsigned short click_timer_cnt = 0;
unsigned short click_timer_total_cnt = 0;
u8 click_click_final_cnt = 0;
char SC7A20_Click_Alog(void)
{
u8 click_status = 0;
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG3, 0x00);
click_status = SC7A20_Click_Read(SC7A20_TH1, SC7A20_TH2); //40,50
g_printf("click_status = 0x%x\n", click_status);
if (click_status == 1) {
if (sl_click_timer_en == 0) {
//set click timer flag
sl_click_timer_en = 1;
//clear click timer cnt value
click_timer_cnt = 0;
click_timer_total_cnt = 0;
click_click_final_cnt = 0;
}
sl_click_status = 1;
}
SL_MEMS_i2cWrite(SC7A20_W_ADDR, SC7A20_CTRL_REG3, 0x82);
return click_status;
}
//This fuction is execute in 50ms timer when the timer is opened
char SC7A20_click_status(void)
{
u8 click_e_cnt = 0;
if (sl_click_timer_en == 1) {
click_timer_cnt++;
if ((click_timer_cnt < click_pp_num) && (sl_click_status == 1)) {
g_printf("status:%d\r\n", sl_click_status);
g_printf("fin_num:%d\r\n", click_click_final_cnt);
sl_click_status = 0;
click_timer_total_cnt = click_timer_total_cnt + click_timer_cnt;
click_timer_cnt = 0;
click_click_final_cnt++;
}
click_e_cnt = SL_Get_CLICK_PP_CNT(1);
if ((((click_timer_cnt >= click_pp_num) || (click_timer_total_cnt >= click_max_num)) && (click_e_cnt < 1)) ||
((click_timer_cnt >= click_pp_num) && (click_e_cnt > 0)))
// if((click_timer_cnt>=click_pp_num)||(click_timer_total_cnt>=click_max_num))
{
//clear click timer flag
sl_click_timer_en = 0;
//clear click timer cnt value
click_timer_cnt = 0;
click_timer_total_cnt = 0;
g_printf("fin_num:%d\r\n", click_click_final_cnt);
if (click_e_cnt > 0) {
click_e_cnt = SL_Get_CLICK_PP_CNT(0);
return 0;
} else {
return click_click_final_cnt;
}
}
}
return 0;
}
void SC7A20_int_io_detect(u8 int_io_status)
{
static u8 int_io_status_old;
/* u8 int_io_status = 0; */
/* int_io_status = gpio_read(INT_IO); */
if ((int_io_status) && (int_io_status_old == 0)) {
log_e("sc7a20_int_io_detect\n");
SC7A20_Click_Alog();
} else {
}
int_io_status_old = int_io_status;
}
void SC7A20_read_data(axis_info_t *sl_accel)
{
u8 data[6];
u8 fifo_len = 0;
SL_MEMS_i2cRead(SC7A20_R_ADDR, SC7A20_SRC_REG, 1, &fifo_len);
if ((fifo_len & 0x40) == 0x40) {
fifo_len = 32;
} else {
fifo_len = fifo_len & 0x1f;
}
for (u8 i = 0; i < fifo_len; i++) {
SL_MEMS_i2cRead(SC7A20_R_ADDR, 0xA8, 6, data);
sl_accel[i].x = (short)((data[1] << 8) | data[0]);
sl_accel[i].x = sl_accel[i].x >> 4;
sl_accel[i].y = (short)((data[3] << 8) | data[2]);
sl_accel[i].y = sl_accel[i].y >> 4;
sl_accel[i].z = (short)((data[5] << 8) | data[4]);
sl_accel[i].z = sl_accel[i].z >> 4;
/* printf("group:%2d,sl_accel_x:%5d, sl_accel_y:%5d, sl_accel_z:%5d\n", i, sl_accel[i].x, sl_accel[i].y, sl_accel[i].z); */
}
}
void SC7A20_ctl(u8 cmd, void *arg)
{
switch (cmd) {
case GSENSOR_RESET_INT:
break;
case GSENSOR_RESUME_INT:
break;
case GSENSOR_INT_DET:
SC7A20_int_io_detect(*(u8 *)arg);
break;
case READ_GSENSOR_DATA:
SC7A20_read_data((axis_info_t *)arg);
break;
default:
break;
}
}
static u8 sc7a20_idle_query(void)
{
return !sl_click_timer_en;
}
REGISTER_GRAVITY_SENSOR(gSensor) = {
.logo = "sc7a20",
.gravity_sensor_init = SC7A20_Config,
.gravity_sensor_check = SC7A20_click_status,
.gravity_sensor_ctl = SC7A20_ctl,
};
REGISTER_LP_TARGET(sc7a20_lp_target) = {
.name = "sc7a20",
.is_idle = sc7a20_idle_query,
};
#endif