kopia lustrzana https://github.com/meshtastic/firmware
				
				
				
			Portduino work (#3049)
* Move to Portduino's getMacAddr() * Add ST7735/S screen support * Push Raspbian support into native target * Remove latent pigpio references. * CardKB defensive programming * Adds configurable spidev * Fixes to build on Fedora 40 * ENUMs are not #defines. Pull latest portduino * Add more configuration options for SPI displays * Add config.yaml option to set DIO3_TCXO_VOLTAGE * change tft clear() to fillScreen() Maintains compatability with ESPI driver. * Adds TXen and RXen pins to portduino * Add -c --config options to specify config file * Fail when a specified config file is unavailable --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>pull/3084/head^2
							rodzic
							
								
									7e53a96ee5
								
							
						
					
					
						commit
						4a867c81c0
					
				|  | @ -1,6 +1,6 @@ | |||
| ; The Portduino based sim environment on top of any host OS, all hardware will be simulated | ||||
| [portduino_base] | ||||
| platform = https://github.com/meshtastic/platform-native.git#8a66ef82cf38a4135d85cbb5043d0e8ebbb8ba17 | ||||
| platform = https://github.com/meshtastic/platform-native.git#04435d06e39916a6c019d511518d8e95c659dfbd | ||||
| framework = arduino | ||||
| 
 | ||||
| build_src_filter =  | ||||
|  | @ -28,4 +28,8 @@ build_flags = | |||
|   ${arduino_base.build_flags} | ||||
|   -fPIC | ||||
|   -Isrc/platform/portduino | ||||
|   -DRADIOLIB_EEPROM_UNSUPPORTED | ||||
|   -DRADIOLIB_EEPROM_UNSUPPORTED | ||||
|   -DPORTDUINO_LINUX_HARDWARE | ||||
|   -lbluetooth | ||||
|   -lgpiod | ||||
|   -lyaml-cpp | ||||
|  | @ -14,6 +14,12 @@ Lora: | |||
| #  IRQ: 17 | ||||
| #  Reset: 22 | ||||
| 
 | ||||
| #  Module: sx1262  # pinedio | ||||
| #  CS: 0 | ||||
| #  IRQ: 10 | ||||
| #  Busy: 11 | ||||
| #  spidev: spidev0.1 | ||||
| 
 | ||||
| #  Module: RF95  # Adafruit RFM9x | ||||
| #  Reset: 25 | ||||
| #  CS: 7 | ||||
|  | @ -31,10 +37,19 @@ Lora: | |||
| #  Busy: 20 | ||||
| #  Reset: 18 | ||||
| 
 | ||||
| #  DIO3_TCXO_VOLTAGE: true  # the Waveshare Core1262 and others are known to need this setting | ||||
| 
 | ||||
| #  TXen: x  # TX and RX enable pins | ||||
| #  RXen: x | ||||
| 
 | ||||
| ### Set gpio chip to use in /dev/. Defaults to 0. | ||||
| ### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4 | ||||
| #  gpiochip: 4 | ||||
| 
 | ||||
| ### Specify the SPI device to use in /dev/. Defaults to spidev0.0 | ||||
| ### Some devices, like the pinedio, may require spidev0.1 as a workaround. | ||||
| #  spidev: spidev0.0 | ||||
| 
 | ||||
| ### Define GPIO buttons here: | ||||
| 
 | ||||
| GPIO: | ||||
|  | @ -58,6 +73,18 @@ Display: | |||
| #  Height: 320 | ||||
| #  Reset: 27 | ||||
| #  Rotate: true | ||||
| #  Invert: true | ||||
| 
 | ||||
| ### Waveshare 1.44inch LCD HAT | ||||
| #  Panel: ST7735S | ||||
| #  CS: 8         #Chip Select | ||||
| #  DC: 25        # Data/Command pin | ||||
| #  Backlight: 24 | ||||
| #  Width: 128 | ||||
| #  Height: 128 | ||||
| #  Reset: 27 | ||||
| #  OffsetX: 0 | ||||
| #  OffsetY: 0 | ||||
| 
 | ||||
| Touchscreen: | ||||
| #  Module: XPT2046 | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ class ButtonThread : public concurrency::OSThread | |||
| #ifdef BUTTON_PIN_TOUCH | ||||
|     OneButton userButtonTouch; | ||||
| #endif | ||||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(ARCH_PORTDUINO) | ||||
|     OneButton userButton; | ||||
| #endif | ||||
|     static bool shutdown_on_long_stop; | ||||
|  | @ -49,8 +49,8 @@ class ButtonThread : public concurrency::OSThread | |||
|     // callback returns the period for the next callback invocation (or 0 if we should no longer be called)
 | ||||
|     ButtonThread() : OSThread("Button") | ||||
|     { | ||||
| #if defined(ARCH_RASPBERRY_PI) || defined(BUTTON_PIN) | ||||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(ARCH_PORTDUINO) || defined(BUTTON_PIN) | ||||
| #if defined(ARCH_PORTDUINO) | ||||
|         if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) | ||||
|             userButton = OneButton(settingsMap[user], true, true); | ||||
| #elif defined(BUTTON_PIN) | ||||
|  | @ -68,7 +68,7 @@ class ButtonThread : public concurrency::OSThread | |||
|         userButton.attachMultiClick(userButtonMultiPressed); | ||||
|         userButton.attachLongPressStart(userButtonPressedLongStart); | ||||
|         userButton.attachLongPressStop(userButtonPressedLongStop); | ||||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(ARCH_PORTDUINO) | ||||
|         if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) | ||||
|             wakeOnIrq(settingsMap[user], FALLING); | ||||
| #else | ||||
|  | @ -105,7 +105,7 @@ class ButtonThread : public concurrency::OSThread | |||
| #if defined(BUTTON_PIN) | ||||
|         userButton.tick(); | ||||
|         canSleep &= userButton.isIdle(); | ||||
| #elif defined(ARCH_RASPBERRY_PI) | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|         if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) { | ||||
|             userButton.tick(); | ||||
|             canSleep &= userButton.isIdle(); | ||||
|  | @ -143,7 +143,7 @@ class ButtonThread : public concurrency::OSThread | |||
|             powerFSM.trigger(EVENT_PRESS); | ||||
|         } | ||||
| #endif | ||||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(ARCH_PORTDUINO) | ||||
|         if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) && | ||||
|                 (settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) || | ||||
|             !moduleConfig.canned_message.enabled) { | ||||
|  |  | |||
|  | @ -100,9 +100,9 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) | |||
|                 int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; | ||||
|                 int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
 | ||||
| 
 | ||||
|                 r += printf("%s | %02d:%02d:%02d %u ", logLevel, hour, min, sec, millis() / 1000); | ||||
|                 r += ::printf("%s | %02d:%02d:%02d %u ", logLevel, hour, min, sec, millis() / 1000); | ||||
|             } else | ||||
|                 r += printf("%s | ??:??:?? %u ", logLevel, millis() / 1000); | ||||
|                 r += ::printf("%s | ??:??:?? %u ", logLevel, millis() / 1000); | ||||
| 
 | ||||
