diff --git a/src/input/ScanAndSelect.cpp b/src/input/ScanAndSelect.cpp index b0c779ca5..8c193b1cb 100644 --- a/src/input/ScanAndSelect.cpp +++ b/src/input/ScanAndSelect.cpp @@ -48,8 +48,8 @@ bool ScanAndSelectInput::init() // Short circuit: if selected pin conficts with the user button #if defined(ARCH_PORTDUINO) int pinUserButton = 0; - if (settingsMap.count(user) != 0) { - pinUserButton = settingsMap[user]; + if (settingsMap.count(userButtonPin) != 0) { + pinUserButton = settingsMap[userButtonPin]; } #elif defined(USERPREFS_BUTTON_PIN) int pinUserButton = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; diff --git a/src/input/TrackballInterruptBase.cpp b/src/input/TrackballInterruptBase.cpp index 1730af62b..219b298e9 100644 --- a/src/input/TrackballInterruptBase.cpp +++ b/src/input/TrackballInterruptBase.cpp @@ -18,17 +18,27 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef this->_eventRight = eventRight; this->_eventPressed = eventPressed; - pinMode(pinPress, INPUT_PULLUP); - pinMode(this->_pinDown, INPUT_PULLUP); - pinMode(this->_pinUp, INPUT_PULLUP); - pinMode(this->_pinLeft, INPUT_PULLUP); - pinMode(this->_pinRight, INPUT_PULLUP); + if (pinPress != 255) { + pinMode(pinPress, INPUT_PULLUP); + attachInterrupt(pinPress, onIntPress, RISING); - attachInterrupt(pinPress, onIntPress, RISING); - attachInterrupt(this->_pinDown, onIntDown, RISING); - attachInterrupt(this->_pinUp, onIntUp, RISING); - attachInterrupt(this->_pinLeft, onIntLeft, RISING); - attachInterrupt(this->_pinRight, onIntRight, RISING); + } + if (this->_pinDown != 255) { + pinMode(this->_pinDown, INPUT_PULLUP); + attachInterrupt(this->_pinDown, onIntDown, RISING); + } + if (this->_pinUp != 255) { + pinMode(this->_pinUp, INPUT_PULLUP); + attachInterrupt(this->_pinUp, onIntUp, RISING); + } + if (this->_pinLeft != 255) { + pinMode(this->_pinLeft, INPUT_PULLUP); + attachInterrupt(this->_pinLeft, onIntLeft, RISING); + } + if (this->_pinRight != 255) { + pinMode(this->_pinRight, INPUT_PULLUP); + attachInterrupt(this->_pinRight, onIntRight, RISING); + } LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight, pinPress); diff --git a/src/input/TrackballInterruptImpl1.cpp b/src/input/TrackballInterruptImpl1.cpp index dfd5c5e82..aef188e20 100644 --- a/src/input/TrackballInterruptImpl1.cpp +++ b/src/input/TrackballInterruptImpl1.cpp @@ -6,17 +6,12 @@ TrackballInterruptImpl1 *trackballInterruptImpl1; TrackballInterruptImpl1::TrackballInterruptImpl1() : TrackballInterruptBase("trackball1") {} -void TrackballInterruptImpl1::init() +void TrackballInterruptImpl1::init(uint8_t pinUp, uint8_t pinDown, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress) { #if !HAS_TRACKBALL // Input device is disabled. return; #else - uint8_t pinUp = TB_UP; - uint8_t pinDown = TB_DOWN; - uint8_t pinLeft = TB_LEFT; - uint8_t pinRight = TB_RIGHT; - uint8_t pinPress = TB_PRESS; input_broker_event eventDown = INPUT_BROKER_DOWN; input_broker_event eventUp = INPUT_BROKER_UP; diff --git a/src/input/TrackballInterruptImpl1.h b/src/input/TrackballInterruptImpl1.h index 36efac6a6..4683efa41 100644 --- a/src/input/TrackballInterruptImpl1.h +++ b/src/input/TrackballInterruptImpl1.h @@ -5,7 +5,7 @@ class TrackballInterruptImpl1 : public TrackballInterruptBase { public: TrackballInterruptImpl1(); - void init(); + void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress); static void handleIntDown(); static void handleIntUp(); static void handleIntLeft(); diff --git a/src/main.cpp b/src/main.cpp index 4fd0da808..3b50e2521 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -105,7 +105,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr; ButtonThread *TouchButtonThread = nullptr; #endif -#if defined(BUTTON_PIN) +#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) ButtonThread *UserButtonThread = nullptr; #endif @@ -908,9 +908,20 @@ void setup() #endif #if defined(ARCH_PORTDUINO) // make it work - if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) { + if (settingsMap.count(userButtonPin) != 0 && settingsMap[userButtonPin] != RADIOLIB_NC) { - LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]); + LOG_DEBUG("Use GPIO%02d for button", settingsMap[userButtonPin]); + UserButtonThread = new ButtonThread("UserButton"); + if (screen) + UserButtonThread->initButton( + settingsMap[userButtonPin], true, true, INPUT_PULLUP, // pull up bias + []() { + UserButtonThread->userButton.tick(); + runASAP = true; + BaseType_t higherWake = 0; + mainDelay.interruptFromISR(&higherWake); + }, + INPUT_BROKER_USER_PRESS, INPUT_BROKER_SELECT); } #endif diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index f7e15db7c..f6d5820da 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -206,7 +206,7 @@ void setupModules() #if HAS_TRACKBALL && !MESHTASTIC_EXCLUDE_INPUTBROKER if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { trackballInterruptImpl1 = new TrackballInterruptImpl1(); - trackballInterruptImpl1->init(); + trackballInterruptImpl1->init(TB_DOWN, TB_UP, TB_LEFT, TB_RIGHT, TB_PRESS); } #endif #ifdef INPUTBROKER_EXPRESSLRSFIVEWAY_TYPE diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index cc0c417d3..8a8bed2aa 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -146,7 +146,7 @@ void portduinoSetup() const configNames GPIO_lines[] = { cs_pin, irq_pin, busy_pin, reset_pin, sx126x_ant_sw_pin, txen_pin, rxen_pin, displayDC, displayCS, displayBacklight, displayBacklightPWMChannel, displayReset, - touchscreenCS, touchscreenIRQ, user}; + touchscreenCS, touchscreenIRQ, userButtonPin, tbUpPin, tbDownPin, tbLeftPin, tbRightPin, tbPressPin}; std::string gpioChipName = "gpiochip"; settingsStrings[i2cdev] = ""; @@ -313,9 +313,34 @@ void portduinoSetup() // Need to bind all the configured GPIO pins so they're not simulated // TODO: If one of these fails, we should log and terminate - if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[user], defaultGpioChipName, settingsMap[user]) != ERRNO_OK) { - settingsMap[user] = RADIOLIB_NC; + if (settingsMap.count(userButtonPin) > 0 && settingsMap[userButtonPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[userButtonPin], defaultGpioChipName, settingsMap[userButtonPin]) != ERRNO_OK) { + settingsMap[userButtonPin] = RADIOLIB_NC; + } + } + if (settingsMap.count(tbUpPin) > 0 && settingsMap[tbUpPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[tbUpPin], defaultGpioChipName, settingsMap[tbUpPin]) != ERRNO_OK) { + settingsMap[tbUpPin] = RADIOLIB_NC; + } + } + if (settingsMap.count(tbDownPin) > 0 && settingsMap[tbDownPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[tbDownPin], defaultGpioChipName, settingsMap[tbDownPin]) != ERRNO_OK) { + settingsMap[tbDownPin] = RADIOLIB_NC; + } + } + if (settingsMap.count(tbLeftPin) > 0 && settingsMap[tbLeftPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[tbLeftPin], defaultGpioChipName, settingsMap[tbLeftPin]) != ERRNO_OK) { + settingsMap[tbLeftPin] = RADIOLIB_NC; + } + } + if (settingsMap.count(tbRightPin) > 0 && settingsMap[tbRightPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[tbRightPin], defaultGpioChipName, settingsMap[tbRightPin]) != ERRNO_OK) { + settingsMap[tbRightPin] = RADIOLIB_NC; + } + } + if (settingsMap.count(tbPressPin) > 0 && settingsMap[tbPressPin] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[tbPressPin], defaultGpioChipName, settingsMap[tbPressPin]) != ERRNO_OK) { + settingsMap[tbPressPin] = RADIOLIB_NC; } } if (settingsMap[displayPanel] != no_screen) { @@ -377,6 +402,8 @@ int initGPIOPin(int pinNum, const std::string gpioChipName, int line) { #ifdef PORTDUINO_LINUX_HARDWARE std::string gpio_name = "GPIO" + std::to_string(pinNum); + std::cout << gpio_name; + printf("\n"); try { GPIOPin *csPin; csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), line, gpio_name.c_str()); @@ -498,7 +525,12 @@ bool loadConfig(const char *configPath) } } if (yamlConfig["GPIO"]) { - settingsMap[user] = yamlConfig["GPIO"]["User"].as(RADIOLIB_NC); + settingsMap[userButtonPin] = yamlConfig["GPIO"]["User"].as(RADIOLIB_NC); + settingsMap[tbUpPin] = yamlConfig["GPIO"]["TrackballUp"].as(RADIOLIB_NC); + settingsMap[tbDownPin] = yamlConfig["GPIO"]["TrackballDown"].as(RADIOLIB_NC); + settingsMap[tbLeftPin] = yamlConfig["GPIO"]["TrackballLeft"].as(RADIOLIB_NC); + settingsMap[tbRightPin] = yamlConfig["GPIO"]["TrackballRight"].as(RADIOLIB_NC); + settingsMap[tbPressPin] = yamlConfig["GPIO"]["TrackballPress"].as(RADIOLIB_NC); } if (yamlConfig["GPS"]) { std::string serialPath = yamlConfig["GPS"]["SerialPath"].as(""); diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index d324aaf47..43aea4218 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -57,7 +57,12 @@ enum configNames { lora_usb_serial_num, lora_usb_pid, lora_usb_vid, - user, + userButtonPin, + tbUpPin, + tbDownPin, + tbLeftPin, + tbRightPin, + tbPressPin, spidev, spiSpeed, i2cdev, diff --git a/src/platform/portduino/architecture.h b/src/platform/portduino/architecture.h index a5e263d5a..1751fb8cd 100644 --- a/src/platform/portduino/architecture.h +++ b/src/platform/portduino/architecture.h @@ -8,6 +8,9 @@ #define HW_VENDOR meshtastic_HardwareModel_PORTDUINO +#ifndef HAS_BUTTON +#define HAS_BUTTON 1 +#endif #ifndef HAS_WIFI #define HAS_WIFI 1 #endif @@ -22,4 +25,12 @@ #endif #ifndef HAS_SENSOR #define HAS_SENSOR 1 +#endif +#ifndef HAS_TRACKBALL +#define HAS_TRACKBALL 1 +#define TB_DOWN (uint8_t)settingsMap[tbDownPin] +#define TB_UP (uint8_t)settingsMap[tbUpPin] +#define TB_LEFT (uint8_t)settingsMap[tbLeftPin] +#define TB_RIGHT (uint8_t)settingsMap[tbRightPin] +#define TB_PRESS (uint8_t)settingsMap[tbPressPin] #endif \ No newline at end of file