iokey.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "key_driver.h"
  2. #include "iokey.h"
  3. #include "gpio.h"
  4. #include "system/event.h"
  5. #include "app_config.h"
  6. #include "asm/clock.h"
  7. #if TCFG_IOKEY_ENABLE
  8. static const struct iokey_platform_data *__this = NULL;
  9. u8 io_get_key_value(void);
  10. #if MOUSE_KEY_SCAN_MODE
  11. struct key_driver_para iokey_scan_para = {
  12. .scan_time = 5, //按键扫描频率, 单位: ms
  13. .last_key = NO_KEY, //上一次get_value按键值, 初始化为NO_KEY;
  14. .filter_time = 2, //按键消抖延时;
  15. .long_time = 5, //按键判定长按数量
  16. .hold_time = (5 + 0), //按键判定HOLD数量
  17. .click_delay_time = 20, //按键被抬起后等待连击延时数量
  18. .key_type = KEY_DRIVER_TYPE_IO,
  19. .get_value = io_get_key_value,
  20. };
  21. #else
  22. //按键驱动扫描参数列表
  23. struct key_driver_para iokey_scan_para = {
  24. .scan_time = 10, //按键扫描频率, 单位: ms
  25. .last_key = NO_KEY, //上一次get_value按键值, 初始化为NO_KEY;
  26. .filter_time = 4, //按键消抖延时;
  27. .long_time = 75, //按键判定长按数量
  28. .hold_time = (75 + 15), //按键判定HOLD数量
  29. .click_delay_time = 20, //按键被抬起后等待连击延时数量
  30. .key_type = KEY_DRIVER_TYPE_IO,
  31. .get_value = io_get_key_value,
  32. };
  33. #endif
  34. #define MARK_BIT_VALUE(b, v) do {if ((v & (~BIT(7))) < 7) b |= BIT(v & (~BIT(7)));} while(0)
  35. static void key_io_pull_down_input(u8 key_io)
  36. {
  37. gpio_direction_input(key_io);
  38. gpio_set_pull_down(key_io, 1);
  39. gpio_set_pull_up(key_io, 0);
  40. gpio_set_die(key_io, 1);
  41. }
  42. static void key_io_pull_up_input(u8 key_io)
  43. {
  44. gpio_direction_input(key_io);
  45. gpio_set_pull_down(key_io, 0);
  46. gpio_set_pull_up(key_io, 1);
  47. gpio_set_die(key_io, 1);
  48. }
  49. static void key_io_output_high(u8 key_io)
  50. {
  51. gpio_set_pull_down(key_io, 0);
  52. gpio_set_pull_up(key_io, 0);
  53. gpio_direction_output(key_io, 1);
  54. }
  55. static void key_io_output_low(u8 key_io)
  56. {
  57. gpio_set_pull_down(key_io, 0);
  58. gpio_set_pull_up(key_io, 0);
  59. gpio_direction_output(key_io, 0);
  60. }
  61. static int get_io_key_value(u8 key_io)
  62. {
  63. return gpio_read(key_io);
  64. }
  65. static void key_io_reset(void)
  66. {
  67. int i;
  68. for (i = 0; i < __this->num; i++) {
  69. switch (__this->port[i].connect_way) {
  70. case ONE_PORT_TO_HIGH:
  71. key_io_pull_down_input(__this->port[i].key_type.one_io.port);
  72. break;
  73. case ONE_PORT_TO_LOW:
  74. #if (TCFG_IO_MULTIPLEX_WITH_SD == ENABLE)
  75. if (TCFG_MULTIPLEX_PORT != __this->port[i].key_type.one_io.port) {
  76. key_io_pull_up_input(__this->port[i].key_type.one_io.port);
  77. }
  78. #else
  79. key_io_pull_up_input(__this->port[i].key_type.one_io.port);
  80. #endif
  81. break;
  82. case DOUBLE_PORT_TO_IO:
  83. break;
  84. default:
  85. ASSERT(0, "IO KEY CONNECT ERR!!!");
  86. break;
  87. }
  88. }
  89. }
  90. #if MULT_KEY_ENABLE
  91. extern const struct key_remap_data iokey_remap_data;
  92. static u8 iokey_value_remap(u8 bit_mark)
  93. {
  94. for (int i = 0; i < iokey_remap_data.remap_num; i++) {
  95. if (iokey_remap_data.table[i].bit_value == bit_mark) {
  96. return iokey_remap_data.table[i].remap_value;
  97. }
  98. }
  99. return NO_KEY;
  100. }
  101. #endif
  102. #if TCFG_IO_MULTIPLEX_WITH_SD == ENABLE
  103. static u8 mult_key_value = 1;
  104. /* extern const int set_to_close_timer0_delay; */
  105. static void udelay(u32 usec)
  106. {
  107. /* if (set_to_close_timer0_delay) { */
  108. /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */
  109. /* JL_MCPWM->TMR3_CNT = 0; */
  110. /* JL_MCPWM->TMR3_PR = clk_get("lsb") / 1000000 * usec; */
  111. /* JL_MCPWM->TMR3_CON = BIT(10) | BIT(0); */
  112. /* JL_MCPWM->MCPWM_CON0 |= BIT(8 + 3); */
  113. /* while (!(JL_MCPWM->TMR3_CON & BIT(12))); */
  114. /* JL_MCPWM->TMR3_CON = BIT(10); */
  115. /* JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3); */
  116. /* } else { */
  117. JL_TIMER0->CON = BIT(14);
  118. JL_TIMER0->CNT = 0;
  119. JL_TIMER0->PRD = 16 * 1000000L / 1000000L * usec; //1us
  120. JL_TIMER0->CON = BIT(0); //sys clk
  121. while ((JL_TIMER0->CON & BIT(15)) == 0);
  122. JL_TIMER0->CON = BIT(14);
  123. /* } */
  124. }
  125. extern u8 sd_io_suspend(u8 sdx, u8 sd_io);
  126. extern u8 sd_io_resume(u8 sdx, u8 sd_io);
  127. void sd_mult_io_detect(void *arg)
  128. {
  129. static u32 cnt = 0;
  130. if (sd_io_suspend(1, 1) == 0) {
  131. gpio_set_direction(TCFG_MULTIPLEX_PORT, 0);
  132. gpio_write(TCFG_MULTIPLEX_PORT, 0);
  133. udelay(10);
  134. gpio_set_die(TCFG_MULTIPLEX_PORT, 1);
  135. gpio_set_pull_down(TCFG_MULTIPLEX_PORT, 0);
  136. gpio_set_pull_up(TCFG_MULTIPLEX_PORT, 1);
  137. gpio_set_direction(TCFG_MULTIPLEX_PORT, 1);
  138. udelay(10);
  139. mult_key_value = gpio_read(TCFG_MULTIPLEX_PORT);
  140. sd_io_resume(1, 1);
  141. }
  142. }
  143. #endif
  144. __attribute__((weak)) u8 iokey_filter_hook(u8 io_state)
  145. {
  146. return 0;
  147. }
  148. u8 io_get_key_value(void)
  149. {
  150. int i;
  151. u8 press_value = 0;
  152. u8 read_value = 0;
  153. u8 read_io;
  154. u8 write_io;
  155. u8 connect_way;
  156. u8 ret_value = NO_KEY;
  157. u8 bit_mark = 0;
  158. if (!__this->enable) {
  159. return NO_KEY;
  160. }
  161. //先扫描单IO接按键方式
  162. for (i = 0; i < __this->num; i++) {
  163. connect_way = __this->port[i].connect_way;
  164. if (connect_way == ONE_PORT_TO_HIGH) {
  165. press_value = 1;
  166. } else if (connect_way == ONE_PORT_TO_LOW) {
  167. press_value = 0;
  168. } else {
  169. continue;
  170. }
  171. read_io = __this->port[i].key_type.one_io.port;
  172. #if (TCFG_IO_MULTIPLEX_WITH_SD == ENABLE)
  173. if (read_io == TCFG_MULTIPLEX_PORT) {
  174. read_value = mult_key_value;
  175. } else {
  176. read_value = get_io_key_value(read_io);
  177. }
  178. #else
  179. read_value = get_io_key_value(read_io);
  180. #endif
  181. if (iokey_filter_hook(read_value)) {
  182. #ifdef TCFG_IOKEY_TIME_REDEFINE
  183. extern struct key_driver_para iokey_scan_user_para;
  184. iokey_scan_user_para.filter_cnt = 0;
  185. iokey_scan_user_para.press_cnt = 0;
  186. iokey_scan_user_para.click_cnt = 0;
  187. iokey_scan_user_para.click_delay_cnt = 0;
  188. iokey_scan_user_para.last_key = NO_KEY;
  189. #else
  190. iokey_scan_para.filter_cnt = 0;
  191. iokey_scan_para.press_cnt = 0;
  192. iokey_scan_para.click_cnt = 0;
  193. iokey_scan_para.click_delay_cnt = 0;
  194. iokey_scan_para.last_key = NO_KEY;
  195. #endif
  196. return NO_KEY;
  197. }
  198. if (read_value == press_value) {
  199. ret_value = __this->port[i].key_value;
  200. #if MULT_KEY_ENABLE
  201. MARK_BIT_VALUE(bit_mark, ret_value); //标记被按下的按键
  202. #else
  203. goto _iokey_get_value_end;
  204. #endif
  205. }
  206. }
  207. //再扫描两个IO接按键方式, in_port: 上拉输入, out_port: 输出低
  208. for (i = 0; i < __this->num; i++) {
  209. connect_way = __this->port[i].connect_way;
  210. if (connect_way == DOUBLE_PORT_TO_IO) {//标准双io
  211. press_value = 0;
  212. read_io = __this->port[i].key_type.two_io.in_port;
  213. key_io_output_low(__this->port[i].key_type.two_io.out_port); //输出低
  214. key_io_pull_up_input(read_io); //上拉
  215. read_value = get_io_key_value(read_io);
  216. key_io_reset(); //按键初始化为单IO检测状态
  217. if (read_value == press_value) {
  218. ret_value = __this->port[i].key_value;
  219. #if MULT_KEY_ENABLE
  220. MARK_BIT_VALUE(bit_mark, ret_value); //标记被按下的按键
  221. #else
  222. goto _iokey_get_value_end;
  223. #endif
  224. }
  225. }
  226. }
  227. #if MULT_KEY_ENABLE
  228. bit_mark = iokey_value_remap(bit_mark); //组合按键重新映射按键值
  229. ret_value = (bit_mark != NO_KEY) ? bit_mark : ret_value;
  230. #endif
  231. _iokey_get_value_end:
  232. return ret_value;
  233. }
  234. int iokey_init(const struct iokey_platform_data *iokey_data)
  235. {
  236. int i;
  237. __this = iokey_data;
  238. if (__this == NULL) {
  239. return -EINVAL;
  240. }
  241. if (!__this->enable) {
  242. return KEY_NOT_SUPPORT;
  243. }
  244. key_io_reset();
  245. return 0;
  246. }
  247. #endif /* #if TCFG_IOKEY_ENABLE */