123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- #include "system/includes.h"
- #include "code_switch.h"
- #include "app_config.h"
- #include "stdlib.h"
- #if TCFG_CODE_SWITCH_ENABLE
- #if 1
- #define log_debug printf
- #else
- #define log_debug(...)
- #endif
- #define INPUT_CHANNLE6_SRC_SEL(x) SFR(JL_IOMAP->CON4, 16, 6, x)
- #define INPUT_CHANNLE7_SRC_SEL(x) SFR(JL_IOMAP->CON4, 24, 6, x)
- static SW_PLATFORM_DATA *sw_pdata = NULL;
- static u8 code_switch_active = 0;
- static void code_switch_event_to_usr(u8 event, s8 sw_val);
- static void get_code_value_handler(void *priv);
- /* static void get_code_value_handler(void); */
- static u8 code_switch_idle_query(void);
- static void code_switch_event_to_usr(u8 event, s8 sw_val)
- {
- struct sys_event e;
- e.type = SYS_DEVICE_EVENT;
- e.arg = "code_switch";
- e.u.codesw.event = event;
- e.u.codesw.value = sw_val;
- sys_event_notify(&e);
- }
- /* ___interrupt */
- /* static void get_code_value_handler(void) */
- /* { */
- /* if (JL_RDEC->CON & 0x80) */
- /* { */
- /* mouse_code_switch_event_to_usr(0, JL_RDEC->DAT); */
- /* JL_RDEC->CON |= BIT(6); */
- /* } */
- /* } */
- /* */
- u8 code_postive_list[] = {
- ((0x00 << 4) | (0x02 << 2) | (0x03 << 0)), \
- ((0x00 << 4) | (0x02 << 2) | (0x01 << 0)), \
- ((0x00 << 4) | (0x03 << 2) | (0x01 << 0)), \
- ((0x02 << 4) | (0x03 << 2) | (0x01 << 0)), \
- ((0x02 << 4) | (0x03 << 2) | (0x00 << 0)), \
- ((0x02 << 4) | (0x01 << 2) | (0x00 << 0)), \
- ((0x03 << 4) | (0x01 << 2) | (0x00 << 0)), \
- ((0x03 << 4) | (0x01 << 2) | (0x02 << 0)), \
- ((0x03 << 4) | (0x00 << 2) | (0x02 << 0)), \
- ((0x01 << 4) | (0x00 << 2) | (0x02 << 0)), \
- ((0x01 << 4) | (0x00 << 2) | (0x03 << 0)), \
- ((0x01 << 4) | (0x02 << 2) | (0x03 << 0))
- };
- u8 code_negative_list[] = {
- ((0x00 << 4) | (0x01 << 2) | (0x03 << 0)), \
- ((0x00 << 4) | (0x01 << 2) | (0x02 << 0)), \
- ((0x00 << 4) | (0x03 << 2) | (0x02 << 0)), \
- ((0x01 << 4) | (0x03 << 2) | (0x02 << 0)), \
- ((0x01 << 4) | (0x03 << 2) | (0x00 << 0)), \
- ((0x01 << 4) | (0x02 << 2) | (0x00 << 0)), \
- ((0x03 << 4) | (0x02 << 2) | (0x00 << 0)), \
- ((0x03 << 4) | (0x02 << 2) | (0x01 << 0)), \
- ((0x03 << 4) | (0x00 << 2) | (0x01 << 0)), \
- ((0x02 << 4) | (0x00 << 2) | (0x01 << 0)), \
- ((0x02 << 4) | (0x00 << 2) | (0x03 << 0)), \
- ((0x02 << 4) | (0x01 << 2) | (0x03 << 0))
- };
- //功能:相位纠正
- static void correct_code(u8 *code_data, u8 *list_data, u8 idx)
- {
- code_data[2] = (list_data[(idx / 3) * 3] & (0x03 << 4)) >> 4;
- code_data[1] = (list_data[(idx / 3) * 3] & (0x03 << 2)) >> 2;
- code_data[0] = (list_data[(idx / 3) * 3] & (0x03 << 0)) >> 0;
- log_debug("lost_phase_recover: %d %d %d\n", code_data[2], code_data[1], code_data[0]);
- }
- //功能:相位遍历
- static u8 traverse_phase_list(u8 *code_data, u8 *list_data, u8 size)
- {
- u8 code_num = 0, idx = 0;
- code_num = code_data[2] << 4 | code_data[1] << 2 | code_data[0] << 0;
- for (idx = 0; idx < size; idx++) {
- if (code_num == list_data[idx]) {
- if (idx % 3) {
- /* correct_code(code_data, list_data, idx); */
- }
- break;
- }
- }
- return idx;
- }
- //功能:消抖
- static bool code_phase_debounce(u8 code_val)
- {
- static u8 filter_value = 0, filter_cnt = 0;
- const u8 filter_time = 2;
- //当前值与上一次值如果不相等, 重新消抖处理, 注意filter_time != 0;
- if (code_val != filter_value && filter_time) {
- filter_cnt = 0; //消抖次数清0, 重新开始消抖
- filter_value = code_val;//记录上一次的值
- return false; //第一次检测, 返回不做处理
- }
- //当前值与上一次值相等, filter_cnt开始累加;
- if (filter_cnt < filter_time) {
- filter_cnt++;
- return false;
- }
- return true;
- }
- //功能:获取相位
- static bool get_code_phase(u8 *code_data)
- {
- static u8 code_now = 0, code_last = 0;
- static u8 debug_count = 0;
- //获取相位值
- code_last = code_now;
- code_now = (gpio_read(sw_pdata->a_phase_io) ? 0x02 : 0x00) + (gpio_read(sw_pdata->b_phase_io) ? 0x01 : 0x00);
- //相位状态出现变化,将相位值存入队列
- if (code_last != code_now && code_now != code_data[0]) {
- code_data[2] = code_data[1];
- code_data[1] = code_data[0];
- code_data[0] = code_now;
- code_switch_active = 200;//编码开关工作状态标志位
- /* log_debug(">>>%d<<<%d %d %d\n", debug_count, code_data[2], code_data[1], code_data[0]); */
- debug_count++;
- return true;
- }
- //相位状态无变化,编码开关工作状态标志位递减
- else {
- if (code_switch_active) {
- code_switch_active--;
- }
- }
- return false;
- }
- //功能:获取编码值
- u8 get_code_value(u8 *code_data)
- {
- u8 idx = 0; //相位序列号
- static u8 code_val = 0;
- static u8 move_now = 0, move_last = 0;
- static u8 idx_pos_last = 0, idx_neg_last = 0;
- enum {
- MOVE_POS,
- MOVE_NEG,
- };
- //正相位遍历,获取相位序列号
- idx = traverse_phase_list(code_data, &code_postive_list[0], ARRAY_SIZE(code_postive_list));
- //相位序列号有效,则出现正向滚动动作
- if (idx < ARRAY_SIZE(code_postive_list)) {
- move_last = move_now;
- move_now = MOVE_POS;
- //相位区域限制,避免重复检测
- if ((idx >= 0 && idx <= 2) || (idx >= 6 && idx <= 8) || (move_now != move_last))
- /* if (abs(idx_pos_last/3-idx/3)>=2 || (move_now != move_last)) */
- {
- code_val++; //正向滚动,编码值+1
- idx_pos_last = idx;
- /* log_debug(">>>>>>>>>>>>>>>>>>>>>>>idx = %d R\n", idx); */
- /* log_debug("\n"); */
- return code_val;
- }
- }
- //负相位遍历,获取相位序列号
- idx = traverse_phase_list(code_data, &code_negative_list[0], ARRAY_SIZE(code_negative_list));
- //相位序列号有效,则出现负向滚动
- if (idx < ARRAY_SIZE(code_negative_list)) {
- move_last = move_now;
- move_now = MOVE_NEG;
- //相位区域限制,避免重复检测
- if ((idx >= 3 && idx <= 5) || (idx >= 9 && idx <= 11) || (move_now != move_last))
- /* if (abs(idx_neg_last/3-idx/3)>=2 || (move_now != move_last)) */
- {
- code_val--; //负向滚动,编码值-1
- idx_neg_last = idx;
- /* log_debug(">>>>>>>>>>>>>>>>>>>>>>>idx = %d L\n", idx); */
- /* log_debug("\n"); */
- return code_val;
- }
- }
- return code_val;
- }
- //功能:旋转编码开关检测
- static u8 code_switch_detector(void)
- {
- static u8 code_table[3] = {0}; //相位值存储队列
- static u8 code_val = 0;
- //相位有变化,进行相位遍历,获取编码值
- if (get_code_phase(&code_table[0])) {
- code_val = get_code_value(&code_table[0]);
- }
- //相位无变化,编码值保持不变
- else {
- code_val = code_val;
- }
- return code_val;
- }
- //功能:旋转编码开关数据采集
- static void code_switch_handler(void *priv)
- {
- static u8 code_val_last = 0;
- static u8 code_val_now = 0;
- code_val_last = code_val_now;
- code_val_now = code_switch_detector();
- if (code_val_last != code_val_now) {
- code_switch_event_to_usr(0, code_val_now - code_val_last);
- }
- /* if (JL_RDEC->DAT != code) */
- /* { */
- /* code_switch_event_to_usr(0, JL_RDEC->DAT - code); */
- /* code_switch_active = 10; */
- /* } */
- /* */
- /* else */
- /* { */
- /* code_switch_active--; */
- /* } */
- /* */
- /* code = JL_RDEC->DAT; */
- /* pnd = JL_RDEC->CON & 0x80; */
- /* if (pnd) */
- /* { */
- /* code_switch_event_to_usr(0, JL_RDEC->DAT); */
- /* JL_RDEC->CON |= BIT(6); */
- /* putchar('Y'); */
- /* CODE_IO_DEBUG_TOGGLE(A,2) */
- /* } */
- }
- void code_switch_init(SW_PLATFORM_DATA *priv)
- {
- sw_pdata = priv;
- /* JL_RDEC->CON |= BIT(0); //Enable RDEC */
- /* JL_RDEC->CON &= ~BIT(1);//pull up */
- /* JL_RDEC->CON |= 15<<2; */
- /* JL_IOMAP->CON1 &= ~BIT(12); //RDES_IOSO = PB4 */
- /* JL_IOMAP->CON1 &= ~BIT(13); //RDES_IOS1 = PB5 */
- /* JL_IOMAP->CON1 |= BIT(12); */
- /* JL_IOMAP->CON1 |= BIT(13); */
- /* INPUT_CHANNLE6_SRC_SEL(sw_pdata->a_phase_io); */
- /* INPUT_CHANNLE7_SRC_SEL(sw_pdata->b_phase_io); */
- gpio_set_die(sw_pdata->a_phase_io, 1);
- gpio_set_dieh(sw_pdata->a_phase_io, 1);
- gpio_set_direction(sw_pdata->a_phase_io, 1);
- gpio_set_pull_up(sw_pdata->a_phase_io, 0);
- gpio_set_pull_down(sw_pdata->a_phase_io, 0);
- gpio_set_die(sw_pdata->b_phase_io, 1);
- gpio_set_dieh(sw_pdata->b_phase_io, 1);
- gpio_set_direction(sw_pdata->b_phase_io, 1);
- gpio_set_pull_up(sw_pdata->b_phase_io, 0);
- gpio_set_pull_down(sw_pdata->b_phase_io, 0);
- /* request_irq(IRQ_RDEC_IDX, 3, code_switch_handler, 0); */
- sys_s_hi_timer_add(NULL, code_switch_handler, 2); //10ms
- }
- static u8 code_switch_idle_query(void)
- {
- /* return !(JL_RDEC->CON & 0x80); */
- return (!code_switch_active);
- }
- REGISTER_LP_TARGET(code_switch_lp_target) = {
- .name = "code_switch",
- .is_idle = code_switch_idle_query,
- };
- #endif /* CODE_SWITCH_ENABLE */
|