|             auto thread = concurrency::OSThread::currentThread; | ||||
|             if (thread) { | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| #include "concurrency/LockGuard.h" | ||||
| #include "configuration.h" | ||||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(ARCH_PORTDUINO) | ||||
| #include "linux/LinuxHardwareI2C.h" | ||||
| #endif | ||||
| #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| #define GPS_RESET_MODE HIGH | ||||
| #endif | ||||
| 
 | ||||
| #if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(aLinuxInputImpl) | ||||
| HardwareSerial *GPS::_serial_gps = &Serial1; | ||||
| #else | ||||
| HardwareSerial *GPS::_serial_gps = NULL; | ||||
|  | @ -924,7 +924,7 @@ GPS *GPS::createGps() | |||
|     if (!_en_gpio) | ||||
|         _en_gpio = PIN_GPS_EN; | ||||
| #endif | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
|     if (!settingsMap[has_gps]) | ||||
|         return nullptr; | ||||
| #endif | ||||
|  | @ -1286,4 +1286,4 @@ int32_t GPS::disable() | |||
|     setAwake(false); | ||||
| 
 | ||||
|     return INT32_MAX; | ||||
| } | ||||
| } | ||||
|  | @ -43,7 +43,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "sleep.h" | ||||
| #include "target_specific.h" | ||||
| 
 | ||||
| #if HAS_WIFI && !defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_WIFI && !defined(ARCH_PORTDUINO) | ||||
| #include "mesh/wifi/WiFiAPClient.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -52,7 +52,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "modules/esp32/StoreForwardModule.h" | ||||
| #endif | ||||
| 
 | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -930,8 +930,8 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O | |||
