key.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /******************************************************************************
  2. * Copyright 2013-2014 Espressif Systems (Wuxi)
  3. *
  4. * FileName: key.c
  5. *
  6. * Description: key driver, now can use different gpio and install different function
  7. *
  8. * Modification history:
  9. * 2014/5/1, v1.0 create this file.
  10. *******************************************************************************/
  11. #include "ets_sys.h"
  12. #include "os_type.h"
  13. #include "osapi.h"
  14. #include "mem.h"
  15. #include "gpio.h"
  16. #include "user_interface.h"
  17. #include "pm/swtimer.h"
  18. #include "driver/key.h"
  19. LOCAL void ICACHE_RAM_ATTR key_intr_handler(void *arg);
  20. /******************************************************************************
  21. * FunctionName : key_init_single
  22. * Description : init single key's gpio and register function
  23. * Parameters : uint8 gpio_id - which gpio to use
  24. * uint32 gpio_name - gpio mux name
  25. * uint32 gpio_func - gpio function
  26. * key_function long_press - long press function, needed to install
  27. * key_function short_press - short press function, needed to install
  28. * Returns : single_key_param - single key parameter, needed by key init
  29. *******************************************************************************/
  30. struct single_key_param *ICACHE_FLASH_ATTR
  31. key_init_single(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, key_function long_press, key_function short_press)
  32. {
  33. struct single_key_param *single_key = (struct single_key_param *)os_zalloc(sizeof(struct single_key_param));
  34. single_key->gpio_id = gpio_id;
  35. single_key->gpio_name = gpio_name;
  36. single_key->gpio_func = gpio_func;
  37. single_key->long_press = long_press;
  38. single_key->short_press = short_press;
  39. return single_key;
  40. }
  41. /******************************************************************************
  42. * FunctionName : key_init
  43. * Description : init keys
  44. * Parameters : key_param *keys - keys parameter, which inited by key_init_single
  45. * Returns : none
  46. *******************************************************************************/
  47. void ICACHE_FLASH_ATTR
  48. key_init(struct keys_param *keys)
  49. {
  50. uint8 i;
  51. ETS_GPIO_INTR_ATTACH(key_intr_handler, keys);
  52. ETS_GPIO_INTR_DISABLE();
  53. for (i = 0; i < keys->key_num; i++) {
  54. keys->single_key[i]->key_level = 1;
  55. PIN_FUNC_SELECT(keys->single_key[i]->gpio_name, keys->single_key[i]->gpio_func);
  56. gpio_output_set(0, 0, 0, GPIO_ID_PIN(keys->single_key[i]->gpio_id));
  57. gpio_register_set(GPIO_PIN_ADDR(keys->single_key[i]->gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
  58. | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
  59. | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
  60. //clear gpio14 status
  61. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(keys->single_key[i]->gpio_id));
  62. //enable interrupt
  63. gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_NEGEDGE);
  64. }
  65. ETS_GPIO_INTR_ENABLE();
  66. }
  67. /******************************************************************************
  68. * FunctionName : key_5s_cb
  69. * Description : long press 5s timer callback
  70. * Parameters : single_key_param *single_key - single key parameter
  71. * Returns : none
  72. *******************************************************************************/
  73. LOCAL void ICACHE_FLASH_ATTR
  74. key_5s_cb(struct single_key_param *single_key)
  75. {
  76. os_timer_disarm(&single_key->key_5s);
  77. // low, then restart
  78. if (0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
  79. if (single_key->long_press) {
  80. single_key->long_press();
  81. }
  82. }
  83. }
  84. /******************************************************************************
  85. * FunctionName : key_50ms_cb
  86. * Description : 50ms timer callback to check it's a real key push
  87. * Parameters : single_key_param *single_key - single key parameter
  88. * Returns : none
  89. *******************************************************************************/
  90. LOCAL void ICACHE_FLASH_ATTR
  91. key_50ms_cb(struct single_key_param *single_key)
  92. {
  93. os_timer_disarm(&single_key->key_50ms);
  94. // high, then key is up
  95. if (1 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
  96. os_timer_disarm(&single_key->key_5s);
  97. single_key->key_level = 1;
  98. gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_NEGEDGE);
  99. if (single_key->short_press) {
  100. single_key->short_press();
  101. }
  102. } else {
  103. gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_POSEDGE);
  104. }
  105. }
  106. /******************************************************************************
  107. * FunctionName : key_intr_handler
  108. * Description : key interrupt handler
  109. * Parameters : key_param *keys - keys parameter, which inited by key_init_single
  110. * Returns : none
  111. *******************************************************************************/
  112. LOCAL void
  113. key_intr_handler(void *arg)
  114. {
  115. uint8 i;
  116. uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
  117. struct keys_param *keys = arg;
  118. for (i = 0; i < keys->key_num; i++) {
  119. if (gpio_status & BIT(keys->single_key[i]->gpio_id)) {
  120. //disable interrupt
  121. gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_DISABLE);
  122. //clear interrupt status
  123. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(keys->single_key[i]->gpio_id));
  124. if (keys->single_key[i]->key_level == 1) {
  125. // 5s, restart & enter softap mode
  126. os_timer_disarm(&keys->single_key[i]->key_5s);
  127. os_timer_setfn(&keys->single_key[i]->key_5s, (os_timer_func_t *)key_5s_cb, keys->single_key[i]);
  128. SWTIMER_REG_CB(key_5s_cb, SWTIMER_DROP);
  129. // key_5s_cb checks the state of a gpio. After resume, gpio state would be invalid
  130. os_timer_arm(&keys->single_key[i]->key_5s, 5000, 0);
  131. keys->single_key[i]->key_level = 0;
  132. gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_POSEDGE);
  133. } else {
  134. // 50ms, check if this is a real key up
  135. os_timer_disarm(&keys->single_key[i]->key_50ms);
  136. os_timer_setfn(&keys->single_key[i]->key_50ms, (os_timer_func_t *)key_50ms_cb, keys->single_key[i]);
  137. SWTIMER_REG_CB(key_50ms_cb, SWTIMER_DROP);
  138. // key_50ms_cb checks the state of a gpio. After resume, gpio state would be invalid
  139. os_timer_arm(&keys->single_key[i]->key_50ms, 50, 0);
  140. }
  141. }
  142. }
  143. }