| 145 | } |
| 146 | |
| 147 | bool ButtonControl::startThread() { |
| 148 | LOGGER.info("Start"); |
| 149 | |
| 150 | esp_err_t err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM); |
| 151 | if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { |
| 152 | LOGGER.error("Failed to install GPIO ISR service: {}", esp_err_to_name(err)); |
| 153 | return false; |
| 154 | } |
| 155 | |
| 156 | // isrArgs has one entry per unique physical pin — no duplicate registrations. |
| 157 | // Addresses are stable: vector was reserved in constructor and is not modified after that. |
| 158 | int handlersAdded = 0; |
| 159 | for (auto& arg : isrArgs) { |
| 160 | err = gpio_isr_handler_add(arg.pin, gpioIsrHandler, &arg); |
| 161 | if (err != ESP_OK) { |
| 162 | LOGGER.error("Failed to add ISR for GPIO {}: {}", static_cast<int>(arg.pin), esp_err_to_name(err)); |
| 163 | for (int i = 0; i < handlersAdded; i++) { |
| 164 | gpio_isr_handler_remove(isrArgs[i].pin); |
| 165 | } |
| 166 | return false; |
| 167 | } |
| 168 | handlersAdded++; |
| 169 | } |
| 170 | |
| 171 | driverThread = std::make_shared<tt::Thread>("ButtonControl", 4096, [this] { |
| 172 | driverThreadMain(); |
| 173 | return 0; |
| 174 | }); |
| 175 | |
| 176 | driverThread->start(); |
| 177 | return true; |
| 178 | } |
| 179 | |
| 180 | void ButtonControl::stopThread() { |
| 181 | LOGGER.info("Stop"); |