mirror of https://github.com/meshcore-dev/MeshCore
committed by
GitHub
12 changed files with 941 additions and 0 deletions
@ -0,0 +1,72 @@ |
|||||
|
{ |
||||
|
"build": { |
||||
|
"arduino": { |
||||
|
"ldscript": "nrf52840_s140_v6.ld" |
||||
|
}, |
||||
|
"core": "nRF5", |
||||
|
"cpu": "cortex-m4", |
||||
|
"extra_flags": "-DARDUINO_NRF52840_MUZI_BASE_DUO -DNRF52840_XXAA", |
||||
|
"f_cpu": "64000000L", |
||||
|
"hwids": [ |
||||
|
[ |
||||
|
"0x239A", |
||||
|
"0x4405" |
||||
|
], |
||||
|
[ |
||||
|
"0x239A", |
||||
|
"0x0029" |
||||
|
], |
||||
|
[ |
||||
|
"0x239A", |
||||
|
"0x002A" |
||||
|
] |
||||
|
], |
||||
|
"usb_product": "muzi_base_duo", |
||||
|
"mcu": "nrf52840", |
||||
|
"variant": "MUZI_BASE_DUO", |
||||
|
"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 Duo", |
||||
|
"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,45 @@ |
|||||
|
#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()); } |
||||
|
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
|
||||
|
} |
||||
|
|
||||
|
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(); } |
||||
|
|
||||
|
void setRxBoostedGainMode(bool en) override { |
||||
|
((CustomLR1121 *)_radio)->setRxBoostedGainMode(en); |
||||
|
} |
||||
|
bool getRxBoostedGainMode() const override { |
||||
|
return ((CustomLR1121 *)_radio)->getRxBoostedGainMode(); |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,103 @@ |
|||||
|
#include "SH1107Display.h" |
||||
|
#include <Adafruit_GrayOLED.h> |
||||
|
#include "Adafruit_SH110X.h" |
||||
|
|
||||
|
#ifndef DISPLAY_ROTATION |
||||
|
#define DISPLAY_ROTATION 0 |
||||
|
#endif |
||||
|
|
||||
|
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(Color 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(Color 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,46 @@ |
|||||
|
#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 |
||||
|
#ifndef PIN_OLED_12V_EN |
||||
|
#define PIN_OLED_12V_EN -1 |
||||
|
#endif |
||||
|
#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, PIN_OLED_12V_EN) { _isOn = false; } |
||||
|
bool begin(); |
||||
|
|
||||
|
bool isOn() override { return _isOn; } |
||||
|
void turnOn() override; |
||||
|
void turnOff() override; |
||||
|
void clear() override; |
||||
|
void startFrame(Color bkg = DARK) override; |
||||
|
void setTextSize(int sz) override; |
||||
|
void setColor(Color 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,50 @@ |
|||||
|
#include <Arduino.h> |
||||
|
#include <Wire.h> |
||||
|
|
||||
|
#include "muzi_base_duoBoard.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 muzi_base_duoBoard::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 muzi_base_duoBoard::begin() { |
||||
|
NRF52BoardDCDC::begin(); |
||||
|
pinMode(PIN_VBAT_READ, INPUT); |
||||
|
pinMode(SCREEN_12V_ENABLE, OUTPUT); |
||||
|
digitalWrite(SCREEN_12V_ENABLE, HIGH); // Enable 12V power for SH1107 display
|
||||
|
delay(250); |
||||
|
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 |
||||
|
// delay(10); // give LR1121 some time to power up
|
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <MeshCore.h> |
||||
|
#include <Arduino.h> |
||||
|
#include <helpers/NRF52Board.h> |
||||
|
|
||||
|
class muzi_base_duoBoard : public NRF52BoardDCDC { |
||||
|
protected: |
||||
|
#ifdef NRF52_POWER_MANAGEMENT |
||||
|
void initiateShutdown(uint8_t reason) override; |
||||
|
#endif |
||||
|
|
||||
|
public: |
||||
|
muzi_base_duoBoard() : NRF52Board("MUZI_BASE_DUO_OTA") {} |
||||
|
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 Duo"; |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,169 @@ |
|||||
|
[muzi_base_duo] |
||||
|
extends = nrf52_base |
||||
|
board = muzi_base_duo |
||||
|
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_duo |
||||
|
-I src/helpers/ui |
||||
|
-D muzi_base_duo |
||||
|
-D NRF52_POWER_MANAGEMENT |
||||
|
-D PIN_USER_BTN=PIN_BUTTON1 |
||||
|
-D USER_BTN_PRESSED=LOW |
||||
|
-D PIN_STATUS_LED=35 |
||||
|
-D RADIO_CLASS=CustomLR1121 |
||||
|
-D WRAPPER_CLASS=CustomLR1121Wrapper |
||||
|
-D LORA_TX_POWER=22 |
||||
|
-D RF_SWITCH_TABLE |
||||
|
-D RX_BOOSTED_GAIN=true |
||||
|
-D P_LORA_BUSY=LORA_BUSY ; P0.7 |
||||
|
-D P_LORA_SCLK=LORA_SCLK ; P0.11 |
||||
|
-D P_LORA_NSS=LORA_NSS ; P0.12 |
||||
|
-D P_LORA_DIO_1=LORA_DIO_1 ; P1.1 |
||||
|
-D P_LORA_MISO=LORA_MISO ; P1.8 |
||||
|
-D P_LORA_MOSI=LORA_MOSI ; P0.9 |
||||
|
-D P_LORA_RESET=LORA_RESET ; P1.10 |
||||
|
-D LR11X0_DIO_AS_RF_SWITCH=true |
||||
|
-D LR11X0_DIO3_TCXO_VOLTAGE=3.0 |
||||
|
-D QSPIFLASH=1 |
||||
|
; -D ENV_INCLUDE_GPS=0 |
||||
|
build_src_filter = ${nrf52_base.build_src_filter} |
||||
|
+<helpers/*.cpp> |
||||
|
+<helpers/sensors> |
||||
|
+<helpers/nrf52/muzi_base_duo.cpp> |
||||
|
+<../variants/muzi_base_duo> |
||||
|
debug_tool = jlink |
||||
|
upload_protocol = nrfutil |
||||
|
lib_deps = |
||||
|
${nrf52_base.lib_deps} |
||||
|
${sensor_base.lib_deps} |
||||
|
[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_duo 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_duo 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 |
||||
|
-D RF_SWITCH_TABLE |
||||
|
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=500 ;can increase number of contacts since we have a ton of extra flash. |
||||
|
-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} |
||||
|
+<../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=500 ;can increase number of contacts since we have a ton of extra flash. |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-D BLE_PIN_CODE=123456 |
||||
|
-D BLE_TX_POWER=0 |
||||
|
-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> |
||||
|
+<../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= 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_duo_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 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/[email protected] |
||||
|
adafruit/Adafruit GFX Library @ ^1.12.1 |
||||
|
debug_tool = jlink |
||||
|
upload_protocol = nrfutil |
||||
|
|
||||
|
|
||||
|
[env:muzi_base_duo_companion_radio_ble_superIO] |
||||
|
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=500 ; can increase number of contacts since we have a ton of extra flash. |
||||
|
-D MAX_GROUP_CHANNELS=40 |
||||
|
-I examples/companion_radio/ui-new |
||||
|
-D BLE_PIN_CODE=123456 |
||||
|
-D BLE_TX_POWER=0 |
||||
|
-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} |
||||
@ -0,0 +1,102 @@ |
|||||
|
#include <Arduino.h> |
||||
|
#include "target.h" |
||||
|
#include "variant.h" |
||||
|
|
||||
|
muzi_base_duoBoard 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); |
||||
|
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); |
||||
|
#else |
||||
|
EnvironmentSensorManager sensors; |
||||
|
#endif |
||||
|
|
||||
|
#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 |
||||
|
|
||||
|
#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 |
||||
|
|
||||
|
bool radio_init() { |
||||
|
//rtc_clock.begin(Wire);
|
||||
|
|
||||
|
#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
|
||||
|
} |
||||
|
|
||||
|
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,41 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#define RADIOLIB_STATIC_ONLY 1 |
||||
|
#include <RadioLib.h> |
||||
|
#include <helpers/radiolib/RadioLibWrappers.h> |
||||
|
#include "muzi_base_duoBoard.h" |
||||
|
#include <helpers/radiolib/CustomLR1121Wrapper.h> |
||||
|
#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_duo_superIO |
||||
|
#include <helpers/ui/SH1107Display.h> |
||||
|
extern DISPLAY_CLASS display; |
||||
|
extern MomentaryButton user_btn; |
||||
|
extern MomentaryButton joystick_left; |
||||
|
extern MomentaryButton joystick_right; |
||||
|
extern MomentaryButton joystick_up; |
||||
|
extern MomentaryButton joystick_down; |
||||
|
extern MomentaryButton back_btn; |
||||
|
#else |
||||
|
#include "helpers/ui/NullDisplayDriver.h" |
||||
|
extern DISPLAY_CLASS display; |
||||
|
extern MomentaryButton user_btn; |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
extern muzi_base_duoBoard board; |
||||
|
extern WRAPPER_CLASS radio_driver; |
||||
|
extern AutoDiscoverRTCClock rtc_clock; |
||||
|
extern EnvironmentSensorManager 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,89 @@ |
|||||
|
/*
|
||||
|
* 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, |
||||
|
}; |
||||
|
|
||||
|
void initVariant() |
||||
|
{ |
||||
|
// All pins output HIGH by default.
|
||||
|
// https://github.com/Seeed-Studio/Adafruit_nRF52_Arduino/blob/fab7d30a997a1dfeef9d1d59bfb549adda73815a/cores/nRF5/wiring.c#L65-L69
|
||||
|
|
||||
|
pinMode(PIN_VBAT_READ, INPUT); |
||||
|
pinMode(PIN_BATTERY_CHARGING, INPUT); |
||||
|
pinMode(PIN_CHARGER_FAULT, INPUT); |
||||
|
pinMode(PIN_BUTTON1, INPUT); |
||||
|
pinMode(PIN_BUTTON2, INPUT); |
||||
|
pinMode(PIN_BUTTON3, INPUT); |
||||
|
pinMode(PIN_BUTTON4, INPUT); |
||||
|
pinMode(PIN_BUTTON5, INPUT); |
||||
|
pinMode(PIN_BUTTON6, INPUT); |
||||
|
pinMode(LED_PIN, OUTPUT); |
||||
|
pinMode(LED_BLUE, OUTPUT); |
||||
|
digitalWrite(LED_PIN, LOW); |
||||
|
digitalWrite(LED_BLUE, LOW); |
||||
|
pinMode(BUZZER_PIN, OUTPUT); |
||||
|
digitalWrite(BUZZER_PIN, LOW); // turn off buzzer at start. don't leave it high.
|
||||
|
pinMode(GPS_EN_GPIO, OUTPUT); |
||||
|
digitalWrite(GPS_EN_GPIO, HIGH); // needs to turn on for GPS detection
|
||||
|
|
||||
|
pinMode(SCREEN_12V_ENABLE, OUTPUT); |
||||
|
digitalWrite(SCREEN_12V_ENABLE, LOW); // disable 12V power for SH1107 display for now.
|
||||
|
} |
||||
@ -0,0 +1,146 @@ |
|||||
|
/*
|
||||
|
* 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 |
||||
|
|
||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||
|
// LR1121
|
||||
|
|
||||
|
#define LORA_DIO_1 (32+8) // P1.08
|
||||
|
#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) |
||||
|
#define LORA_MISO (PIN_SPI_MISO) |
||||
|
#define LORA_MOSI (PIN_SPI_MOSI) |
||||
|
|
||||
|
#define LR11X0_DIO_AS_RF_SWITCH true |
||||
|
#define LR11X0_DIO3_TCXO_VOLTAGE 3.0 |
||||
|
|
||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||
|
// 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 GPS_EN_GPIO (32+1) // P1.01 PWR_IO2 on schematic. just cuts power to gps.
|
||||
|
|
||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||
|
// Buzzer
|
||||
|
|
||||
|
#define BUZZER_PIN (22) // P0.22 same load switch design as GPS_EN.
|
||||
Loading…
Reference in new issue