io.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*******************************************************************************
  2. * IO Driver for IdeasX
  3. * Author: curiousmuch
  4. * Description: HAL layer for IdeasX v0.3.X encoders
  5. * This lib has a couple functions
  6. * 1) Provide SW interface for encoder hardware for the following functions:
  7. * reset, shutdown, enable / disable assistive switches
  8. * 2) Provide the ability to attach custom ISR to assistive switch inputs
  9. and INTR pin on LSM6DS3.
  10. * Todo:
  11. *******************************************************************************/
  12. #include "hal/io.h"
  13. #include "hal/lsm6ds3.h"
  14. #include "log/esp_log.h"
  15. static const char* TAG = "IO Driver";
  16. // debounce timers
  17. static IO_config_t io_config;
  18. void IO_GPIO_Handler(void);
  19. static void switchA_debounce(void);
  20. static void switchB_debounce(void);
  21. void ICACHE_FLASH_ATTR IO_InitIO(void)
  22. {
  23. ETS_GPIO_INTR_DISABLE(); // disable interrupts
  24. gpio_init(); // magic function in SDK
  25. io_config.debounce_delay = DEBOUNCEDELAY;
  26. io_config.switch_a_cb = NULL;
  27. io_config.switch_b_cb = NULL;
  28. io_config.imu_cb = NULL;
  29. io_config.debounce_timer = false;
  30. // setup as GPIO pins
  31. PIN_FUNC_SELECT(LDO_SHUTDOWN_MUX, LDO_SHUTDOWN_FUNC);
  32. PIN_FUNC_SELECT(SWITCH_A_MUX, SWITCH_A_FUNC);
  33. PIN_FUNC_SELECT(SWITCH_B_MUX, SWITCH_B_FUNC);
  34. PIN_FUNC_SELECT(STATUS_LED_MUX, STATUS_LED_FUNC);
  35. // setup GPIO states
  36. gpio_output_set(BIT(LDO_SHUTDOWN), BIT(STATUS_LED), (BIT(LDO_SHUTDOWN)|BIT(STATUS_LED)), (BIT(SWITCH_A)|BIT(SWITCH_B)));
  37. // attach callback function for GPIO interrupts
  38. ETS_GPIO_INTR_ATTACH(IO_GPIO_Handler, NULL);
  39. // setup debounce SW timers
  40. os_timer_disarm(&io_config.switch_a_timer);
  41. os_timer_disarm(&io_config.switch_b_timer);
  42. os_timer_setfn(&io_config.switch_a_timer, (os_timer_func_t *)switchA_debounce, NULL);
  43. os_timer_setfn(&io_config.switch_b_timer, (os_timer_func_t *)switchB_debounce, NULL);
  44. }
  45. void ICACHE_FLASH_ATTR IO_SetSwitchCallback(switch_function_t switch_a_cb, switch_function_t switch_b_cb)
  46. {
  47. io_config.switch_a_cb = switch_a_cb;
  48. io_config.switch_b_cb = switch_b_cb;
  49. }
  50. void ICACHE_FLASH_ATTR IO_SetIMUCallback(imu_function_t imu_cb)
  51. {
  52. io_config.imu_cb = imu_cb;
  53. }
  54. void ICACHE_FLASH_ATTR IO_EnableIOInterrupts(void)
  55. {
  56. ETS_GPIO_INTR_DISABLE();
  57. // clear existing interrupt
  58. uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
  59. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
  60. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_ANYEDGE);
  61. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
  62. ETS_GPIO_INTR_ENABLE();
  63. ESP_LOGV(TAG, "enabled interrupts");
  64. }
  65. void ICACHE_FLASH_ATTR IO_DisableIOInterrupts(void)
  66. {
  67. ETS_GPIO_INTR_DISABLE();
  68. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_DISABLE);
  69. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_DISABLE);
  70. ESP_LOGV(TAG, "disabled interrupts");
  71. ETS_GPIO_INTR_DISABLE();
  72. }
  73. void ICACHE_FLASH_ATTR IO_ActivateDebounceTimer(void)
  74. {
  75. io_config.debounce_timer = true;
  76. }
  77. void ICACHE_FLASH_ATTR IO_DisableDebounceTimer(void)
  78. {
  79. io_config.debounce_timer = false;
  80. }
  81. uint32_t ICACHE_FLASH_ATTR IO_GetStates(void)
  82. {
  83. return GPIO_REG_READ(GPIO_IN_ADDRESS);
  84. }
  85. void ICACHE_FLASH_ATTR IO_Shutdown(void)
  86. {
  87. gpio_output_set(0, BIT(LDO_SHUTDOWN), BIT(LDO_SHUTDOWN), 0);
  88. //GPIO_OUTPUT_SET(LDO_SHUTDOWN, 0);
  89. }
  90. void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
  91. {
  92. uint8_t i;
  93. uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); // read interupt status of pins
  94. uint32_t gpio_states = GPIO_REG_READ(GPIO_IN_ADDRESS); // read pin status
  95. ETS_GPIO_INTR_DISABLE(); // disable GPIO interrupts
  96. for (i=0;i<GPIO_PIN_COUNT;i++)
  97. {
  98. if (BIT(i) & gpio_status)
  99. {
  100. gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_DISABLE); // disable interrupt for pin
  101. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(i)); // clear interrupt status
  102. ESP_LOGV(TAG, "Pin Interrupt %d", i);
  103. switch(i)
  104. {
  105. case SWITCH_A:
  106. {
  107. //ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);
  108. LSM6DS3_Interrupt_et imu_interrupt;
  109. imu_interrupt = LSM6DS3_Get_Interrupts();
  110. if (imu_interrupt != LSM6DS3_NO_INT)
  111. {
  112. if (io_config.imu_cb != NULL)
  113. io_config.imu_cb((IMU_Interrupt_et) imu_interrupt);
  114. //gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE); // re-enable interrupts
  115. }
  116. else
  117. {
  118. //os_delay_us(10000);
  119. //if (io_config.switch_a_cb != NULL)
  120. // io_config.switch_a_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
  121. if (io_config.debounce_timer)
  122. os_timer_arm(&io_config.switch_a_timer, io_config.debounce_delay, 0);
  123. }
  124. break;
  125. }
  126. case SWITCH_B:
  127. {
  128. //ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);
  129. //os_delay_us(10000);
  130. //if (io_config.switch_b_cb != NULL)
  131. // io_config.switch_b_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
  132. if (io_config.debounce_timer)
  133. os_timer_arm(&io_config.switch_b_timer, io_config.debounce_delay, 0);
  134. break;
  135. }
  136. default:
  137. {
  138. ESP_LOGW(TAG, "unexpected interrupt on pin %d", i);
  139. }
  140. }
  141. }
  142. }
  143. ETS_GPIO_INTR_ENABLE();
  144. }
  145. static void ICACHE_FLASH_ATTR switchA_debounce(void)
  146. {
  147. ESP_LOGV(TAG, "switchA");
  148. ETS_GPIO_INTR_DISABLE();
  149. if (io_config.switch_a_cb != NULL)
  150. io_config.switch_a_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
  151. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_A), GPIO_PIN_INTR_ANYEDGE);
  152. os_timer_disarm(&io_config.switch_a_timer);
  153. ETS_GPIO_INTR_ENABLE();
  154. }
  155. static void ICACHE_FLASH_ATTR switchB_debounce(void)
  156. {
  157. ESP_LOGV(TAG, "switchB");
  158. ETS_GPIO_INTR_DISABLE();
  159. if (io_config.switch_b_cb != NULL)
  160. io_config.switch_b_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
  161. gpio_pin_intr_state_set(GPIO_ID_PIN(SWITCH_B), GPIO_PIN_INTR_ANYEDGE);
  162. os_timer_disarm(&io_config.switch_b_timer);
  163. ETS_GPIO_INTR_ENABLE();
  164. }