| #elif defined(USE_ST7567) | ||||
|     dispdev = new ST7567Wire(address.address, -1, -1, geometry, | ||||
|                              (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); | ||||
| #elif ARCH_RASPBERRY_PI | ||||
|     if (settingsMap[displayPanel] == st7789) { | ||||
| #elif ARCH_PORTDUINO | ||||
|     if (settingsMap[displayPanel] != no_screen) { | ||||
|         LOG_DEBUG("Making TFTDisplay!\n"); | ||||
|         dispdev = new TFTDisplay(address.address, -1, -1, geometry, | ||||
|                                  (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); | ||||
|  | @ -976,7 +976,7 @@ void Screen::handleSetOn(bool on) | |||
| #ifdef T_WATCH_S3 | ||||
|             PMU->enablePowerOutput(XPOWERS_ALDO2); | ||||
| #endif | ||||
| #if !ARCH_RASPBERRY_PI | ||||
| #if !ARCH_PORTDUINO | ||||
|             dispdev->displayOn(); | ||||
| #endif | ||||
|             dispdev->displayOn(); | ||||
|  | @ -1060,7 +1060,7 @@ void Screen::setup() | |||
|     uint8_t dmac[6]; | ||||
|     getMacAddr(dmac); | ||||
|     snprintf(ourId, sizeof(ourId), "%02x%02x", dmac[4], dmac[5]); | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|     handleSetOn(false); // force clean init
 | ||||
| #endif | ||||
| 
 | ||||
|  | @ -1075,7 +1075,7 @@ void Screen::setup() | |||
| #endif | ||||
|     serialSinceMsec = millis(); | ||||
| 
 | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[touchscreenModule]) { | ||||
|         touchScreenImpl1 = | ||||
|             new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast<TFTDisplay *>(dispdev)->getTouch); | ||||
|  | @ -1344,7 +1344,7 @@ void Screen::setFrames() | |||
|     // call a method on debugInfoScreen object (for more details)
 | ||||
|     normalFrames[numframes++] = &Screen::drawDebugInfoSettingsTrampoline; | ||||
| 
 | ||||
| #if HAS_WIFI && !defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_WIFI && !defined(ARCH_PORTDUINO) | ||||
|     if (isWifiAvailable()) { | ||||
|         // call a method on debugInfoScreen object (for more details)
 | ||||
|         normalFrames[numframes++] = &Screen::drawDebugInfoWiFiTrampoline; | ||||
|  | @ -1588,7 +1588,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 | |||
| #endif | ||||
|     } else { | ||||
|         // TODO: Raspberry Pi supports more than just the one screen size
 | ||||
| #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_RASPBERRY_PI) &&           \ | ||||
| #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_PORTDUINO) &&              \ | ||||
|     !defined(DISPLAY_FORCE_SMALL_FONTS) | ||||
|         display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, | ||||
|                                imgInfoL1); | ||||
|  | @ -1615,7 +1615,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 | |||
| // Jm
 | ||||
| void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) | ||||
| { | ||||
| #if HAS_WIFI && !defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_WIFI && !defined(ARCH_PORTDUINO) | ||||
|     const char *wifiName = config.network.wifi_ssid; | ||||
| 
 | ||||
|     display->setFont(FONT_SMALL); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #include "configuration.h" | ||||
| #include "main.h" | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -331,7 +331,7 @@ static LGFX *tft = nullptr; | |||
| #include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip | ||||
| 
 | ||||
| static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
 | ||||
| #elif ARCH_RASPBERRY_PI | ||||
| #elif ARCH_PORTDUINO | ||||
| #include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip | ||||
| 
 | ||||
| class LGFX : public lgfx::LGFX_Device | ||||
|  | @ -344,8 +344,12 @@ class LGFX : public lgfx::LGFX_Device | |||
|   public: | ||||
|     LGFX(void) | ||||
|     { | ||||
| 
 | ||||
|         _panel_instance = new lgfx::Panel_ST7789; | ||||
|         if (settingsMap[displayPanel] == st7789) | ||||
|             _panel_instance = new lgfx::Panel_ST7789; | ||||
|         else if (settingsMap[displayPanel] == st7735) | ||||
|             _panel_instance = new lgfx::Panel_ST7735; | ||||
|         else if (settingsMap[displayPanel] == st7735s) | ||||
|             _panel_instance = new lgfx::Panel_ST7735S; | ||||
|         auto buscfg = _bus_instance.config(); | ||||
|         buscfg.spi_mode = 0; | ||||
| 
 | ||||
|  | @ -356,19 +360,14 @@ class LGFX : public lgfx::LGFX_Device | |||
| 
 | ||||
|         auto cfg = _panel_instance->config(); // Gets a structure for display panel settings.
 | ||||
|         LOG_DEBUG("Height: %d, Width: %d \n", settingsMap[displayHeight], settingsMap[displayWidth]); | ||||
|         cfg.pin_cs = settingsMap[displayCS];           // Pin number where CS is connected (-1 = disable)
 | ||||
|         cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
 | ||||
|         cfg.pin_rst = settingsMap[displayReset]; | ||||
|         cfg.panel_width = settingsMap[displayWidth];   // actual displayable width
 | ||||
|         cfg.panel_height = settingsMap[displayHeight]; // actual displayable height
 | ||||
|         cfg.offset_x = 0;                              // Panel offset amount in X direction
 | ||||
|         cfg.offset_y = 0;                              // Panel offset amount in Y direction
 | ||||
|         cfg.offset_x = settingsMap[displayOffsetX];    // Panel offset amount in X direction
 | ||||
|         cfg.offset_y = settingsMap[displayOffsetY];    // Panel offset amount in Y direction
 | ||||
|         cfg.offset_rotation = 0;                       // Rotation direction value offset 0~7 (4~7 is mirrored)
 | ||||
|         cfg.dummy_read_pixel = 9;                      // Number of bits for dummy read before pixel readout
 | ||||
|         cfg.dummy_read_bits = 1;                       // Number of bits for dummy read before non-pixel data read
 | ||||
|         cfg.readable = true;                           // Set to true if data can be read
 | ||||
|         cfg.invert = true;                             // Set to true if the light/darkness of the panel is reversed
 | ||||
|         cfg.rgb_order = false;                         // Set to true if the panel's red and blue are swapped
 | ||||
|         cfg.dlen_16bit = false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
 | ||||
|         cfg.bus_shared = true;  // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
 | ||||
|         cfg.invert = settingsMap[displayInvert];       // Set to true if the light/darkness of the panel is reversed
 | ||||
| 
 | ||||
|         _panel_instance->config(cfg); | ||||
| 
 | ||||
|  | @ -399,7 +398,7 @@ class LGFX : public lgfx::LGFX_Device | |||
| static LGFX *tft = nullptr; | ||||
| #endif | ||||
| 
 | ||||
| #if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || ARCH_RASPBERRY_PI | ||||
| #if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || ARCH_PORTDUINO | ||||
| #include "SPILock.h" | ||||
| #include "TFTDisplay.h" | ||||
| #include <SPI.h> | ||||
|  | @ -407,7 +406,7 @@ static LGFX *tft = nullptr; | |||
| TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus) | ||||
| { | ||||
|     LOG_DEBUG("TFTDisplay!\n"); | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[displayRotate]) { | ||||
|         setGeometry(GEOMETRY_RAWMODE, settingsMap[configNames::displayHeight], settingsMap[configNames::displayWidth]); | ||||
|     } else { | ||||
|  | @ -460,7 +459,7 @@ void TFTDisplay::sendCommand(uint8_t com) | |||
|     // handle display on/off directly
 | ||||
|     switch (com) { | ||||
|     case DISPLAYON: { | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|         display(true); | ||||
|         if (settingsMap[displayBacklight] > 0) | ||||
|             digitalWrite(settingsMap[displayBacklight], TFT_BACKLIGHT_ON); | ||||
|  | @ -492,7 +491,7 @@ void TFTDisplay::sendCommand(uint8_t com) | |||
|         break; | ||||
|     } | ||||
|     case DISPLAYOFF: { | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|         tft->clear(); | ||||
|         if (settingsMap[displayBacklight] > 0) | ||||
|             digitalWrite(settingsMap[displayBacklight], !TFT_BACKLIGHT_ON); | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3 | |||
| const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF}; | ||||
| const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF}; | ||||
| 
 | ||||
| #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_RASPBERRY_PI) &&           \ | ||||
| #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_PORTDUINO) &&              \ | ||||
|     !defined(DISPLAY_FORCE_SMALL_FONTS) | ||||
| const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff}; | ||||
| const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f}; | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| #if ARCH_RASPBERRY_PI | ||||
| #include "LinuxInput.h" | ||||
| #include "configuration.h" | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
| #include "LinuxInput.h" | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #include <assert.h> | ||||
| #include <ctype.h> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| #pragma once | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
| #include "InputBroker.h" | ||||
| #include "concurrency/OSThread.h" | ||||
| #include <assert.h> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #if ARCH_RASPBERRY_PI | ||||
| #include "LinuxInputImpl.h" | ||||
| #include "configuration.h" | ||||
| #if ARCH_PORTDUINO | ||||
| #include "InputBroker.h" | ||||
| #include "LinuxInputImpl.h" | ||||
| 
 | ||||
| LinuxInputImpl *aLinuxInputImpl; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
| #pragma once | ||||
| #include "LinuxInput.h" | ||||
| #include "main.h" | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| #include "configuration.h" | ||||
| #include "modules/ExternalNotificationModule.h" | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -17,7 +17,7 @@ TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTo | |||
| 
 | ||||
| void TouchScreenImpl1::init() | ||||
| { | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[touchscreenModule]) { | ||||
|         TouchScreenBase::init(true); | ||||
|         inputBroker->registerSource(this); | ||||
|  |  | |||
|  | @ -187,7 +187,7 @@ int32_t KbI2cBase::runOnce() | |||
| 
 | ||||
|         i2cBus->requestFrom((int)cardkb_found.address, 1); | ||||
| 
 | ||||
|         while (i2cBus->available()) { | ||||
|         if (i2cBus->available()) { | ||||
|             char c = i2cBus->read(); | ||||
|             InputEvent e; | ||||
|             e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; | ||||
|  | @ -222,7 +222,11 @@ int32_t KbI2cBase::runOnce() | |||
|             case 0x00: // nopress
 | ||||
|                 e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; | ||||
|                 break; | ||||
|             default: // all other keys
 | ||||
|             default:           // all other keys
 | ||||
|                 if (c > 127) { // bogus key value
 | ||||
|                     e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; | ||||
|                     break; | ||||
|                 } | ||||
|                 e.inputEvent = ANYKEY; | ||||
|                 e.kbchar = c; | ||||
|                 break; | ||||
|  | @ -238,4 +242,4 @@ int32_t KbI2cBase::runOnce() | |||
|         LOG_WARN("Unknown kb_model 0x%02x\n", kb_model); | ||||
|     } | ||||
|     return 300; | ||||
| } | ||||
| } | ||||
							
								
								
									
										48
									
								
								src/main.cpp
								
								
								
								
							
							
						
						
									
										48
									
								
								src/main.cpp
								
								
								
								
							|  | @ -66,7 +66,7 @@ NRF52Bluetooth *nrf52Bluetooth; | |||
| #include "platform/portduino/SimRadio.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
| #include "linux/LinuxHardwareI2C.h" | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #include <fstream> | ||||
|  | @ -74,7 +74,7 @@ NRF52Bluetooth *nrf52Bluetooth; | |||
| #include <string> | ||||
| #endif | ||||
| 
 | ||||
| #if HAS_BUTTON || defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_BUTTON || defined(ARCH_PORTDUINO) | ||||
| #include "ButtonThread.h" | ||||
| #endif | ||||
| #include "PowerFSMThread.h" | ||||
|  | @ -141,32 +141,12 @@ std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySenso | |||
| 
 | ||||
| Router *router = NULL; // Users of router don't care what sort of subclass implements that API
 | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| void getPiMacAddr(uint8_t *dmac) | ||||
| { | ||||
|     std::fstream macIdentity; | ||||
|     macIdentity.open("/sys/kernel/debug/bluetooth/hci0/identity", std::ios::in); | ||||
|     std::string macLine; | ||||
|     getline(macIdentity, macLine); | ||||
|     macIdentity.close(); | ||||
| 
 | ||||
|     dmac[0] = strtol(macLine.substr(0, 2).c_str(), NULL, 16); | ||||
|     dmac[1] = strtol(macLine.substr(3, 2).c_str(), NULL, 16); | ||||
|     dmac[2] = strtol(macLine.substr(6, 2).c_str(), NULL, 16); | ||||
|     dmac[3] = strtol(macLine.substr(9, 2).c_str(), NULL, 16); | ||||
|     dmac[4] = strtol(macLine.substr(12, 2).c_str(), NULL, 16); | ||||
|     dmac[5] = strtol(macLine.substr(15, 2).c_str(), NULL, 16); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| const char *getDeviceName() | ||||
| { | ||||
|     uint8_t dmac[6]; | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
|     getPiMacAddr(dmac); | ||||
| #else | ||||
| 
 | ||||
|     getMacAddr(dmac); | ||||
| #endif | ||||
| 
 | ||||
|     // Meshtastic_ab3c or Shortname_abcd
 | ||||
|     static char name[20]; | ||||
|     snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]); | ||||
|  | @ -211,13 +191,13 @@ static int32_t ledBlinker() | |||
| 
 | ||||
| uint32_t timeLastPowered = 0; | ||||
| 
 | ||||
| #if HAS_BUTTON || defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_BUTTON || defined(ARCH_PORTDUINO) | ||||
| bool ButtonThread::shutdown_on_long_stop = false; | ||||
| #endif | ||||
| 
 | ||||
| static Periodic *ledPeriodic; | ||||
| static OSThread *powerFSMthread; | ||||
| #if HAS_BUTTON || defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_BUTTON || defined(ARCH_PORTDUINO) | ||||
| static OSThread *buttonThread; | ||||
| uint32_t ButtonThread::longPressTime = 0; | ||||
| #endif | ||||
|  | @ -613,7 +593,7 @@ void setup() | |||
|     } else | ||||
|         router = new ReliableRouter(); | ||||
| 
 | ||||
| #if HAS_BUTTON || defined(ARCH_RASPBERRY_PI) | ||||
| #if HAS_BUTTON || defined(ARCH_PORTDUINO) | ||||
|     // Buttons. Moved here cause we need NodeDB to be initialized
 | ||||
|     buttonThread = new ButtonThread(); | ||||
| #endif | ||||
|  | @ -664,12 +644,14 @@ void setup() | |||
|     pinMode(LORA_CS, OUTPUT); | ||||
|     digitalWrite(LORA_CS, HIGH); | ||||
|     SPI1.begin(false); | ||||
| #else                      // HW_SPI1_DEVICE
 | ||||
| #else  // HW_SPI1_DEVICE
 | ||||
|     SPI.setSCK(LORA_SCK); | ||||
|     SPI.setTX(LORA_MOSI); | ||||
|     SPI.setRX(LORA_MISO); | ||||
|     SPI.begin(false); | ||||
| #endif                     // HW_SPI1_DEVICE
 | ||||
| #endif // HW_SPI1_DEVICE
 | ||||
| #elif ARCH_PORTDUINO | ||||
|     SPI.begin(settingsStrings[spidev].c_str()); | ||||
| #elif !defined(ARCH_ESP32) // ARCH_RP2040
 | ||||
|     SPI.begin(); | ||||
| #else | ||||
|  | @ -715,7 +697,7 @@ void setup() | |||
| // the current region name)
 | ||||
| #if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) | ||||
|     screen->setup(); | ||||
| #elif ARCH_RASPBERRY_PI | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|     if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) { | ||||
|         screen->setup(); | ||||
|     } | ||||
|  | @ -732,7 +714,7 @@ void setup() | |||
|     digitalWrite(SX126X_ANT_SW, 1); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
|     if (settingsMap[use_sx1262]) { | ||||
|         if (!rIf) { | ||||
|             LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); | ||||
|  | @ -822,7 +804,7 @@ void setup() | |||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(USE_SX1262) && !defined(ARCH_RASPBERRY_PI) | ||||
| #if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) | ||||
|     if (!rIf) { | ||||
|         rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); | ||||
|         if (!rIf->init()) { | ||||
|  | @ -997,4 +979,4 @@ void loop() | |||
|         mainDelay.delay(delayMsec); | ||||
|     } | ||||
|     // if (didWake) LOG_DEBUG("wake!\n");
 | ||||
| } | ||||
| } | ||||
|  | @ -62,7 +62,6 @@ extern graphics::Screen *screen; | |||
| 
 | ||||
