Files
MeshCore/variants/muzi_base/target.cpp
T
TJ Downes 798ce636df Address review feedback on Muzi Base support
- rename the board class and files to MuziBaseBoard
- uppercase the build flags (MUZI_BASE, MUZI_BASE_SUPERIO)
- name the superIO envs muzi_base_{duo,uno}_superIO_companion_radio_ble so
  build.sh picks them up
- set MAX_CONTACTS to 350 like the other variants
- move the pin setup from initVariant() into MuziBaseBoard::begin()
2026-09-19 21:47:24 -07:00

163 lines
5.0 KiB
C++

#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
}