/* * This file is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Code by David "Buzz" Bussenschutt and others * */ #include "SoftSigReaderInt.h" #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/gpio.h" // future possible TODO - can we use the RMT peripheral on the esp32 to do this ? looks plausible. // https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html // with an example here for both transmit and recieve of IR signals: // https://github.com/espressif/esp-idf/tree/2f8b6cfc7/examples/peripherals/rmt_nec_tx_rx //for now, we use GPIO interrupts,refer here: // https://github.com/espressif/esp-idf/blob/master/examples/peripherals/gpio/main/gpio_example_main.c #if CONFIG_HAL_BOARD == HAL_BOARD_ESP32 using namespace ESP32; extern const AP_HAL::HAL& hal; #if HAL_USE_EICU == TRUE #define GPIO_INPUT_IO_0 (gpio_num_t)4 #define GPIO_INPUT_PIN_SEL ((1ULL<sigbuf.push(pulse); pulse.w0 = 0; pulse.w1 = 0; } } // reset on too-big-a-big gap between pulse edges if ( AP_HAL::micros() - last_transitioned_time > 1000000 ) { // thats 1 second with no data at all. //we have probably missed some pulses //try to reset RCProtocol parser by returning invalid value (i.e. 0 width pulse) //pulse.w0 = 0; //pulse.w1 = 0; //_instance->sigbuf.push(pulse); } } // singleton instance SoftSigReaderInt *SoftSigReaderInt::_instance; SoftSigReaderInt::SoftSigReaderInt() { _instance = this; printf("SoftSigReaderInt-constructed\n"); } SoftSigReaderInt::~SoftSigReaderInt() { //remove isr handler for gpio number. gpio_isr_handler_remove(GPIO_INPUT_IO_0); } void SoftSigReaderInt::init() { printf("SoftSigReaderInt::init\n"); // lets start with GPIO4: input, pulled up, interrupt from rising edge and falling edge gpio_config_t io_conf; //interrupt of rising edge io_conf.intr_type = GPIO_INTR_ANYEDGE; // GPIO_PIN_INTR_POSEDGE; //bit mask of the pins, use GPIO4/5 here io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; //set as input mode io_conf.mode = GPIO_MODE_INPUT; //disable pull-down mode io_conf.pull_down_en = (gpio_pulldown_t)0; //enable pull-up mode io_conf.pull_up_en = (gpio_pullup_t)1; // apply settings to this gpio gpio_config(&io_conf); //change gpio intrrupt type for one pin //gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE); //create a queue to handle gpio event from isr gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); //install gpio isr service gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); //hook isr handler for specific gpio pin //gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0); gpio_isr_handler_add(GPIO_INPUT_IO_0, _irq_handler, (void*) GPIO_INPUT_IO_0); } bool SoftSigReaderInt::read(uint32_t &widths0, uint32_t &widths1) { //printf("SoftSigReaderInt::read\n"); if (sigbuf.available() >= 2) { pulse_t pulse; if (sigbuf.pop(pulse)) { widths0 = uint16_t(pulse.w0 - last_value); widths1 = uint16_t(pulse.w1 - pulse.w0); last_value = pulse.w1; return true; } } return false; } #endif // HAL_USE_EICU #endif //CONFIG_HAL_BOARD == HAL_BOARD_ESP32