| // Return a human readable string of the form "Meshtastic_ab13"
 | ||||
| const char *getDeviceName(); | ||||
| void getPiMacAddr(uint8_t *dmac); | ||||
| 
 | ||||
| extern uint32_t timeLastPowered; | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ | |||
| #include <nvs_flash.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
| #include "platform/portduino/PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -195,7 +195,7 @@ void NodeDB::installDefaultConfig() | |||
|     config.bluetooth.fixed_pin = defaultBLEPin; | ||||
| #if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) | ||||
|     bool hasScreen = true; | ||||
| #elif ARCH_RASPBERRY_PI | ||||
| #elif ARCH_PORTDUINO | ||||
|     bool hasScreen = false; | ||||
|     if (settingsMap[displayPanel]) | ||||
|         hasScreen = true; | ||||
|  | @ -464,11 +464,8 @@ void NodeDB::init() | |||
|  */ | ||||
| void NodeDB::pickNewNodeNum() | ||||
| { | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
|     getPiMacAddr(ourMacAddr); // Make sure ourMacAddr is set
 | ||||
| #else | ||||
| 
 | ||||
|     getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
 | ||||
| #endif | ||||
| 
 | ||||
|     // Pick an initial nodenum based on the macaddr
 | ||||
|     NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5]; | ||||
|  |  | |||
|  | @ -4,6 +4,10 @@ | |||
| #include "configuration.h" | ||||
| #include "error.h" | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
| #include "PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
| #define MAX_POWER 20 | ||||
| // if we use 20 we are limited to 1% duty cycle or hw might overheat.  For continuous operation set a limit of 17
 | ||||
| // In theory up to 27 dBm is possible, but the modules installed in most radios can cope with a max of 20.  So BIG WARNING
 | ||||
|  | @ -23,10 +27,18 @@ void RF95Interface::setTransmitEnable(bool txon) | |||
| { | ||||
| #ifdef RF95_TXEN | ||||
|     digitalWrite(RF95_TXEN, txon ? 1 : 0); | ||||
| #elif ARCH_PORTDUINO | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[txen], txon ? 1 : 0); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RF95_RXEN | ||||
|     digitalWrite(RF95_RXEN, txon ? 0 : 1); | ||||
| #elif ARCH_PORTDUINO | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[rxen], txon ? 0 : 1); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -62,6 +74,16 @@ bool RF95Interface::init() | |||
| #ifdef RF95_RXEN | ||||
|     pinMode(RF95_RXEN, OUTPUT); | ||||
|     digitalWrite(RF95_RXEN, 1); | ||||
| #endif | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         pinMode(settingsMap[txen], OUTPUT); | ||||
|         digitalWrite(settingsMap[txen], 0); | ||||
|     } | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         pinMode(settingsMap[rxen], OUTPUT); | ||||
|         digitalWrite(settingsMap[rxen], 0); | ||||
|     } | ||||
| #endif | ||||
|     setTransmitEnable(false); | ||||
| 
 | ||||
