123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- #include "includes.h"
- #include "asm/plcnt.h"
- #include "asm/gpio.h"
- static u8 port_index_mapping_talbe[PLCNT_KEY_CH_MAX] = {0};
- static u32 touch_pre_value[PLCNT_KEY_CH_MAX] = {0};
- static u32 touch_normal_value[PLCNT_KEY_CH_MAX] = {0};
- #define TOUCH_VAL_CALIBRATE_CYCLE (200)//周期大约2秒
- static u32 touch_calibrate_cnt[PLCNT_KEY_CH_MAX] = {0};
- static u32 touch_calibrate_tmp_value[PLCNT_KEY_CH_MAX] = {0};
- static u8 touch_state = 0;
- static const struct touch_key_platform_data *user_data = NULL;
- static JL_PORT_FLASH_TypeDef *PLCNT_IO_PORTx = NULL;
- static u8 PLCNT_IO_xx;
- void plcnt_io_out(struct touch_key_port *key)
- {
- if (key->port > IO_MAX_NUM) {
- return;
- } else if ((key->port / 16) == 0) {
- PLCNT_IO_PORTx = JL_PORTA;
- } else if ((key->port / 16) == 1) {
- PLCNT_IO_PORTx = JL_PORTB;
- }
- PLCNT_IO_xx = key->port % 16;
- PLCNT_IO_PORTx->DIE |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->PU &= ~BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->PD |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->OUT |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->DIR &= ~BIT(PLCNT_IO_xx);
- }
- void plcnt_io_in(struct touch_key_port *key)
- {
- if (key->port > IO_MAX_NUM) {
- return;
- } else if ((key->port / 16) == 0) {
- PLCNT_IO_PORTx = JL_PORTA;
- } else if ((key->port / 16) == 1) {
- PLCNT_IO_PORTx = JL_PORTB;
- }
- PLCNT_IO_xx = key->port % 16;
- PLCNT_IO_PORTx->DIE |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->PU &= ~BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->PD |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->OUT |= BIT(PLCNT_IO_xx);
- PLCNT_IO_PORTx->DIR |= BIT(PLCNT_IO_xx);
- }
- void plcnt_iomc(struct touch_key_port *key)
- {
- //放电计数引脚选择intputchannel2
- gpio_set_fun_input_port(key->port, PFI_GP_ICH6);
- SFR(JL_IOMAP->CON1, 8, 4, 6);
- }
- static u32 key_or = 0;
- void plcnt_flt(u32 cur_val, u32 ch)
- {
- /* printf("ch%d : %d\n", ch, cur_val); */
- //简单滤波
- if (touch_pre_value[ch] == 0) {
- touch_pre_value[ch] = cur_val;
- } else if (cur_val >= touch_pre_value[ch]) {
- touch_pre_value[ch] = touch_pre_value[ch] + (u32)((cur_val - touch_pre_value[ch]) * 0.2f);
- } else {
- touch_pre_value[ch] = touch_pre_value[ch] - (u32)((touch_pre_value[ch] - cur_val) * 0.2f);
- }
- //处理滤波之后的值
- if (touch_pre_value[ch] > (touch_normal_value[ch] + user_data->port_list[ch].press_delta)) {
- key_or |= BIT(ch);
- touch_calibrate_cnt[ch] = 0;
- } else {
- key_or &= ~BIT(ch);
- touch_calibrate_cnt[ch] ++;
- }
- //定期标定常态下的基准值
- if (touch_calibrate_cnt[ch] > TOUCH_VAL_CALIBRATE_CYCLE) {
- touch_normal_value[ch] = touch_calibrate_tmp_value[ch] / 10;
- touch_calibrate_tmp_value[ch] = 0;
- touch_calibrate_cnt[ch] = 0;
- } else if (touch_calibrate_cnt[ch] >= (TOUCH_VAL_CALIBRATE_CYCLE / 2)) {
- if (touch_calibrate_cnt[ch] < ((TOUCH_VAL_CALIBRATE_CYCLE / 2) + 10)) {
- touch_calibrate_tmp_value[ch] += touch_pre_value[ch];
- }
- } else {
- touch_calibrate_tmp_value[ch] = 0;
- }
- }
- void scan_capkey_async(void *priv)
- {
- if (!user_data) {
- return;
- }
- static u8 cur_ch = 0;
- static u32 new_val = 0;
- static u32 old_val = 0;
- u8 pre_ch = cur_ch - 1;
- u8 net_ch = cur_ch + 1;
- if (cur_ch == 0) {
- pre_ch = user_data->num - 1;
- }
- if (net_ch >= user_data->num) {
- net_ch = 0;
- }
- new_val = JL_PCNT->VAL;
- u32 delta_val = 0;
- if (new_val >= old_val) {
- delta_val = new_val - old_val;
- } else {
- delta_val = (u32) - new_val + old_val;
- }
- plcnt_flt(delta_val, pre_ch);
- old_val = JL_PCNT->VAL;
- plcnt_iomc(&(user_data->port_list[cur_ch]));
- plcnt_io_in(&(user_data->port_list[cur_ch]));
- if (net_ch != cur_ch) {
- plcnt_io_out(&(user_data->port_list[net_ch]));
- }
- cur_ch = net_ch;
- }
- void scan_capkey(void *priv)
- {
- if (!user_data) {
- return;
- }
- for (u8 ch = 0; ch < user_data->num; ch ++) {
- plcnt_io_out(&(user_data->port_list[ch]));
- plcnt_iomc(&(user_data->port_list[ch]));
- u32 tmp_val, start_val, end_val, delta_val = 0;
- for (u8 i = 0; i < 5; i ++) {
- delay(100);
- start_val = JL_PCNT->VAL;
- PLCNT_IO_PORTx->DIR |= BIT(PLCNT_IO_xx);
- __asm__ volatile("csync");
- while (PLCNT_IO_PORTx->IN & BIT(PLCNT_IO_xx));
- end_val = JL_PCNT->VAL;
- PLCNT_IO_PORTx->DIR &= ~BIT(PLCNT_IO_xx);
- if (end_val > start_val) {
- tmp_val = end_val - start_val;
- } else {
- tmp_val = (u32) - start_val + end_val;
- }
- delta_val += tmp_val;
- }
- delta_val = delta_val / 5;
- /* printf("%d: %d\n", ch, delta_val); */
- plcnt_flt(delta_val, ch);
- }
- }
- /*
- @brief 引脚放电计数模块初始化
- */
- int plcnt_init(void *_data)
- {
- if (_data == NULL) {
- return -1;
- }
- user_data = (const struct touch_key_platform_data *)_data;
- if (user_data->num > PLCNT_KEY_CH_MAX) {
- return -1;
- }
- for (u8 ch = 0; ch < user_data->num; ch ++) {
- touch_normal_value[ch] = 0 - (2 * user_data->port_list[ch].press_delta);
- }
- for (u8 ch = 0; ch < user_data->num; ch ++) {
- plcnt_iomc(&(user_data->port_list[ch]));
- plcnt_io_out(&(user_data->port_list[ch]));
- }
- JL_PCNT->CON = 0;
- JL_PCNT->CON |= (0b11 << 2); //选择PLL240M为时钟源
- JL_PCNT->CON |= BIT(1); //引脚放电计数使能
- /* sys_s_hi_timer_add(NULL, scan_capkey_async, 2); //2ms */
- sys_s_hi_timer_add(NULL, scan_capkey, 10); //10ms
- return 0;
- }
- static u8 key_filter(u8 key)
- {
- static u8 used_key = 0xff;
- static u8 old_key;
- static u8 key_counter;
- if (old_key != key) {
- key_counter = 0;
- old_key = key;
- } else {
- key_counter++;
- if (key_counter == 3) {
- used_key = key;
- }
- }
- return used_key;
- }
- u8 get_plcnt_value(void)
- {
- /* printf("%d %d %d\n", touch_pre_value[0], touch_pre_value[1], touch_pre_value[2]); */
- static u8 pre_i = 0;
- u8 key_num = 0xff;
- if (key_or) {
- if (key_or & BIT(pre_i)) {
- key_num = pre_i;
- } else {
- for (u8 ch = 0; ch < user_data->num; ch ++) {
- if (key_or & BIT(ch)) {
- key_num = ch;
- pre_i = ch;
- break;
- }
- }
- }
- /* printf("key_num : %d\n", key_num); */
- }
- return key_filter(key_num);
- }
|