Add ITU regions for this device and make GPS work.
This commit is contained in:
@@ -1239,6 +1239,22 @@ bool Power::axpChipInit()
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
} else if (HW_VENDOR == meshtastic_HardwareModel_TBEAM_BPF) {
|
||||
// T-Beam BPF rail map (per schematic LilyGo_TBeam_BPF r2025-05-08):
|
||||
// DCDC1 -> ESP32 + OLED 3V3 (always on, protected)
|
||||
// ALDO2 -> MicroSD 3V3 (OFF at reset, must enable)
|
||||
// ALDO4 -> L76K GNSS 3V3 (OFF at reset, must enable)
|
||||
// ALDO1/3, BLDO1/2, DLDO1 -> user headers / unused at boot, leave at reset defaults.
|
||||
// LoRa power is outside the PMU (external P-MOSFET switched by RF95_POWER_EN / IO16).
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
// Make sure nothing's driving into an unused rail
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5);
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1);
|
||||
}
|
||||
|
||||
// disable all axp chip interrupt
|
||||
|
||||
@@ -112,6 +112,14 @@ void menuHandler::OnboardMessage()
|
||||
|
||||
void menuHandler::LoraRegionPicker(uint32_t duration)
|
||||
{
|
||||
#ifdef HAS_HAM_2M_ONLY
|
||||
// Hardware is restricted to the amateur 2m band — offer only the two 2m regions
|
||||
// so the user cannot pick a sub-GHz region the RF path cannot emit or receive.
|
||||
static const LoraRegionOption regionOptions[] = {
|
||||
{"ITU1_2M (144-146)", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_ITU1_2M},
|
||||
{"ITU2/3_2M (144-148)", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M},
|
||||
};
|
||||
#else
|
||||
static const LoraRegionOption regionOptions[] = {
|
||||
{"Back", OptionsAction::Back},
|
||||
{"US", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_US},
|
||||
@@ -141,6 +149,7 @@ void menuHandler::LoraRegionPicker(uint32_t duration)
|
||||
{"NP_865", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_NP_865},
|
||||
{"BR_902", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_BR_902},
|
||||
};
|
||||
#endif
|
||||
|
||||
constexpr size_t regionCount = sizeof(regionOptions) / sizeof(regionOptions[0]);
|
||||
static std::array<const char *, regionCount> regionLabels{};
|
||||
|
||||
@@ -26,9 +26,9 @@ struct RegionProfile {
|
||||
extern const RegionProfile PROFILE_STD;
|
||||
extern const RegionProfile PROFILE_EU868;
|
||||
extern const RegionProfile PROFILE_UNDEF;
|
||||
extern const RegionProfile PROFILE_HAM;
|
||||
// extern const RegionProfile PROFILE_LITE;
|
||||
// extern const RegionProfile PROFILE_NARROW;
|
||||
// extern const RegionProfile PROFILE_HAM;
|
||||
|
||||
// Map from old region names to new region enums
|
||||
struct RegionInfo {
|
||||
|
||||
@@ -1124,6 +1124,13 @@ void NodeDB::installDefaultDeviceState()
|
||||
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = false;
|
||||
|
||||
#ifdef HAS_HAM_2M_ONLY
|
||||
// Ham-band-only hardware defaults to licensed operation. The user can still flip this off later
|
||||
// (e.g. a commercial operator on an adjacent allocation who wants to keep encryption on) — we
|
||||
// only set the default here, not on every boot.
|
||||
owner.is_licensed = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We reserve a few nodenums for future use
|
||||
|
||||
@@ -54,6 +54,7 @@ static const meshtastic_Config_LoRaConfig_ModemPreset PRESETS_UNDEF[] = {meshtas
|
||||
const RegionProfile PROFILE_STD = {PRESETS_STD, 0, 0, true, false, 0, 0, 0, 0};
|
||||
const RegionProfile PROFILE_EU868 = {PRESETS_EU_868, 0, 0, false, false, 0, 0, 0, 0};
|
||||
const RegionProfile PROFILE_UNDEF = {PRESETS_UNDEF, 0, 0, true, false, 0, 0, 0, 0};
|
||||
const RegionProfile PROFILE_HAM = {PRESETS_STD, 0, 0, false, true, 0, 0, 0, 0};
|
||||
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, power_limit, frequency_switching, wide_lora, profile_ptr) \
|
||||
{ \
|
||||
@@ -223,6 +224,19 @@ const RegionInfo regions[] = {
|
||||
*/
|
||||
RDEF(BR_902, 902.0f, 907.5f, 100, 30, false, false, PROFILE_STD),
|
||||
|
||||
/*
|
||||
ITU Region 1 (Europe, Africa, Middle East, former USSR) amateur 2m allocation: 144.000 - 146.000 MHz.
|
||||
Power limit is the regulatory ceiling (1 W / 30 dBm) — individual hardware will cap below this
|
||||
via its own PA curve; the field here is just the legal upper bound.
|
||||
*/
|
||||
RDEF(ITU1_2M, 144.0f, 146.0f, 100, 30, false, false, PROFILE_HAM),
|
||||
|
||||
/*
|
||||
ITU Region 2 (Americas) and Region 3 (Asia/Pacific) amateur 2m allocation: 144.000 - 148.000 MHz.
|
||||
Typical admin rules (e.g. US FCC Part 97) allow well above 30 dBm for licensed operators.
|
||||
*/
|
||||
RDEF(ITU23_2M, 144.0f, 148.0f, 100, 30, false, false, PROFILE_HAM),
|
||||
|
||||
/*
|
||||
2.4 GHZ WLAN Band equivalent. Only for SX128x chips.
|
||||
*/
|
||||
@@ -505,6 +519,23 @@ std::unique_ptr<RadioInterface> initLoRa()
|
||||
rebootAtMsec = millis() + 5000;
|
||||
}
|
||||
}
|
||||
|
||||
// Hardware/region crosscheck for the amateur 2m band: ham-only boards must run a 2m region,
|
||||
// and boards without 2m support must not run one. In either mismatch, drop to UNSET so the
|
||||
// first-start picker runs and the user re-selects a legal region for the hardware.
|
||||
const bool is2mRegion = config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_ITU1_2M ||
|
||||
config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M;
|
||||
#ifdef HAS_HAM_2M_ONLY
|
||||
const bool mismatch = !is2mRegion && config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||
#else
|
||||
const bool mismatch = is2mRegion;
|
||||
#endif
|
||||
if (mismatch) {
|
||||
LOG_WARN("Saved region incompatible with this hardware's RF path. Revert to unset");
|
||||
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||
nodeDB->saveToDisk(SEGMENT_CONFIG);
|
||||
}
|
||||
|
||||
return rIf;
|
||||
}
|
||||
|
||||
@@ -787,7 +818,14 @@ bool RadioInterface::validateConfigRegion(const meshtastic_Config_LoRaConfig &lo
|
||||
const RegionInfo *newRegion = getRegion(loraConfig.region);
|
||||
|
||||
// If you are not licensed, you can't use ham regions.
|
||||
if (newRegion->profile->licensedOnly && !devicestate.owner.is_licensed) {
|
||||
// Exception: on hardware that can *only* operate on a ham band (e.g. T-Beam BPF), the user has
|
||||
// no other region to choose, so allow unlicensed selection — a commercial operator on adjacent
|
||||
// frequencies can still use the band plan and keep encryption enabled.
|
||||
bool allowUnlicensedHam = false;
|
||||
#ifdef HAS_HAM_2M_ONLY
|
||||
allowUnlicensedHam = true;
|
||||
#endif
|
||||
if (newRegion->profile->licensedOnly && !devicestate.owner.is_licensed && !allowUnlicensedHam) {
|
||||
char err_string[160];
|
||||
snprintf(err_string, sizeof(err_string), "Region %s requires licensed mode", newRegion->name);
|
||||
LOG_ERROR("%s", err_string);
|
||||
@@ -796,6 +834,34 @@ bool RadioInterface::validateConfigRegion(const meshtastic_Config_LoRaConfig &lo
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool is2mRegion = loraConfig.region == meshtastic_Config_LoRaConfig_RegionCode_ITU1_2M ||
|
||||
loraConfig.region == meshtastic_Config_LoRaConfig_RegionCode_ITU23_2M;
|
||||
|
||||
#ifdef HAS_HAM_2M_ONLY
|
||||
// This hardware's front-end / band-pass filter only passes 144-148 MHz. Any other region
|
||||
// selection would key the radio on a frequency the RF path cannot emit or receive.
|
||||
if (!is2mRegion && loraConfig.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
|
||||
char err_string[160];
|
||||
snprintf(err_string, sizeof(err_string), "Region %s not supported: this hardware is 2m-only", newRegion->name);
|
||||
LOG_ERROR("%s", err_string);
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
sendErrorNotification(err_string);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// Conversely, the 2m ham regions are illegal RF output for hardware not designed for that band
|
||||
// (e.g. selecting ITU23_2M on a 915 MHz node would transmit at ~3x the expected frequency with
|
||||
// an untuned antenna and filter). Refuse the selection entirely.
|
||||
if (is2mRegion) {
|
||||
char err_string[160];
|
||||
snprintf(err_string, sizeof(err_string), "Region %s requires 2m-band hardware", newRegion->name);
|
||||
LOG_ERROR("%s", err_string);
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
sendErrorNotification(err_string);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// LilyGo T-Beam-BPF variant.h
|
||||
// Configuration based on LilyGO utilities.h and RF documentation
|
||||
|
||||
// TODO Lock to 2M (144mhz) ham "region"
|
||||
// #define REGULATORY_LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_HAM_2M
|
||||
// Hardware is restricted to the amateur 2m band (144-148 MHz).
|
||||
#define HAS_HAM_2M_ONLY 1
|
||||
|
||||
// I2C for OLED display (SH1106 at 0x3C)
|
||||
#define I2C_SDA 8
|
||||
#define I2C_SCL 9
|
||||
|
||||
// GPS - Quectel L76K
|
||||
// GPS - Quectel L76K. Per schematic sheet 7:
|
||||
|
||||
#define GPS_RX_PIN 5
|
||||
#define GPS_TX_PIN 6
|
||||
#define GPS_1PPS_PIN 7
|
||||
|
||||
Reference in New Issue
Block a user