|  | @ -202,4 +224,4 @@ bool RF95Interface::sleep() | |||
|     lora->sleep(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| } | ||||
|  | @ -2,7 +2,7 @@ | |||
| #include "configuration.h" | ||||
| #include "error.h" | ||||
| #include "mesh/NodeDB.h" | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #ifdef ARCH_PORTDUINO | ||||
| #include "PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
|  | @ -30,18 +30,25 @@ template <typename T> bool SX126xInterface<T>::init() | |||
|     digitalWrite(SX126X_POWER_EN, HIGH); | ||||
| #endif | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
|     float tcxoVoltage = 0; | ||||
|     if (settingsMap[dio3_tcxo_voltage]) | ||||
|         tcxoVoltage = 1.8; | ||||
| // FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
 | ||||
| #if !defined(SX126X_DIO3_TCXO_VOLTAGE) | ||||
| #elif !defined(SX126X_DIO3_TCXO_VOLTAGE) | ||||
|     float tcxoVoltage = | ||||
|         0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
 | ||||
|            // https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.h#L471C26-L471C104
 | ||||
|     // (DIO3 is free to be used as an IRQ)
 | ||||
|     LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n"); | ||||
| #else | ||||
|     float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; | ||||
|     LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", SX126X_DIO3_TCXO_VOLTAGE); | ||||
|     // (DIO3 is not free to be used as an IRQ)
 | ||||
| #endif | ||||
|     if (tcxoVoltage == 0) | ||||
|         LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n"); | ||||
|     else | ||||
|         LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", tcxoVoltage); | ||||
| 
 | ||||
|     // FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
 | ||||
|     bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
 | ||||
| 
 | ||||
|  | @ -77,7 +84,7 @@ template <typename T> bool SX126xInterface<T>::init() | |||
| #ifdef SX126X_DIO2_AS_RF_SWITCH | ||||
|     LOG_DEBUG("Setting DIO2 as RF switch\n"); | ||||
|     bool dio2AsRfSwitch = true; | ||||
| #elif defined(ARCH_RASPBERRY_PI) | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|     bool dio2AsRfSwitch = false; | ||||
|     if (settingsMap[dio2_as_rf_switch]) { | ||||
|         LOG_DEBUG("Setting DIO2 as RF switch\n"); | ||||
|  | @ -93,6 +100,12 @@ template <typename T> bool SX126xInterface<T>::init() | |||
| 
 | ||||
|     // If a pin isn't defined, we set it to RADIOLIB_NC, it is safe to always do external RF switching with RADIOLIB_NC as it has
 | ||||
|     // no effect
 | ||||
| #if ARCH_PORTDUINO | ||||
|     if (res == RADIOLIB_ERR_NONE) { | ||||
|         LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", settingsMap[rxen], settingsMap[txen]); | ||||
|         lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]); | ||||
|     } | ||||
| #else | ||||
| #ifndef SX126X_RXEN | ||||
| #define SX126X_RXEN RADIOLIB_NC | ||||
|     LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC\n"); | ||||
|  | @ -105,7 +118,7 @@ template <typename T> bool SX126xInterface<T>::init() | |||
|         LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", SX126X_RXEN, SX126X_TXEN); | ||||
|         lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN); | ||||
|     } | ||||
| 
 | ||||
| #endif | ||||
|     if (config.lora.sx126x_rx_boosted_gain) { | ||||
|         uint16_t result = lora.setRxBoostedGainMode(true); | ||||
|         LOG_INFO("Set RX gain to boosted mode; result: %d\n", result); | ||||
|  | @ -322,4 +335,4 @@ template <typename T> bool SX126xInterface<T>::sleep() | |||
| #endif | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| } | ||||
|  | @ -3,6 +3,10 @@ | |||
| #include "error.h" | ||||
| #include "mesh/NodeDB.h" | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
| #include "PortduinoGlue.h" | ||||
| #endif | ||||
| 
 | ||||
| // Particular boards might define a different max power based on what their hardware can do
 | ||||
| #ifndef SX128X_MAX_POWER | ||||
| #define SX128X_MAX_POWER 13 | ||||
|  | @ -31,6 +35,16 @@ template <typename T> bool SX128xInterface<T>::init() | |||
|     digitalWrite(RF95_FAN_EN, 1); | ||||
| #endif | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         pinMode(settingsMap[rxen], OUTPUT); | ||||
|         digitalWrite(settingsMap[rxen], LOW); // Set low before becoming an output
 | ||||
|     } | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         pinMode(settingsMap[txen], OUTPUT); | ||||
|         digitalWrite(settingsMap[txen], LOW); // Set low before becoming an output
 | ||||
|     } | ||||
| #else | ||||
| #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
 | ||||
|     pinMode(SX128X_RXEN, OUTPUT); | ||||
|     digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
 | ||||
|  | @ -38,6 +52,7 @@ template <typename T> bool SX128xInterface<T>::init() | |||
| #if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) | ||||
|     pinMode(SX128X_TXEN, OUTPUT); | ||||
|     digitalWrite(SX128X_TXEN, LOW); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|     RadioLibInterface::init(); | ||||
|  | @ -75,6 +90,10 @@ template <typename T> bool SX128xInterface<T>::init() | |||
|     if (res == RADIOLIB_ERR_NONE) { | ||||
|         lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN); | ||||
|     } | ||||
| #elif ARCH_PORTDUINO | ||||
|     if (res == RADIOLIB_ERR_NONE && settingsMap[rxen] != RADIOLIB_NC && settingsMap[txen] != RADIOLIB_NC) { | ||||
|         lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     if (res == RADIOLIB_ERR_NONE) | ||||
|  | @ -148,14 +167,21 @@ template <typename T> void SX128xInterface<T>::setStandby() | |||
|     } | ||||
| 
 | ||||
|     assert(err == RADIOLIB_ERR_NONE); | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[rxen], LOW); | ||||
|     } | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[txen], LOW); | ||||
|     } | ||||
| #else | ||||
| #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power
 | ||||
|     digitalWrite(SX128X_RXEN, LOW); | ||||
| #endif | ||||
| #if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) | ||||
|     digitalWrite(SX128X_TXEN, LOW); | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
|     isReceiving = false; // If we were receiving, not any more
 | ||||
|     activeReceiveStart = 0; | ||||
|     disableInterrupt(); | ||||
|  | @ -176,11 +202,21 @@ template <typename T> void SX128xInterface<T>::addReceiveMetadata(meshtastic_Mes | |||
|  */ | ||||
| template <typename T> void SX128xInterface<T>::configHardwareForSend() | ||||
| { | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[txen], HIGH); | ||||
|     } | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[rxen], LOW); | ||||
|     } | ||||
| 
 | ||||
| #else | ||||
| #if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
 | ||||
|     digitalWrite(SX128X_TXEN, HIGH); | ||||
| #endif | ||||
| #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) | ||||
|     digitalWrite(SX128X_RXEN, LOW); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|     RadioLibInterface::configHardwareForSend(); | ||||
|  | @ -197,11 +233,21 @@ template <typename T> void SX128xInterface<T>::startReceive() | |||
| 
 | ||||
|     setStandby(); | ||||
| 
 | ||||
