diff --git a/Firmware/main/include/buttons.hpp b/Firmware/main/include/buttons.hpp index aa7e406..5ef48d7 100644 --- a/Firmware/main/include/buttons.hpp +++ b/Firmware/main/include/buttons.hpp @@ -24,12 +24,14 @@ public: static Buttons& get(); void pooler(); // FIXME: uint8_t get_pressed(); + void install_isr(); + + TaskHandle_t _pooler_task; private: Buttons(); volatile uint8_t _current; - TaskHandle_t _pooler_task; }; diff --git a/Firmware/main/include/power_helper.hpp b/Firmware/main/include/power_helper.hpp index ff644d5..302d0dd 100644 --- a/Firmware/main/include/power_helper.hpp +++ b/Firmware/main/include/power_helper.hpp @@ -11,10 +11,10 @@ class PowerHelper { public: static PowerHelper& get(); - bool is_slow() const; - void set_slow(bool slow); - void reset_slow_isr(); // FIXME: - void delay(int slow_ms, int normal_ms); + bool is_slow() const; + void set_slow(bool slow); + BaseType_t reset_slow_isr(BaseType_t* xHigherPriorityTaskWoken); + void delay(int slow_ms, int normal_ms); void install_isr(); diff --git a/Firmware/main/src/buttons.cpp b/Firmware/main/src/buttons.cpp index d932da0..6a6a11e 100644 --- a/Firmware/main/src/buttons.cpp +++ b/Firmware/main/src/buttons.cpp @@ -29,6 +29,28 @@ Buttons& Buttons::get() { static void start_pooler(void* arg) { static_cast(arg)->pooler(); } +static bool is_on_low; + +static void wakeup(void* arg) { + if (is_on_low) { + ESP_ERROR_CHECK(gpio_set_intr_type(EXP_INT, GPIO_INTR_HIGH_LEVEL)); + ESP_ERROR_CHECK(gpio_wakeup_enable(EXP_INT, GPIO_INTR_HIGH_LEVEL)); + is_on_low = false; + + BaseType_t xResult = pdFAIL; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + xTaskNotifyFromISR(Buttons::get()._pooler_task, 0, eNoAction, &xHigherPriorityTaskWoken); + + PowerHelper::get().reset_slow_isr(&xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } else { + ESP_ERROR_CHECK(gpio_set_intr_type(EXP_INT, GPIO_INTR_LOW_LEVEL)); + ESP_ERROR_CHECK(gpio_wakeup_enable(EXP_INT, GPIO_INTR_LOW_LEVEL)); + is_on_low = true; + } +} + Buttons::Buttons() { ESP_ERROR_CHECK(i2c_master_bus_add_device(I2cGlobal::get().get_bus_handle(), &dev_cfg, &dev_handle)); uint8_t buf2[2]; @@ -38,10 +60,17 @@ Buttons::Buttons() { buf2[1] = 0xFF; ESP_ERROR_CHECK(i2c_master_transmit(dev_handle, buf2, sizeof(buf2), -1)); buf2[0] = 7; + buf2[1] = 0x80; ESP_ERROR_CHECK(i2c_master_transmit(dev_handle, buf2, sizeof(buf2), -1)); xTaskCreate(&start_pooler, "ButtonsPooler", 2048, this, 1, &_pooler_task); -} + ESP_ERROR_CHECK(gpio_reset_pin(EXP_INT)); + ESP_ERROR_CHECK(gpio_set_direction(EXP_INT, GPIO_MODE_INPUT)); + ESP_ERROR_CHECK(gpio_set_pull_mode(EXP_INT, GPIO_FLOATING)); + ESP_ERROR_CHECK(gpio_set_intr_type(EXP_INT, GPIO_INTR_LOW_LEVEL)); + ESP_ERROR_CHECK(gpio_wakeup_enable(EXP_INT, GPIO_INTR_LOW_LEVEL)); + is_on_low = true; +} static void delay(unsigned long long loop) { for (unsigned long long i = 0; i < loop; i++) { @@ -51,12 +80,17 @@ static void delay(unsigned long long loop) { void Buttons::pooler() { while (true) { - uint8_t reg = 0; - uint8_t buffer; + BaseType_t xResult = xTaskNotifyWait(pdFALSE, ULONG_MAX, nullptr, portMAX_DELAY); + uint8_t reg = 0; + uint8_t buffer; ESP_ERROR_CHECK( i2c_master_transmit_receive(dev_handle, ®, sizeof(reg), reinterpret_cast(&buffer), 1, -1)); _current = buffer; - PowerHelper::get().delay(10000, 200); + // read second port too to clear the interrupt + reg = 1; + ESP_ERROR_CHECK( + i2c_master_transmit_receive(dev_handle, ®, sizeof(reg), reinterpret_cast(&buffer), 1, -1)); } } uint8_t Buttons::get_pressed() { return _current; } +void Buttons::install_isr() { gpio_isr_handler_add(EXP_INT, wakeup, nullptr); } diff --git a/Firmware/main/src/hello_world_main.cpp b/Firmware/main/src/hello_world_main.cpp index 0fad828..f4d8998 100644 --- a/Firmware/main/src/hello_world_main.cpp +++ b/Firmware/main/src/hello_world_main.cpp @@ -47,10 +47,11 @@ extern "C" void app_main() { // ESP_ERROR_CHECK(gpio_install_isr_service(0)); PowerHelper::get(); Shutdowner::get(); + Buttons::get(); ESP_ERROR_CHECK(gpio_install_isr_service(0)); Shutdowner::get().install_isr(); PowerHelper::get().install_isr(); - Buttons::get(); + Buttons::get().install_isr(); I2cGlobal::get(); BatMon::get(); SpiGlobal::get(); diff --git a/Firmware/main/src/power_helper.cpp b/Firmware/main/src/power_helper.cpp index fab86a9..00afc38 100644 --- a/Firmware/main/src/power_helper.cpp +++ b/Firmware/main/src/power_helper.cpp @@ -17,7 +17,6 @@ PowerHelper& PowerHelper::get() { } bool PowerHelper::is_slow() const { return _slow; } void PowerHelper::set_slow(bool slow) { - return; _slow = slow; if (_slow) { xEventGroupClearBits(_event_group, 1); @@ -26,32 +25,22 @@ void PowerHelper::set_slow(bool slow) { } } -void PowerHelper::reset_slow_isr() { +BaseType_t PowerHelper::reset_slow_isr(BaseType_t* xHigherPriorityTaskWoken) { + _slow = false; + return xEventGroupSetBitsFromISR(_event_group, 1, xHigherPriorityTaskWoken); +} + +static void wakeup(void* arg) { BaseType_t xHigherPriorityTaskWoken, xResult; xHigherPriorityTaskWoken = pdFALSE; - - _slow = false; - xResult = xEventGroupSetBitsFromISR(_event_group, 1, &xHigherPriorityTaskWoken); - + xResult = static_cast(arg)->reset_slow_isr(&xHigherPriorityTaskWoken); if (xResult != pdFAIL) { portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + }; } -static void wakeup(void* arg) { static_cast(arg)->reset_slow_isr(); } - -PowerHelper::PowerHelper() : _event_group(xEventGroupCreate()) { - // ESP_ERROR_CHECK(gpio_reset_pin(EXP_INT)); - // ESP_ERROR_CHECK(gpio_set_direction(EXP_INT, GPIO_MODE_INPUT)); - // ESP_ERROR_CHECK(gpio_set_pull_mode(EXP_INT, GPIO_FLOATING)); - // ESP_ERROR_CHECK(gpio_set_intr_type(EXP_INT, GPIO_INTR_HIGH_LEVEL)); - // ESP_ERROR_CHECK(gpio_wakeup_enable(EXP_INT, GPIO_INTR_HIGH_LEVEL)); - // ESP_ERROR_CHECK(gpio_install_isr_service(0)); - // gpio_isr_handler_add(EXP_INT, wakeup, this); - - set_slow(false); -} +PowerHelper::PowerHelper() : _event_group(xEventGroupCreate()) { set_slow(false); } void PowerHelper::delay(int slow_ms, int normal_ms) { if (is_slow()) {