From 3376d52d8e0b96d22649cd902336696bf8e22b0c Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 30 Mar 2025 12:26:16 -0700 Subject: [PATCH] Parameterize gpio expander settings into constants --- src/edmfd/main.cc | 50 ++++++++++++++++++++++++++++++++----------- src/edmfd/mcp23017.cc | 10 ++++----- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/edmfd/main.cc b/src/edmfd/main.cc index 91dc977..25196b3 100644 --- a/src/edmfd/main.cc +++ b/src/edmfd/main.cc @@ -17,7 +17,6 @@ using mcp23017::reg; -static constexpr unsigned i2c_baud = 1200 * 1000; extern "C" { // TinyUSB callbacks @@ -27,14 +26,15 @@ extern "C" { void tud_resume_cb(); } -static constexpr unsigned bank_leds = 0; -static constexpr unsigned bank_buttons = 1; +static constexpr unsigned i2c_baud = 400 * 1000; static constexpr unsigned hid_update_ms = 1000/20; // 20Hz +static constexpr unsigned bank_leds = 0; +static constexpr unsigned bank_buttons = 1; static constexpr unsigned buttons_per_group = 5; static constexpr unsigned button_group_count = 2; -static const unsigned button_group_irqs[] = {5, 6}; +static const unsigned button_group_irqs[] = {4, 7}; mcp23017::extender button_groups[] ={ {0x20}, {0x21} }; uint8_t button_states[] = {0, 0}; uint8_t button_leds[] = {0, 0}; @@ -68,6 +68,16 @@ void set_leds_callback(uint32_t leds) { button_leds[i] = desired; } } + log::trace("set leds to %02x %02x", button_leds[0], button_leds[1]); +} + +void test_irq_handler(unsigned pin, uint32_t events) { + log::debug("irq received on %d", pin); + irq_handler(pin, events); + uint32_t leds = 0; + for (unsigned i = 0; i < button_group_count; ++i) + leds |= (uint32_t(button_states[i]) << (i*8)); + set_leds_callback(leds); } int main(void) @@ -98,6 +108,7 @@ int main(void) } bool have_any_buttons = false; + bool start_test_mode = false; for (unsigned i = 0; i < button_group_count; ++i) { if (!button_groups[i].init()) { log::warn("failed to initialize button group %d", i); @@ -110,12 +121,21 @@ int main(void) using mcp23017::direction; for (unsigned i = 0; i < buttons_per_group; ++i) - buttons.set_direction(0, i, direction::out); + buttons.set_direction(bank_leds, i, direction::out); - buttons.set_direction(1, 0, direction::in); - buttons.set_polarity(1, 0, true); - buttons.set_pullup(1, 0, true); - buttons.set_irq(1, 0, true); + for (unsigned i = 0; i < buttons_per_group; ++i) { + buttons.set_direction(bank_buttons, i, direction::in); + buttons.set_polarity(bank_buttons, i, true); + buttons.set_pullup(bank_buttons, i, true); + buttons.set_irq(bank_buttons, i, true); + } + + button_states[i] = buttons.get_gpios(bank_buttons); + if (button_states[i] != 0) { + log::debug("button group %d has pressed buttons %02x, enabling test mode.", + i, button_states[i]); + start_test_mode = true; + } } if (!have_any_buttons) { @@ -123,10 +143,16 @@ int main(void) return 1; } - hid::init(set_leds_callback); - repeating_timer hid_timer; - add_repeating_timer_ms(hid_update_ms, hid_update_callback, nullptr, &hid_timer); + if (start_test_mode) { + // Replace IRQ handlers + for (int pin : button_group_irqs) + gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_FALL, true, test_irq_handler); + } else { + // Regular mode + hid::init(set_leds_callback); + add_repeating_timer_ms(hid_update_ms, hid_update_callback, nullptr, &hid_timer); + } // Let timers and iterrupts handle most things while (1) { diff --git a/src/edmfd/mcp23017.cc b/src/edmfd/mcp23017.cc index 2633d62..0c5eb54 100644 --- a/src/edmfd/mcp23017.cc +++ b/src/edmfd/mcp23017.cc @@ -42,11 +42,11 @@ extender::init() sleep_ms(10); } - if (read(reg::iodira, m_direction, 2) > 0) { - //log::info("initialized directions to %02x %02x", m_direction[0], m_direction[1]); - return true; - } - return false; + if (read(reg::iodira, m_direction, 2) < 0) + return false; + + uint8_t config = (1 << 6); // mirror interrupt lines + return write(reg::iocona, config) >= 0; } template