| #if ARCH_PORTDUINO | ||||
|     if (settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[rxen], HIGH); | ||||
|     } | ||||
|     if (settingsMap[txen] != RADIOLIB_NC) { | ||||
|         digitalWrite(settingsMap[txen], LOW); | ||||
|     } | ||||
| 
 | ||||
| #else | ||||
| #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on RX power / off TX power
 | ||||
|     digitalWrite(SX128X_RXEN, HIGH); | ||||
| #endif | ||||
| #if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) | ||||
|     digitalWrite(SX128X_TXEN, LOW); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|     // We use the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
 | ||||
|  | @ -281,4 +327,4 @@ template <typename T> bool SX128xInterface<T>::sleep() | |||
| #endif | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| } | ||||
|  | @ -8,5 +8,6 @@ template <class T> constexpr const T &clamp(const T &v, const T &lo, const T &hi | |||
| 
 | ||||
| #if (defined(ARCH_PORTDUINO) && !defined(STRNSTR)) | ||||
| #define STRNSTR | ||||
| #include <string.h> | ||||
| char *strnstr(const char *s, const char *find, size_t slen); | ||||
| #endif | ||||
|  | @ -1,5 +1,5 @@ | |||
| #include "configuration.h" | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
| #include "PortduinoGlue.h" | ||||
| #endif | ||||
| #if HAS_SCREEN | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ | |||
| #include "modules/TextMessageModule.h" | ||||
| #include "modules/TraceRouteModule.h" | ||||
| #include "modules/WaypointModule.h" | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
| #include "input/LinuxInputImpl.h" | ||||
| #endif | ||||
| #if HAS_TELEMETRY | ||||
|  | @ -50,7 +50,7 @@ | |||
| void setupModules() | ||||
| { | ||||
|     if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) { | ||||
| #if HAS_BUTTON || ARCH_RASPBERRY_PI | ||||
| #if HAS_BUTTON || ARCH_PORTDUINO | ||||
|         inputBroker = new InputBroker(); | ||||
| #endif | ||||
|         adminModule = new AdminModule(); | ||||
|  | @ -67,7 +67,7 @@ void setupModules() | |||
| 
 | ||||
|         new RemoteHardwareModule(); | ||||
|         new ReplyModule(); | ||||
| #if HAS_BUTTON || ARCH_RASPBERRY_PI | ||||
| #if HAS_BUTTON || ARCH_PORTDUINO | ||||
|         rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); | ||||
|         if (!rotaryEncoderInterruptImpl1->init()) { | ||||
|             delete rotaryEncoderInterruptImpl1; | ||||
|  | @ -85,7 +85,7 @@ void setupModules() | |||
|         kbMatrixImpl->init(); | ||||
| #endif // INPUTBROKER_MATRIX_TYPE
 | ||||
| #endif // HAS_BUTTON
 | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if ARCH_PORTDUINO | ||||
|         aLinuxInputImpl = new LinuxInputImpl(); | ||||
|         aLinuxInputImpl->init(); | ||||
| #endif | ||||
|  |  | |||
|  | @ -8,10 +8,8 @@ | |||
| #include <Utility.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #include "PortduinoGlue.h" | ||||
| #include "linux/gpio/LinuxGPIOPin.h" | ||||
| #include "pigpio.h" | ||||
| #include "yaml-cpp/yaml.h" | ||||
| #include <iostream> | ||||
| #include <map> | ||||
|  | @ -19,10 +17,7 @@ | |||
| 
 | ||||
| std::map<configNames, int> settingsMap; | ||||
| std::map<configNames, std::string> settingsStrings; | ||||
| 
 | ||||
| #else | ||||
| #include <linux/gpio/LinuxGPIOPin.h> | ||||
| #endif | ||||
| char *configPath = nullptr; | ||||
| 
 | ||||
| // FIXME - move setBluetoothEnable into a HALPlatform class
 | ||||
| void setBluetoothEnable(bool on) | ||||
|  | @ -36,34 +31,7 @@ void cpuDeepSleep(uint32_t msecs) | |||
| } | ||||
| 
 | ||||
| void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); | ||||
| #ifndef ARCH_RASPBERRY_PI | ||||
| /** a simulated pin for busted IRQ hardware
 | ||||
|  * Porduino helper class to do this i2c based polling: | ||||
|  */ | ||||
| class PolledIrqPin : public GPIOPin | ||||
| { | ||||
|   public: | ||||
|     PolledIrqPin() : GPIOPin(LORA_DIO1, "loraIRQ") {} | ||||
| 
 | ||||
|     /// Read the low level hardware for this pin
 | ||||
|     virtual PinStatus readPinHardware() | ||||
|     { | ||||
|         if (isrPinStatus < 0) | ||||
|             return LOW; // No interrupt handler attached, don't bother polling i2c right now
 | ||||
|         else { | ||||
|             extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this
 | ||||
| 
 | ||||
|             assert(rIf); | ||||
|             RadioLibInterface *rIf95 = static_cast<RadioLibInterface *>(rIf); | ||||
|             bool p = rIf95->isIRQPending(); | ||||
|             log(SysGPIO, LogDebug, "PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p); | ||||
|             return p ? HIGH : LOW; | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static GPIOPin *loraIrq; | ||||
| #endif | ||||
| int TCPPort = 4403; | ||||
| 
 | ||||
| static error_t parse_opt(int key, char *arg, struct argp_state *state) | ||||
|  | @ -73,7 +41,10 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) | |||
|         if (sscanf(arg, "%d", &TCPPort) < 1) | ||||
|             return ARGP_ERR_UNKNOWN; | ||||
|         else | ||||
|             printf("Using TCP port %d\n", TCPPort); | ||||
|             printf("Using config file %d\n", TCPPort); | ||||
|         break; | ||||
|     case 'c': | ||||
|         configPath = arg; | ||||
|         break; | ||||
|     case ARGP_KEY_ARG: | ||||
|         return 0; | ||||
|  | @ -85,7 +56,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) | |||
| 
 | ||||
| void portduinoCustomInit() | ||||
| { | ||||
|     static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."}, {0}}; | ||||
|     static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."}, | ||||
|                                            {"config", 'c', "CONFIG_PATH", 0, "Full path of the .yaml config file to use."}, | ||||
|                                            {0}}; | ||||
|     static void *childArguments; | ||||
|     static char doc[] = "Meshtastic native build."; | ||||
|     static char args_doc[] = "..."; | ||||
|  | @ -101,14 +74,20 @@ void portduinoCustomInit() | |||
| void portduinoSetup() | ||||
| { | ||||
|     printf("Setting up Meshtastic on Portduino...\n"); | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
|     gpioInit(); | ||||
| 
 | ||||
|     std::string gpioChipName = "gpiochip"; | ||||
| 
 | ||||
|     YAML::Node yamlConfig; | ||||
| 
 | ||||
|     if (access("config.yaml", R_OK) == 0) { | ||||
|     if (configPath != nullptr) { | ||||
|         try { | ||||
|             yamlConfig = YAML::LoadFile(configPath); | ||||
|         } catch (YAML::Exception e) { | ||||
|             std::cout << "Could not open " << configPath << " because of error: " << e.what() << std::endl; | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|     } else if (access("config.yaml", R_OK) == 0) { | ||||
|         try { | ||||
|             yamlConfig = YAML::LoadFile("config.yaml"); | ||||
|         } catch (YAML::Exception e) { | ||||
|  | @ -123,8 +102,24 @@ void portduinoSetup() | |||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|     } else { | ||||
|         std::cout << "No 'config.yaml' found, exiting." << std::endl; | ||||
|         exit(EXIT_FAILURE); | ||||
|         std::cout << "No 'config.yaml' found, running simulated." << std::endl; | ||||
|         // Set the random seed equal to TCPPort to have a different seed per instance
 | ||||
|         randomSeed(TCPPort); | ||||
| 
 | ||||
|         /* Aren't all pins defaulted to simulated?
 | ||||
|         auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy"); | ||||
|         fakeBusy->writePin(LOW); | ||||
|         fakeBusy->setSilent(true); | ||||
|         gpioBind(fakeBusy); | ||||
| 
 | ||||
|         auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS"); | ||||
|         cs->setSilent(true); | ||||
|         gpioBind(cs); | ||||
| 
 | ||||
|         gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset")); | ||||
|         gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq")); | ||||
|         */ | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|  | @ -141,12 +136,17 @@ void portduinoSetup() | |||
|                 settingsMap[use_sx1280] = true; | ||||
|             } | ||||
|             settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false); | ||||
|             settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false); | ||||
|             settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[txen] = yamlConfig["Lora"]["TXen"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as<int>(RADIOLIB_NC); | ||||
|             settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0); | ||||
|             gpioChipName += std::to_string(settingsMap[gpiochip]); | ||||
| 
 | ||||
|             settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as<std::string>("spidev0.0"); | ||||
|         } | ||||
|         if (yamlConfig["GPIO"]) { | ||||
|             settingsMap[user] = yamlConfig["GPIO"]["User"].as<int>(RADIOLIB_NC); | ||||
|  | @ -162,13 +162,20 @@ void portduinoSetup() | |||
|         if (yamlConfig["Display"]) { | ||||
|             if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789") | ||||
|                 settingsMap[displayPanel] = st7789; | ||||
|             else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735") | ||||
|                 settingsMap[displayPanel] = st7735; | ||||
|             else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735S") | ||||
|                 settingsMap[displayPanel] = st7735s; | ||||
|             settingsMap[displayHeight] = yamlConfig["Display"]["Height"].as<int>(0); | ||||
|             settingsMap[displayWidth] = yamlConfig["Display"]["Width"].as<int>(0); | ||||
|             settingsMap[displayDC] = yamlConfig["Display"]["DC"].as<int>(-1); | ||||
|             settingsMap[displayCS] = yamlConfig["Display"]["CS"].as<int>(-1); | ||||
|             settingsMap[displayBacklight] = yamlConfig["Display"]["Backlight"].as<int>(-1); | ||||
|             settingsMap[displayReset] = yamlConfig["Display"]["Reset"].as<int>(-1); | ||||
|             settingsMap[displayOffsetX] = yamlConfig["Display"]["OffsetX"].as<int>(0); | ||||
|             settingsMap[displayOffsetY] = yamlConfig["Display"]["OffsetY"].as<int>(0); | ||||
|             settingsMap[displayRotate] = yamlConfig["Display"]["Rotate"].as<bool>(false); | ||||
|             settingsMap[displayInvert] = yamlConfig["Display"]["Invert"].as<bool>(false); | ||||
|         } | ||||
|         settingsMap[touchscreenModule] = no_touchscreen; | ||||
|         if (yamlConfig["Touchscreen"]) { | ||||
|  | @ -185,10 +192,6 @@ void portduinoSetup() | |||
|         std::cout << "*** Exception " << e.what() << std::endl; | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|     if (access("/sys/kernel/debug/bluetooth/hci0/identity", R_OK) != 0) { | ||||
|         std::cout << "Cannot read Bluetooth MAC Address. Please run as root" << std::endl; | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
| 
 | ||||
|     // Need to bind all the configured GPIO pins so they're not simulated
 | ||||
|     if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) { | ||||
|  | @ -216,6 +219,16 @@ void portduinoSetup() | |||
|             settingsMap[user] = RADIOLIB_NC; | ||||
|         } | ||||
|     } | ||||
|     if (settingsMap.count(rxen) > 0 && settingsMap[rxen] != RADIOLIB_NC) { | ||||
|         if (initGPIOPin(settingsMap[rxen], gpioChipName) != ERRNO_OK) { | ||||
|             settingsMap[rxen] = RADIOLIB_NC; | ||||
|         } | ||||
|     } | ||||
|     if (settingsMap.count(txen) > 0 && settingsMap[txen] != RADIOLIB_NC) { | ||||
|         if (initGPIOPin(settingsMap[txen], gpioChipName) != ERRNO_OK) { | ||||
|             settingsMap[txen] = RADIOLIB_NC; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (settingsMap[displayPanel] != no_screen) { | ||||
|         if (settingsMap[displayCS] > 0) | ||||
|  | @ -235,55 +248,8 @@ void portduinoSetup() | |||
|     } | ||||
| 
 | ||||
|     return; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef defined(PORTDUINO_LINUX_HARDWARE) | ||||
|     SPI.begin(); // We need to create SPI
 | ||||
|     bool usePineLora = !spiChip->isSimulated(); | ||||
|     if (usePineLora) { | ||||
|         printf("Connecting to PineLora board...\n"); | ||||
| 
 | ||||
|         // FIXME: remove this hack once interrupts are confirmed to work on new pine64 board
 | ||||
|         // loraIrq = new PolledIrqPin();
 | ||||
|         loraIrq = new LinuxGPIOPin(LORA_DIO1, "ch341", "int", "loraIrq"); // or "err"?
 | ||||
|         loraIrq->setSilent(); | ||||
|         gpioBind(loraIrq); | ||||
| 
 | ||||
|         // BUSY hw was busted on current board - just use the simulated pin (which will read low)
 | ||||
|         auto busy = new LinuxGPIOPin(SX126X_BUSY, "ch341", "slct", "loraBusy"); | ||||
|         busy->setSilent(); | ||||
|         gpioBind(busy); | ||||
| 
 | ||||
|         gpioBind(new LinuxGPIOPin(SX126X_RESET, "ch341", "ini", "loraReset")); | ||||
| 
 | ||||
|         auto loraCs = new LinuxGPIOPin(SX126X_CS, "ch341", "cs0", "loraCs"); | ||||
|         loraCs->setSilent(); | ||||
|         gpioBind(loraCs); | ||||
|     } else | ||||
| #endif | ||||
| #ifndef ARCH_RASPBERRY_PI | ||||
|     { | ||||
|         // Set the random seed equal to TCPPort to have a different seed per instance
 | ||||
|         randomSeed(TCPPort); | ||||
| 
 | ||||
|         auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy"); | ||||
|         fakeBusy->writePin(LOW); | ||||
|         fakeBusy->setSilent(true); | ||||
|         gpioBind(fakeBusy); | ||||
| 
 | ||||
|         auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS"); | ||||
|         cs->setSilent(true); | ||||
|         gpioBind(cs); | ||||
| 
 | ||||
|         gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset")); | ||||
|         gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq")); | ||||
|     } | ||||
|     // gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
 | ||||
|     // gpioBind((new SimGPIOPin(LORA_CS, "LORA_CS"))->setSilent());
 | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| int initGPIOPin(int pinNum, std::string gpioChipName) | ||||
| { | ||||
|     std::string gpio_name = "GPIO" + std::to_string(pinNum); | ||||
|  | @ -298,5 +264,4 @@ int initGPIOPin(int pinNum, std::string gpioChipName) | |||
|         std::cout << "Warning, cannot claim pin " << gpio_name << (p ? p.__cxa_exception_type()->name() : "null") << std::endl; | ||||
|         return ERRNO_DISABLED; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| } | ||||
|  | @ -1,5 +1,4 @@ | |||
| #pragma once | ||||
| #ifdef ARCH_RASPBERRY_PI | ||||
| #include <map> | ||||
| 
 | ||||
| enum configNames { | ||||
|  | @ -8,11 +7,15 @@ enum configNames { | |||
|     irq, | ||||
|     busy, | ||||
|     reset, | ||||
|     txen, | ||||
|     rxen, | ||||
|     dio2_as_rf_switch, | ||||
|     dio3_tcxo_voltage, | ||||
|     use_rf95, | ||||
|     use_sx1280, | ||||
|     user, | ||||
|     gpiochip, | ||||
|     spidev, | ||||
|     has_gps, | ||||
|     touchscreenModule, | ||||
|     touchscreenCS, | ||||
|  | @ -25,13 +28,14 @@ enum configNames { | |||
|     displayBacklight, | ||||
|     displayReset, | ||||
|     displayRotate, | ||||
|     displayOffsetX, | ||||
|     displayOffsetY, | ||||
|     displayInvert, | ||||
|     keyboardDevice | ||||
| }; | ||||
| enum { no_screen, st7789 }; | ||||
| enum { no_screen, st7789, st7735, st7735s }; | ||||
| enum { no_touchscreen, xpt2046 }; | ||||
| 
 | ||||
| extern std::map<configNames, int> settingsMap; | ||||
| extern std::map<configNames, std::string> settingsStrings; | ||||
| int initGPIOPin(int pinNum, std::string gpioChipname); | ||||
| 
 | ||||
| #endif | ||||
| int initGPIOPin(int pinNum, std::string gpioChipname); | ||||
|  | @ -1,6 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #define ARCH_PORTDUINO | ||||
| #define ARCH_PORTDUINO 1 | ||||
| 
 | ||||
| //
 | ||||
| // set HW_VENDOR
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| #include "graphics/Screen.h" | ||||
| #include "main.h" | ||||
| #include "power.h" | ||||
| #if ARCH_RASPBERRY_PI | ||||
| #if defined(ARCH_PORTDUINO) | ||||
| #include "api/WiFiServerAPI.h" | ||||
| #include "input/LinuxInputImpl.h" | ||||
| 
 | ||||
|  | @ -19,7 +19,7 @@ void powerCommandsCheck() | |||
|         NVIC_SystemReset(); | ||||
| #elif defined(ARCH_RP2040) | ||||
|         rp2040.reboot(); | ||||
| #elif defined(ARCH_RASPBERRY_PI) | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|         deInitApiServer(); | ||||
|         if (aLinuxInputImpl) | ||||
|             aLinuxInputImpl->deInit(); | ||||
|  | @ -27,11 +27,6 @@ void powerCommandsCheck() | |||
|         Wire.end(); | ||||
|         Serial1.end(); | ||||
|         reboot(); | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|         deInitApiServer(); | ||||
|         SPI.end(); | ||||
|         Wire.end(); | ||||
|         reboot(); | ||||
| #else | ||||
|         rebootAtMsec = -1; | ||||
|         LOG_WARN("FIXME implement reboot for this platform. Note that some settings require a restart to be applied.\n"); | ||||
|  | @ -49,7 +44,7 @@ void powerCommandsCheck() | |||
| #if defined(ARCH_NRF52) || defined(ARCH_ESP32) | ||||
|         playShutdownMelody(); | ||||
|         power->shutdown(); | ||||
| #elif ARCH_RASPBERRY_PI | ||||
| #elif defined(ARCH_PORTDUINO) | ||||
|         exit(EXIT_SUCCESS); | ||||
| #else | ||||
|         LOG_WARN("FIXME implement shutdown for this platform"); | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ extends = portduino_base | |||
| build_flags = ${portduino_base.build_flags} -O0 -I variants/portduino | ||||
| board = cross_platform | ||||
| lib_deps = ${portduino_base.lib_deps} | ||||
|   lovyan03/LovyanGFX@^1.1.12 | ||||
| build_src_filter = ${portduino_base.build_src_filter} | ||||
| 
 | ||||
| ; The Portduino based sim environment on top of a linux OS and touching linux hardware devices | ||||
|  | @ -16,7 +17,7 @@ build_src_filter = ${portduino_base.build_src_filter} | |||
| ; The Raspberry Pi actually has accessible SPI and GPIO, so we can support real hardware there. | ||||
| [env:raspbian] | ||||
| extends = portduino_base | ||||
| build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -lpigpio -lyaml-cpp | ||||
| build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -lyaml-cpp | ||||
| board = linux_arm | ||||
| lib_deps = ${portduino_base.lib_deps} | ||||
|   https://github.com/jp-bennett/LovyanGFX.git#jp-bennett-patch-1 ; lovyan03/LovyanGFX@^1.1.9 | ||||
|  |  | |||
|  | @ -1,33 +1,3 @@ | |||
| #if defined(ARCH_RASPBERRY_PI) | ||||
| #define HAS_WIRE 1 | ||||
| #define HAS_SCREEN 1 | ||||
| #define CANNED_MESSAGE_MODULE_ENABLE 1 | ||||
| 
 | ||||
| #else // Pine64 mode.
 | ||||
| 
 | ||||
| // Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
 | ||||
| // not found then probe for SX1262.  Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
 | ||||
| // #define USE_RF95
 | ||||
| #define USE_SX1262 | ||||
| 
 | ||||
| // Fake SPI device selections
 | ||||
| #define LORA_SCK 5 | ||||
| #define LORA_MISO 19 | ||||
| #define LORA_MOSI 27 | ||||
| #define LORA_CS RADIOLIB_NC // the ch341f spi controller does CS for us
 | ||||
| 
 | ||||
| #define LORA_DIO0 26 // a No connect on the SX1262 module
 | ||||
| #define LORA_RESET 14 | ||||
| #define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
 | ||||
| #define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
 | ||||
| #define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
 | ||||
| 
 | ||||
| #ifdef USE_SX1262 | ||||
| #define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
 | ||||
| #define SX126X_DIO1 LORA_DIO1 | ||||
| #define SX126X_BUSY LORA_DIO2 | ||||
| #define SX126X_RESET LORA_RESET | ||||
| #define SX126X_DIO2_AS_RF_SWITCH | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| #define CANNED_MESSAGE_MODULE_ENABLE 1 | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Jonathan Bennett
						Jonathan Bennett