347 lines
9.7 KiB
C
347 lines
9.7 KiB
C
|
#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, ®_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
|
|||
|
|