mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 10:51:57 +00:00
Merge pull request #3108 from tjdownes/muzi-base
Add Muzi Base board support (Duo + Uno + SuperIO)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include "MuziBaseBoard.h"
|
||||
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
const PowerMgtConfig power_config = {
|
||||
.lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
|
||||
.lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
|
||||
.voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
|
||||
};
|
||||
|
||||
void MuziBaseBoard::initiateShutdown(uint8_t reason) {
|
||||
// Disable LoRa module power before shutdown
|
||||
if (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
|
||||
reason == SHUTDOWN_REASON_BOOT_PROTECT) {
|
||||
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
|
||||
}
|
||||
|
||||
enterSystemOff(reason);
|
||||
}
|
||||
#endif // NRF52_POWER_MANAGEMENT
|
||||
|
||||
void MuziBaseBoard::begin() {
|
||||
NRF52BoardDCDC::begin();
|
||||
pinMode(PIN_VBAT_READ, INPUT);
|
||||
pinMode(PIN_BATTERY_CHARGING, INPUT);
|
||||
pinMode(PIN_CHARGER_FAULT, INPUT);
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
// output latches default to HIGH, so pull these low right after enabling
|
||||
pinMode(BUZZER_PIN, OUTPUT);
|
||||
digitalWrite(BUZZER_PIN, LOW);
|
||||
// gps power is driven by the sensor manager (mode switch). off to start.
|
||||
pinMode(PIN_GPS_EN, OUTPUT);
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
// 12V rail is only needed for the superIO display
|
||||
pinMode(SCREEN_12V_ENABLE, OUTPUT);
|
||||
#ifdef MUZI_BASE_SUPERIO
|
||||
digitalWrite(SCREEN_12V_ENABLE, HIGH); // Enable 12V power for SH1107 display
|
||||
delay(250);
|
||||
#else
|
||||
digitalWrite(SCREEN_12V_ENABLE, LOW);
|
||||
#endif
|
||||
Wire.begin();
|
||||
// delay(1000); // wait for display to initialize. otherwise it doesn't come up on boot.
|
||||
|
||||
#ifdef PIN_USER_BTN
|
||||
pinMode(PIN_USER_BTN, INPUT_PULLUP);
|
||||
#endif
|
||||
pinMode(PIN_BUTTON1, INPUT_PULLUP);
|
||||
pinMode(PIN_BUTTON2, INPUT_PULLUP);
|
||||
pinMode(PIN_BUTTON3, INPUT_PULLUP);
|
||||
pinMode(PIN_BUTTON4, INPUT_PULLUP);
|
||||
pinMode(PIN_BUTTON5, INPUT_PULLUP);
|
||||
pinMode(PIN_BUTTON6, INPUT_PULLUP);
|
||||
|
||||
// #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
// Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
|
||||
// #endif
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
checkBootVoltage(&power_config);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <MeshCore.h>
|
||||
#include <Arduino.h>
|
||||
#include <helpers/NRF52Board.h>
|
||||
|
||||
// The Muzi Base PCB ships in two radio flavors. Keep the user-facing identity
|
||||
// (OTA/DFU name and reported manufacturer) distinct per radio even though the
|
||||
// board logic is shared.
|
||||
#if defined(USE_SX1262)
|
||||
#define MUZI_BASE_OTA_NAME "MUZI_BASE_UNO_OTA"
|
||||
#define MUZI_BASE_MFR_NAME "Muzi Base Uno"
|
||||
#else
|
||||
#define MUZI_BASE_OTA_NAME "MUZI_BASE_DUO_OTA"
|
||||
#define MUZI_BASE_MFR_NAME "Muzi Base Duo"
|
||||
#endif
|
||||
|
||||
class MuziBaseBoard : public NRF52BoardDCDC {
|
||||
protected:
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
void initiateShutdown(uint8_t reason) override;
|
||||
#endif
|
||||
|
||||
public:
|
||||
MuziBaseBoard() : NRF52Board(MUZI_BASE_OTA_NAME) {}
|
||||
void begin();
|
||||
|
||||
#define BATTERY_SAMPLES 8
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(12);
|
||||
analogReference(AR_INTERNAL_3_0);
|
||||
delay(1);
|
||||
|
||||
uint32_t raw = 0;
|
||||
for (int i = 0; i < BATTERY_SAMPLES; i++) {
|
||||
raw += analogRead(PIN_VBAT_READ);
|
||||
}
|
||||
raw = raw / BATTERY_SAMPLES;
|
||||
|
||||
// ADC_MULTIPLIER is the voltage divider ratio
|
||||
return (raw * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096;
|
||||
}
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
return MUZI_BASE_MFR_NAME;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,322 @@
|
||||
; ============================================================================
|
||||
; Muzi Base (MuziWorks)
|
||||
;
|
||||
; One nRF52840 board, shipped in two radio flavors. The radio is selected per
|
||||
; environment; all board logic lives in variants/muzi_base and is shared:
|
||||
; muzi_base_duo_* -> LR1121 (USE_LR1121)
|
||||
; muzi_base_uno_* -> SX1262 (USE_SX1262)
|
||||
; ============================================================================
|
||||
|
||||
[muzi_base_common]
|
||||
extends = nrf52_base
|
||||
board = muzi_base
|
||||
board_build.ldscript = boards/nrf52840_s140_v6.ld
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
-I src/helpers/nrf52
|
||||
-I lib/nrf52/s140_nrf52_6.1.1_API/include
|
||||
-I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
|
||||
-I variants/muzi_base
|
||||
-I src/helpers/ui
|
||||
-D MUZI_BASE
|
||||
-D NRF52_POWER_MANAGEMENT
|
||||
-D PIN_USER_BTN=PIN_BUTTON1
|
||||
-D USER_BTN_PRESSED=LOW
|
||||
-D PIN_STATUS_LED=35
|
||||
-D LORA_TX_POWER=22
|
||||
-D P_LORA_BUSY=LORA_BUSY
|
||||
-D P_LORA_SCLK=LORA_SCLK
|
||||
-D P_LORA_NSS=LORA_NSS
|
||||
-D P_LORA_DIO_1=LORA_DIO_1
|
||||
-D P_LORA_MISO=LORA_MISO
|
||||
-D P_LORA_MOSI=LORA_MOSI
|
||||
-D P_LORA_RESET=LORA_RESET
|
||||
-D QSPIFLASH=1
|
||||
build_src_filter = ${nrf52_base.build_src_filter}
|
||||
+<helpers/*.cpp>
|
||||
+<helpers/sensors>
|
||||
+<../variants/muzi_base>
|
||||
debug_tool = jlink
|
||||
upload_protocol = nrfutil
|
||||
lib_deps =
|
||||
${nrf52_base.lib_deps}
|
||||
${sensor_base.lib_deps}
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Radio selection (Duo = LR1121, Uno = SX1262). The matching radio pins / TCXO
|
||||
; / RF-switch defines are picked up in variant.h via USE_LR1121 / USE_SX1262.
|
||||
; ---------------------------------------------------------------------------
|
||||
[muzi_base_duo]
|
||||
extends = muzi_base_common
|
||||
build_flags = ${muzi_base_common.build_flags}
|
||||
-D USE_LR1121
|
||||
-D RADIO_CLASS=CustomLR1121
|
||||
-D WRAPPER_CLASS=CustomLR1121Wrapper
|
||||
-D RF_SWITCH_TABLE
|
||||
-D RX_BOOSTED_GAIN=true
|
||||
-D LR11X0_DIO_AS_RF_SWITCH=true
|
||||
-D LR11X0_DIO3_TCXO_VOLTAGE=3.0
|
||||
|
||||
[muzi_base_uno]
|
||||
extends = muzi_base_common
|
||||
build_flags = ${muzi_base_common.build_flags}
|
||||
-D USE_SX1262
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
-D SX126X_DIO2_AS_RF_SWITCH=1
|
||||
-D SX126X_DIO3_TCXO_VOLTAGE=3.3
|
||||
|
||||
; ===========================================================================
|
||||
; Duo (LR1121) environments
|
||||
; ===========================================================================
|
||||
[env:muzi_base_duo_repeater]
|
||||
extends = muzi_base_duo
|
||||
build_flags = ${muzi_base_duo.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ADVERT_NAME='"Muzi Base Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${muzi_base_duo.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps = ${muzi_base_duo.lib_deps}
|
||||
|
||||
[env:muzi_base_duo_room_server]
|
||||
extends = muzi_base_duo
|
||||
build_flags = ${muzi_base_duo.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ADVERT_NAME='"Muzi Base Room"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${muzi_base_duo.build_src_filter}
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps = ${muzi_base_duo.lib_deps}
|
||||
|
||||
[env:muzi_base_duo_companion_radio_usb]
|
||||
extends = muzi_base_duo
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_duo.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
build_src_filter = ${muzi_base_duo.build_src_filter}
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps = ${muzi_base_duo.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:muzi_base_duo_companion_radio_ble]
|
||||
extends = muzi_base_duo
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_duo.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D QSPIFLASH=1
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
; -D ADVERT_NAME='"@@MAC"'
|
||||
build_src_filter = ${muzi_base_duo.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/sensors>
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps = ${muzi_base_duo.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[muzi_base_duo_superIO]
|
||||
extends = muzi_base_duo
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_duo.build_flags}
|
||||
-D MUZI_BASE_SUPERIO
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=SH1107Display
|
||||
-D DISPLAY_ROTATION=2
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
-D ENV_SKIP_GPS_DETECT
|
||||
-D PIN_BUZZER=22
|
||||
build_src_filter = ${muzi_base_duo.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/sensors>
|
||||
+<helpers/ui/SH1107Display.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
lib_deps = ${muzi_base_duo.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
stevemarple/MicroNMEA @ ^2.0.6
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
adafruit/Adafruit SH110X@^2.1.14
|
||||
artronshop/ArtronShop_RX8130CE@1.0.0
|
||||
adafruit/Adafruit GFX Library @ ^1.12.1
|
||||
debug_tool = jlink
|
||||
upload_protocol = nrfutil
|
||||
|
||||
[env:muzi_base_duo_superIO_companion_radio_ble]
|
||||
extends = muzi_base_duo_superIO
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_duo_superIO.build_flags}
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-I examples/companion_radio/ui-new
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D QSPIFLASH=1
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
build_src_filter = ${muzi_base_duo_superIO.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${muzi_base_duo_superIO.lib_deps}
|
||||
|
||||
; ===========================================================================
|
||||
; Uno (SX1262) environments
|
||||
; ===========================================================================
|
||||
[env:muzi_base_uno_repeater]
|
||||
extends = muzi_base_uno
|
||||
build_flags = ${muzi_base_uno.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ADVERT_NAME='"Muzi Base Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${muzi_base_uno.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
lib_deps = ${muzi_base_uno.lib_deps}
|
||||
|
||||
[env:muzi_base_uno_room_server]
|
||||
extends = muzi_base_uno
|
||||
build_flags = ${muzi_base_uno.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D ADVERT_NAME='"Muzi Base Room"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D ROOM_PASSWORD='"hello"'
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${muzi_base_uno.build_src_filter}
|
||||
+<../examples/simple_room_server>
|
||||
lib_deps = ${muzi_base_uno.lib_deps}
|
||||
|
||||
[env:muzi_base_uno_companion_radio_usb]
|
||||
extends = muzi_base_uno
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_uno.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
build_src_filter = ${muzi_base_uno.build_src_filter}
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps = ${muzi_base_uno.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:muzi_base_uno_companion_radio_ble]
|
||||
extends = muzi_base_uno
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_uno.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D QSPIFLASH=1
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=NullDisplayDriver
|
||||
; -D ADVERT_NAME='"@@MAC"'
|
||||
build_src_filter = ${muzi_base_uno.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/sensors>
|
||||
+<helpers/ui/NullDisplayDriver.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps = ${muzi_base_uno.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[muzi_base_uno_superIO]
|
||||
extends = muzi_base_uno
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_uno.build_flags}
|
||||
-D MUZI_BASE_SUPERIO
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=SH1107Display
|
||||
-D DISPLAY_ROTATION=2
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
-D ENV_SKIP_GPS_DETECT
|
||||
-D PIN_BUZZER=22
|
||||
build_src_filter = ${muzi_base_uno.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/sensors>
|
||||
+<helpers/ui/SH1107Display.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
lib_deps = ${muzi_base_uno.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
stevemarple/MicroNMEA @ ^2.0.6
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
adafruit/Adafruit SH110X@^2.1.14
|
||||
artronshop/ArtronShop_RX8130CE@1.0.0
|
||||
adafruit/Adafruit GFX Library @ ^1.12.1
|
||||
debug_tool = jlink
|
||||
upload_protocol = nrfutil
|
||||
|
||||
[env:muzi_base_uno_superIO_companion_radio_ble]
|
||||
extends = muzi_base_uno_superIO
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 708608
|
||||
build_flags = ${muzi_base_uno_superIO.build_flags}
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-I examples/companion_radio/ui-new
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D QSPIFLASH=1
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
build_src_filter = ${muzi_base_uno_superIO.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${muzi_base_uno_superIO.lib_deps}
|
||||
@@ -0,0 +1,162 @@
|
||||
#include <Arduino.h>
|
||||
#include <nrf_gpio.h>
|
||||
#include "target.h"
|
||||
#include "variant.h"
|
||||
|
||||
MuziBaseBoard board;
|
||||
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
|
||||
|
||||
WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
VolatileRTCClock fallback_clock;
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
#if ENV_INCLUDE_GPS
|
||||
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
||||
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
|
||||
MuziBaseSensorManager sensors = MuziBaseSensorManager(nmea);
|
||||
#else
|
||||
MuziBaseSensorManager sensors;
|
||||
#endif
|
||||
|
||||
// user button for the N-click power-off. single-click mode (multiclick off) so
|
||||
// each press is its own CLICK; we count them ourselves. reliable across the
|
||||
// idle-sleep loop because it's the same MomentaryButton the UI navigates with.
|
||||
static MomentaryButton pwr_btn(PIN_USER_BTN, 0, true, true, false);
|
||||
|
||||
// power off, arming the user button as a wake source first so a later press
|
||||
// turns it back on. wait for the button to release (the 5th click already fires
|
||||
// on release, so this returns quickly), then set nRF52 GPIO SENSE (press = LOW);
|
||||
// it survives into SYSTEMOFF because shutdownPeripherals() doesn't touch this pin.
|
||||
static void muziPowerOff() {
|
||||
uint32_t t0 = millis();
|
||||
while (digitalRead(PIN_USER_BTN) == USER_BTN_PRESSED && (millis() - t0) < 3000) { delay(5); }
|
||||
delay(50); // settle
|
||||
nrf_gpio_cfg_sense_input(g_ADigitalPinMap[PIN_USER_BTN], NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
|
||||
board.powerOff(); // shutdownPeripherals() + SYSTEMOFF
|
||||
}
|
||||
|
||||
bool MuziBaseSensorManager::begin() {
|
||||
pwr_btn.begin();
|
||||
bool ok = EnvironmentSensorManager::begin();
|
||||
#if ENV_INCLUDE_GPS
|
||||
pinMode(PIN_GPS_SWITCH, INPUT);
|
||||
_last_gps_sw = digitalRead(PIN_GPS_SWITCH); // initial gps state from the switch
|
||||
if (_last_gps_sw == HIGH) start_gps(); else stop_gps();
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
void MuziBaseSensorManager::loop() {
|
||||
// user button: USER_BTN_POWER_OFF_CLICKS quick clicks -> power off
|
||||
if (pwr_btn.check() == BUTTON_EVENT_CLICK) {
|
||||
unsigned long t = millis();
|
||||
if (t - _pwr_last_click > 2000) _pwr_clicks = 0; // restart if too slow
|
||||
_pwr_last_click = t;
|
||||
if (++_pwr_clicks >= USER_BTN_POWER_OFF_CLICKS) muziPowerOff();
|
||||
}
|
||||
#if ENV_INCLUDE_GPS
|
||||
unsigned long now = millis();
|
||||
if (now > _next_sw_check) { // check the mode switch ~once a sec
|
||||
_next_sw_check = now + 1000;
|
||||
int sw = digitalRead(PIN_GPS_SWITCH);
|
||||
if (sw != _last_gps_sw) {
|
||||
_last_gps_sw = sw;
|
||||
if (sw == HIGH) start_gps(); else stop_gps();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EnvironmentSensorManager::loop();
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
DISPLAY_CLASS display;
|
||||
MomentaryButton user_btn(PIN_USER_BTN, 1000, true, false, false);
|
||||
MomentaryButton joystick_left(JOYSTICK_LEFT, 1000, true, false, false);
|
||||
MomentaryButton joystick_right(JOYSTICK_RIGHT, 1000, true, false, false);
|
||||
MomentaryButton back_btn(PIN_BACK_BTN, 1000, true, false, true);
|
||||
#endif
|
||||
|
||||
#if defined(USE_LR1121)
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
#ifdef RF_SWITCH_TABLE
|
||||
static const uint32_t rfswitch_dios[Module::RFSWITCH_MAX_PINS] = {
|
||||
RADIOLIB_LR11X0_DIO5,
|
||||
RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, {LOW, LOW}},
|
||||
{ LR11x0::MODE_RX, {HIGH, LOW}},
|
||||
{ LR11x0::MODE_TX, {LOW, HIGH}},
|
||||
{ LR11x0::MODE_TX_HP, {LOW, HIGH}},
|
||||
{ LR11x0::MODE_TX_HF, {LOW, LOW}},
|
||||
{ LR11x0::MODE_GNSS, {LOW, LOW}},
|
||||
{ LR11x0::MODE_WIFI, {LOW, LOW}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
#endif
|
||||
#endif // USE_LR1121
|
||||
|
||||
bool radio_init() {
|
||||
//rtc_clock.begin(Wire);
|
||||
|
||||
#if defined(USE_LR1121)
|
||||
#ifdef LR11X0_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = LR11X0_DIO3_TCXO_VOLTAGE;
|
||||
#else
|
||||
float tcxo = 1.6f;
|
||||
#endif
|
||||
|
||||
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
|
||||
SPI.begin();
|
||||
int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo);
|
||||
if (status != RADIOLIB_ERR_NONE) {
|
||||
Serial.print("ERROR: radio init failed: ");
|
||||
Serial.println(status);
|
||||
return false; // fail
|
||||
}
|
||||
|
||||
radio.setCRC(2);
|
||||
radio.explicitHeader();
|
||||
|
||||
#ifdef RF_SWITCH_TABLE
|
||||
radio.setRfSwitchTable(rfswitch_dios, rfswitch_table);
|
||||
#endif
|
||||
#ifdef RX_BOOSTED_GAIN
|
||||
radio.setRxBoostedGainMode(RX_BOOSTED_GAIN);
|
||||
#endif
|
||||
|
||||
return true; // success
|
||||
#else // USE_SX1262
|
||||
// CustomSX1262::std_init() configures the SPI pins, runs begin() with the
|
||||
// TCXO-voltage fallback, sets CRC, current limit, the DIO2 RF switch, and
|
||||
// RX boosted gain from the SX126X_* build flags.
|
||||
return radio.std_init(&SPI);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t radio_get_rng_seed() {
|
||||
return radio.random(0x7FFFFFFF);
|
||||
}
|
||||
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
|
||||
radio.setFrequency(freq);
|
||||
radio.setSpreadingFactor(sf);
|
||||
radio.setBandwidth(bw);
|
||||
radio.setCodingRate(cr);
|
||||
}
|
||||
|
||||
void radio_set_tx_power(int8_t dbm) {
|
||||
radio.setOutputPower(dbm);
|
||||
}
|
||||
|
||||
mesh::LocalIdentity radio_new_identity() {
|
||||
RadioNoiseListener rng(radio);
|
||||
return mesh::LocalIdentity(&rng); // create new random identity
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#define RADIOLIB_STATIC_ONLY 1
|
||||
#include <RadioLib.h>
|
||||
#include <helpers/radiolib/RadioLibWrappers.h>
|
||||
#include "MuziBaseBoard.h"
|
||||
#if defined(USE_LR1121)
|
||||
#include <helpers/radiolib/CustomLR1121Wrapper.h>
|
||||
#elif defined(USE_SX1262)
|
||||
#include <helpers/radiolib/CustomSX1262Wrapper.h>
|
||||
#else
|
||||
#error "muzi_base: no radio selected (define USE_LR1121 or USE_SX1262)"
|
||||
#endif
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/SensorManager.h>
|
||||
#include <helpers/sensors/LocationProvider.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/sensors/EnvironmentSensorManager.h> // Added: Include for EnvironmentSensorManager
|
||||
#include <helpers/ui/MomentaryButton.h>
|
||||
|
||||
|
||||
#ifdef MUZI_BASE_SUPERIO
|
||||
#include <helpers/ui/SH1107Display.h>
|
||||
extern DISPLAY_CLASS display;
|
||||
extern MomentaryButton user_btn;
|
||||
extern MomentaryButton joystick_left;
|
||||
extern MomentaryButton joystick_right;
|
||||
extern MomentaryButton back_btn;
|
||||
#elif defined(DISPLAY_CLASS)
|
||||
#include "helpers/ui/NullDisplayDriver.h"
|
||||
extern DISPLAY_CLASS display;
|
||||
extern MomentaryButton user_btn;
|
||||
#endif
|
||||
|
||||
extern MuziBaseBoard board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
|
||||
// muzi sensor manager, polled from main loop via sensors.loop():
|
||||
// - user button: USER_BTN_POWER_OFF_CLICKS quick presses -> power off (all builds)
|
||||
// - gps mode switch on/off (superIO only, see thinknode_m1)
|
||||
class MuziBaseSensorManager : public EnvironmentSensorManager {
|
||||
unsigned long _pwr_last_click = 0;
|
||||
uint8_t _pwr_clicks = 0;
|
||||
#if ENV_INCLUDE_GPS
|
||||
int _last_gps_sw = -1;
|
||||
unsigned long _next_sw_check = 0;
|
||||
#endif
|
||||
public:
|
||||
#if ENV_INCLUDE_GPS
|
||||
MuziBaseSensorManager(LocationProvider& location) : EnvironmentSensorManager(location) {}
|
||||
#else
|
||||
MuziBaseSensorManager() {}
|
||||
#endif
|
||||
bool begin() override;
|
||||
void loop() override;
|
||||
};
|
||||
extern MuziBaseSensorManager sensors;
|
||||
|
||||
bool radio_init();
|
||||
uint32_t radio_get_rng_seed();
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
|
||||
void radio_set_tx_power(int8_t dbm);
|
||||
mesh::LocalIdentity radio_new_identity();
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* variant.cpp
|
||||
* Copyright (C) 2023 Seeed K.K.
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[PINS_COUNT + 1] =
|
||||
{
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
// P1 pins.
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* variant.h
|
||||
* Copyright (C) 2023 Seeed K.K.
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Low frequency clock source
|
||||
|
||||
#define USE_LFXO // 32.768 kHz crystal oscillator
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
// #define USE_LFRC // 32.768 kHz RC oscillator
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Power
|
||||
|
||||
#define PIN_VBAT_READ (31) // P0.31
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.537
|
||||
#define ADC_RESOLUTION 14
|
||||
#define PIN_BATTERY_CHARGING (32+2) // P1.02 STAT2
|
||||
#define PIN_CHARGER_FAULT (27) // P0.27 STAT1 this pin is disabled on meshtastic.
|
||||
// BQ25185 has 2 status pins: STAT1 and STAT2. Both are high when not charging. STAT1 high, STAT2 low: charging. Recoverable fault: STAT1 low, STAT2 high. Unrecoverable fault: both low.
|
||||
// We only need to detect charging vs not charging, but someone else can use the fault pin to log when the battery gets too hot or cold.
|
||||
|
||||
// Power management boot protection threshold (millivolts)
|
||||
#define PWRMGT_VOLTAGE_BOOTLOCK 3100 // Won't boot below this voltage (mV). BB15 battery min voltage is 3v, 3100mV is minimum batt in meshtastic code.
|
||||
|
||||
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
||||
#define PWRMGT_LPCOMP_AIN 7 // AIN7 = P0.31 = PIN_VBAT_READ
|
||||
#define PWRMGT_LPCOMP_REFSEL 4 // 5/8 VDD (~3.13-3.44V) was the default on RAK4631. should still apply here.
|
||||
|
||||
// Other pins
|
||||
#define PIN_AREF (-1)
|
||||
#define SCREEN_12V_ENABLE (23) // SH1107 OLED controller has a pin that needs to be enabled to turn on the screen.
|
||||
|
||||
static const uint8_t AREF = (PIN_AREF); // not used
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Number of pins
|
||||
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (6)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// UART pin definition
|
||||
|
||||
#define PIN_SERIAL1_RX (19) // P0.19 used for GPS RX
|
||||
#define PIN_SERIAL1_TX (20) // P0.20 used for GPS TX
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// I2C pin definition
|
||||
|
||||
#define HAS_WIRE (1)
|
||||
#define WIRE_INTERFACES_COUNT (2)
|
||||
|
||||
#define PIN_WIRE1_SDA (4) // P0.4
|
||||
#define PIN_WIRE1_SCL (6) // P0.6
|
||||
#define PIN_WIRE_SDA (24) // P0.24 OLED I2C
|
||||
#define PIN_WIRE_SCL (25) // P0.25 OLED I2C
|
||||
#define I2C_NO_RESCAN
|
||||
// #define I2C_NO_RESCAN
|
||||
// #define HAS_QMA6100P
|
||||
// #define QMA_6100P_INT_PIN (34) // P1.2
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SPI pin definition
|
||||
|
||||
#define SPI_INTERFACES_COUNT (1)
|
||||
|
||||
#define PIN_SPI_MISO (32+15) // internally connected to p1.15
|
||||
#define PIN_SPI_MOSI (32+14) // internally connected to p1.14
|
||||
#define PIN_SPI_SCK (32+13) // internally connected to p1.13
|
||||
#define PIN_SPI_NSS (32+12) // internally connected to p1.12
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Builtin LEDs
|
||||
|
||||
#define LED_BUILTIN (35)
|
||||
#define LED_BLUE (-1) // P1.04 turned off, because the blue LED was annoying.
|
||||
// #define LED_GREEN (35) // P1.03
|
||||
#define LED_PIN LED_BUILTIN
|
||||
|
||||
#define LED_STATE_ON LOW
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Builtin buttons
|
||||
#define PIN_BUTTON1 (10) // P0.10 Menu / User Button | on superIO, this is in the center of the "D-Pad", but it's also the button on the Uno/Duo.
|
||||
#define PIN_BUTTON2 (21) // Joystick Up
|
||||
#define PIN_BUTTON3 (17) // Joystick Down
|
||||
#define PIN_BUTTON4 (37) // Joystick Left
|
||||
#define PIN_BUTTON5 (16) // Joystick Right
|
||||
#define PIN_BUTTON6 (15) // Back / Cancel Button.
|
||||
#define JOYSTICK_PRESS PIN_BUTTON1
|
||||
#define JOYSTICK_UP PIN_BUTTON2
|
||||
#define JOYSTICK_DOWN PIN_BUTTON3
|
||||
#define JOYSTICK_LEFT PIN_BUTTON4
|
||||
#define JOYSTICK_RIGHT PIN_BUTTON5
|
||||
#define PIN_BACK_BTN PIN_BUTTON6
|
||||
|
||||
// quick user-button presses that power the device off (per Muzi's docs)
|
||||
#ifndef USER_BTN_POWER_OFF_CLICKS
|
||||
#define USER_BTN_POWER_OFF_CLICKS 5
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LoRa radio
|
||||
//
|
||||
// The Muzi Base PCB is populated with one of two radios:
|
||||
// * Base Uno -> SX1262 (USE_SX1262)
|
||||
// * Base Duo -> LR1121 (USE_LR1121)
|
||||
// Both share NSS/SCLK/MISO/MOSI/RESET/BUSY. The only pin difference is the
|
||||
// radio IRQ (DIO1): the SX1262 routes it to P1.06, the LR1121 to P1.08.
|
||||
// (see Meshtastic muzi_base variant, which defines both radios on this board)
|
||||
|
||||
#define LORA_NSS (PIN_SPI_NSS) // P1.12
|
||||
#define LORA_RESET (32+10) // P1.10
|
||||
#define LORA_BUSY (32+11) // P1.11
|
||||
#define LORA_SCLK (PIN_SPI_SCK) // P1.13
|
||||
#define LORA_MISO (PIN_SPI_MISO) // P1.15
|
||||
#define LORA_MOSI (PIN_SPI_MOSI) // P1.14
|
||||
|
||||
// only the IRQ pin differs per radio. rf-switch/tcxo defines are in platformio.ini
|
||||
#if defined(USE_LR1121)
|
||||
#define LORA_DIO_1 (32+8) // P1.08 LR1121 IRQ/DIO1
|
||||
#elif defined(USE_SX1262)
|
||||
#define LORA_DIO_1 (32+6) // P1.06 SX1262 IRQ/DIO1
|
||||
#else
|
||||
#error "muzi_base: no radio selected (define USE_LR1121 or USE_SX1262)"
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// QSPI Flash
|
||||
#define PIN_QSPI_SCK (0 + 3)
|
||||
#define PIN_QSPI_CS (0 + 26)
|
||||
#define PIN_QSPI_IO0 (0 + 30)
|
||||
#define PIN_QSPI_IO1 (0 + 29)
|
||||
#define PIN_QSPI_IO2 (0 + 28)
|
||||
#define PIN_QSPI_IO3 (0 + 2)
|
||||
|
||||
#define EXTERNAL_FLASH_DEVICES W25Q128JVPQ
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// GPS
|
||||
#define HAS_GPS 1
|
||||
#define PIN_GPS_RX PIN_SERIAL1_RX
|
||||
#define PIN_GPS_TX PIN_SERIAL1_TX
|
||||
#define PIN_GPS_EN (32+1) // P1.01 PWR_IO2 on schematic. gps power, driven by the sensor manager.
|
||||
|
||||
// superIO 3-position mode switch (pins from the meshtastic muzi_base variant).
|
||||
// "Mode 2" reads HIGH on PIN_GPS_SWITCH and turns the gps on.
|
||||
#define SWITCH_MODE1 (32+9) // P1.09
|
||||
#define SWITCH_MODE2 (12) // P0.12
|
||||
#define PIN_GPS_SWITCH SWITCH_MODE2
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Buzzer
|
||||
|
||||
#define BUZZER_PIN (22) // P0.22 same load switch design as GPS_EN.
|
||||
Reference in New Issue
Block a user