| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- #include "gpio.h"
- uint32_t last_switch = 0;
- uint32_t last_time_up_tick = 0;
- uint32_t last_time_down_tick = 0;
- static void gpio_interrupt_callback(void* context) {
- furi_assert(context);
- GPIOContext* gpio_context = context;
- uint32_t current_tick = furi_get_tick();
- if(last_switch > 0) {
- bool shift_up = furi_hal_gpio_read(gpio_context->pin) ^ gpio_context->inverted;
- if(shift_up) {
- last_time_down_tick = current_tick - last_switch;
- } else {
- last_time_up_tick = current_tick - last_switch;
- }
- GPIOEvent event = {
- .shift_up = shift_up,
- .time_passed_down = last_time_down_tick,
- .time_passed_up = last_time_up_tick};
- furi_message_queue_put(gpio_context->queue, &event, 0);
- }
- last_switch = current_tick;
- }
- static const GpioPin* data_pins_to_gpio_pins[] =
- {&gpio_ext_pa7, &gpio_ext_pa4, &gpio_ext_pb2, &gpio_ext_pc1, &gpio_ext_pc0};
- GPIOContext*
- gpio_start_listening(const LWCDataPin data_pin, bool inverted, void* callback_context) {
- GPIOContext* result = malloc(sizeof(GPIOContext));
- result->inverted = inverted;
- result->pin = data_pins_to_gpio_pins[data_pin];
- result->context = callback_context;
- result->queue = furi_message_queue_alloc(32, sizeof(GPIOEvent));
- furi_hal_gpio_add_int_callback(result->pin, gpio_interrupt_callback, result);
- furi_hal_gpio_enable_int_callback(result->pin);
- furi_hal_gpio_init(result->pin, GpioModeInterruptRiseFall, GpioPullUp, GpioSpeedVeryHigh);
- return result;
- }
- void gpio_stop_listening(GPIOContext* context) {
- furi_hal_gpio_disable_int_callback(context->pin);
- furi_hal_gpio_remove_int_callback(context->pin);
- furi_hal_gpio_init_simple(context->pin, GpioModeAnalog);
- }
- bool gpio_callback_with_event(GPIOContext* context, void (*callback)(GPIOEvent, void*)) {
- GPIOEvent event;
- FuriStatus event_status = furi_message_queue_get(context->queue, &event, 0);
- if(event_status == FuriStatusOk) {
- callback(event, context->context);
- return true;
- } else {
- return false;
- }
- }
|