#include #include #include #ifdef APP_NFC void nfc_isr(void); #endif #ifdef BUILD_CC1101 void cc1101_isr(); #endif static volatile bool initialized = false; static ValueManager input_state_record; static PubSub input_events_record; static Event event; static InputState input_state = { false, }; static void exti_input_callback(void* _pin, void* _ctx); void input_task(void* p) { uint32_t state_bits = 0; uint8_t debounce_counters[INPUT_COUNT]; if(!init_managed(&input_state_record, &input_state, sizeof(input_state))) { printf("[input_task] cannot initialize ValueManager for input_state\r\n"); furiac_exit(NULL); } if(!init_pubsub(&input_events_record)) { printf("[input_task] cannot initialize PubSub for input_events\r\n"); furiac_exit(NULL); } if(!init_event(&event)) { printf("[input_task] cannot initialize Event\r\n"); furiac_exit(NULL); } furi_record_create("input_state", &input_state_record); furi_record_create("input_events", &input_events_record); api_interrupt_add(exti_input_callback, InterruptTypeExternalInterrupt, NULL); // we ready to work initialized = true; // Force state update for(uint32_t i = 0; i < INPUT_COUNT; i++) { debounce_counters[i] = DEBOUNCE_TICKS / 2; } for(;;) { bool changed = false; for(uint32_t i = 0; i < INPUT_COUNT; i++) { bool input_state = false; // dirty hack, f3 has no CHARGING pin // TODO rewrite this if(i < GPIO_INPUT_PINS_COUNT) { input_state = gpio_read(&input_gpio[i]) ^ input_invert[i]; } if(input_state) { if(debounce_counters[i] < DEBOUNCE_TICKS) { debounce_counters[i] += 1; changed = true; } } else { if(debounce_counters[i] > 0) { debounce_counters[i] -= 1; changed = true; } } } if(!changed) { uint32_t new_state_bits = 0; for(uint32_t i = 0; i < INPUT_COUNT; i++) { if(debounce_counters[i] == DEBOUNCE_TICKS) { new_state_bits |= (1 << i); } } uint32_t changed_bits = new_state_bits ^ state_bits; if(changed_bits != 0) { // printf("[input] %02x -> %02x\n", state_bits, new_state_bits); InputState new_state = _BITS2STATE(new_state_bits); write_managed(&input_state_record, &new_state, sizeof(new_state), osWaitForever); state_bits = new_state_bits; for(uint32_t i = 0; i < INPUT_COUNT; i++) { if((changed_bits & (1 << i)) != 0) { bool state = (new_state_bits & (1 << i)) != 0; InputEvent event = {i, state}; notify_pubsub(&input_events_record, &event); } } } // Sleep: wait for event wait_event(&event); } else { osDelay(1); } } } static void exti_input_callback(void* _pin, void* _ctx) { // interrupt manager get us pin constant, so... uint32_t pin = (uint32_t)_pin; #ifdef APP_NFC if(pin == NFC_IRQ_Pin) { nfc_isr(); return; } #endif #ifdef BUILD_CC1101 if(pin == CC1101_G0_Pin) { cc1101_isr(); return; } #endif if(!initialized) return; signal_event(&event); }