mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-10-05 20:57:37 +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,72 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_MUZI_BASE -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x4405"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x0029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x002A"
|
||||
]
|
||||
],
|
||||
"usb_product": "muzi_base",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "MUZI_BASE",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": [
|
||||
"jlink"
|
||||
],
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "Muzi Base",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
]
|
||||
},
|
||||
"url": "https://github.com/muzi-works",
|
||||
"vendor": "MuziWorks"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <RadioLib.h>
|
||||
#include "MeshCore.h"
|
||||
|
||||
class CustomLR1121 : public LR1121 {
|
||||
bool _rx_boosted = false;
|
||||
|
||||
public:
|
||||
CustomLR1121(Module *mod) : LR1121(mod) { }
|
||||
|
||||
size_t getPacketLength(bool update) override {
|
||||
size_t len = LR1121::getPacketLength(update);
|
||||
if (len == 0 && getIrqStatus() & RADIOLIB_LR11X0_IRQ_HEADER_ERR) {
|
||||
// we've just received a corrupted packet
|
||||
// this may have triggered a bug causing subsequent packets to be shifted
|
||||
// call standby() to return radio to known-good state
|
||||
// recvRaw will call startReceive() to restart rx
|
||||
MESH_DEBUG_PRINTLN("LR1121: got header err, calling standby()");
|
||||
standby();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
float getFreqMHz() const { return freqMHz; }
|
||||
|
||||
int16_t setRxBoostedGainMode(bool en) {
|
||||
_rx_boosted = en;
|
||||
return LR1121::setRxBoostedGainMode(en);
|
||||
}
|
||||
|
||||
bool getRxBoostedGainMode() const { return _rx_boosted; }
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqStatus();
|
||||
bool detected = ((irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED));
|
||||
return detected;
|
||||
}
|
||||
uint8_t getSpreadingFactor() const { return spreadingFactor; }
|
||||
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "CustomLR1121.h"
|
||||
#include "RadioLibWrappers.h"
|
||||
#include "LR11x0Reset.h"
|
||||
|
||||
class CustomLR1121Wrapper : public RadioLibWrapper {
|
||||
public:
|
||||
CustomLR1121Wrapper(CustomLR1121& radio, mesh::MainBoard& board) : RadioLibWrapper(radio, board) { }
|
||||
|
||||
void setParams(float freq, float bw, uint8_t sf, uint8_t cr) override {
|
||||
((CustomLR1121 *)_radio)->setFrequency(freq);
|
||||
((CustomLR1121 *)_radio)->setSpreadingFactor(sf);
|
||||
((CustomLR1121 *)_radio)->setBandwidth(bw);
|
||||
((CustomLR1121 *)_radio)->setCodingRate(cr);
|
||||
updatePreamble(sf);
|
||||
}
|
||||
|
||||
void doResetAGC() override { lr11x0ResetAGC((LR11x0 *)_radio, ((CustomLR1121 *)_radio)->getFreqMHz(), getRxBoostedGainMode()); }
|
||||
bool isReceivingPacket() override {
|
||||
return ((CustomLR1121 *)_radio)->isReceiving();
|
||||
}
|
||||
float getCurrentRSSI() override {
|
||||
float rssi = -110;
|
||||
((CustomLR1121 *)_radio)->getRssiInst(&rssi);
|
||||
return rssi;
|
||||
}
|
||||
|
||||
void onSendFinished() override {
|
||||
RadioLibWrapper::onSendFinished();
|
||||
_radio->setPreambleLength(preambleLengthForSF(getSpreadingFactor())); // overcomes weird issues with small and big pkts
|
||||
}
|
||||
|
||||
uint32_t getEstAirtimeFor(int len_bytes) override {
|
||||
auto airtime = RadioLibWrapper::getEstAirtimeFor(len_bytes);
|
||||
return airtime < 200 ? 200 : airtime; // at least 200 millis
|
||||
}
|
||||
|
||||
float getLastRSSI() const override { return ((CustomLR1121 *)_radio)->getRSSI(); }
|
||||
float getLastSNR() const override { return ((CustomLR1121 *)_radio)->getSNR(); }
|
||||
|
||||
uint8_t getSpreadingFactor() const override { return ((CustomLR1121 *)_radio)->getSpreadingFactor(); }
|
||||
|
||||
bool setRxBoostedGainMode(bool en) override {
|
||||
return ((CustomLR1121 *)_radio)->setRxBoostedGainMode(en) == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
bool getRxBoostedGainMode() const override {
|
||||
return ((CustomLR1121 *)_radio)->getRxBoostedGainMode();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "SH1107Display.h"
|
||||
#include <Adafruit_GrayOLED.h>
|
||||
#include "Adafruit_SH110X.h"
|
||||
|
||||
#ifndef DISPLAY_ROTATION
|
||||
#define DISPLAY_ROTATION 0
|
||||
#endif
|
||||
|
||||
ColorVal UIColor::window_bkg = SH110X_BLACK;
|
||||
ColorVal UIColor::title_bkg = SH110X_BLACK;
|
||||
ColorVal UIColor::title_txt = SH110X_WHITE;
|
||||
ColorVal UIColor::primary_txt = SH110X_WHITE;
|
||||
ColorVal UIColor::secondary_txt = SH110X_WHITE;
|
||||
ColorVal UIColor::warning_txt = SH110X_WHITE;
|
||||
ColorVal UIColor::popup_bkg = SH110X_BLACK;
|
||||
ColorVal UIColor::popup_txt = SH110X_WHITE;
|
||||
ColorVal UIColor::corp_blue = SH110X_WHITE;
|
||||
|
||||
bool SH1107Display::i2c_probe(TwoWire &wire, uint8_t addr)
|
||||
{
|
||||
wire.beginTransmission(addr);
|
||||
uint8_t error = wire.endTransmission();
|
||||
return (error == 0);
|
||||
}
|
||||
|
||||
bool SH1107Display::begin()
|
||||
{
|
||||
bool result = display.begin(DISPLAY_ADDRESS, true) && i2c_probe(Wire, DISPLAY_ADDRESS);
|
||||
if (result) {
|
||||
display.setRotation(DISPLAY_ROTATION);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SH1107Display::turnOn()
|
||||
{
|
||||
display.oled_command(SH110X_DISPLAYON);
|
||||
uint8_t cmd[] = {0xD5, 0xF0};
|
||||
display.oled_commandList(cmd, 2);
|
||||
_isOn = true;
|
||||
}
|
||||
|
||||
void SH1107Display::turnOff()
|
||||
{
|
||||
display.oled_command(SH110X_DISPLAYOFF);
|
||||
_isOn = false;
|
||||
}
|
||||
|
||||
void SH1107Display::clear()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void SH1107Display::startFrame(ColorVal bkg)
|
||||
{
|
||||
display.clearDisplay(); // TODO: apply 'bkg'
|
||||
display.setContrast(120); // 0-127. default setting was causing some flickering.
|
||||
// display.SH110X_SETPRECHARGE(255);
|
||||
_color = SH110X_WHITE;
|
||||
display.setTextColor(_color);
|
||||
display.setTextSize(1);
|
||||
display.cp437(true); // Use full 256 char 'Code Page 437' font
|
||||
}
|
||||
|
||||
void SH1107Display::setTextSize(int sz)
|
||||
{
|
||||
display.setTextSize(sz);
|
||||
}
|
||||
|
||||
void SH1107Display::setColor(ColorVal c)
|
||||
{
|
||||
_color = (c != 0) ? SH110X_WHITE : SH110X_BLACK;
|
||||
display.setTextColor(_color);
|
||||
}
|
||||
|
||||
void SH1107Display::setCursor(int x, int y)
|
||||
{
|
||||
display.setCursor(x, y);
|
||||
}
|
||||
|
||||
void SH1107Display::print(const char *str)
|
||||
{
|
||||
display.print(str);
|
||||
}
|
||||
|
||||
void SH1107Display::fillRect(int x, int y, int w, int h)
|
||||
{
|
||||
display.fillRect(x, y, w, h, _color);
|
||||
}
|
||||
|
||||
void SH1107Display::drawRect(int x, int y, int w, int h)
|
||||
{
|
||||
display.drawRect(x, y, w, h, _color);
|
||||
}
|
||||
|
||||
void SH1107Display::drawXbm(int x, int y, const uint8_t *bits, int w, int h)
|
||||
{
|
||||
display.drawBitmap(x, y, bits, w, h, SH110X_WHITE);
|
||||
}
|
||||
|
||||
uint16_t SH1107Display::getTextWidth(const char *str)
|
||||
{
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
display.getTextBounds(str, 0, 0, &x1, &y1, &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
void SH1107Display::endFrame()
|
||||
{
|
||||
display.display();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "DisplayDriver.h"
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#define SH110X_NO_SPLASH
|
||||
#include <Adafruit_SH110X.h>
|
||||
|
||||
#ifndef PIN_OLED_RESET
|
||||
#define PIN_OLED_RESET -1
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_ADDRESS
|
||||
#define DISPLAY_ADDRESS 0x3c
|
||||
#endif
|
||||
|
||||
class SH1107Display : public DisplayDriver
|
||||
{
|
||||
Adafruit_SH1107 display;
|
||||
bool _isOn;
|
||||
uint8_t _color;
|
||||
|
||||
bool i2c_probe(TwoWire &wire, uint8_t addr);
|
||||
|
||||
public:
|
||||
SH1107Display() : DisplayDriver(128, 128), display(128, 128, &Wire, PIN_OLED_RESET) { _isOn = false; }
|
||||
bool begin();
|
||||
|
||||
bool isOn() override { return _isOn; }
|
||||
void turnOn() override;
|
||||
void turnOff() override;
|
||||
void clear() override;
|
||||
void startFrame(ColorVal bkg = UIColor::window_bkg) override;
|
||||
void setTextSize(int sz) override;
|
||||
void setColor(ColorVal c) override;
|
||||
void setCursor(int x, int y) override;
|
||||
void print(const char *str) override;
|
||||
void fillRect(int x, int y, int w, int h) override;
|
||||
void drawRect(int x, int y, int w, int h) override;
|
||||
void drawXbm(int x, int y, const uint8_t *bits, int w, int h) override;
|
||||
uint16_t getTextWidth(const char *str) override;
|
||||
void endFrame() override;
|
||||
};
|
||||
@@ -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