diff --git a/src/configuration.h b/src/configuration.h
index 1149f344ce..3d10feeaaf 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -75,11 +75,17 @@ along with this program. If not, see .
#endif
// -----------------------------------------------------------------------------
-// Regulatory overrides for producing regional builds
+// Regulatory overrides
// -----------------------------------------------------------------------------
-// Define if region should override user saved region
-// #define LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923
+// Override user saved region, for producing region-locked builds
+// #define REGULATORY_LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923
+
+// Total system gain in dBm to subtract from Tx power to remain within regulatory ERP limit for non-licensed operators
+// This value should be set in variant.h and is PA gain + antenna gain (if system ships with an antenna)
+#ifndef REGULATORY_GAIN_LORA
+#define REGULATORY_GAIN_LORA 0
+#endif
// -----------------------------------------------------------------------------
// Feature toggles
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index eb86f42678..78228c077c 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -154,8 +154,8 @@ static uint8_t bytes[MAX_RHPACKETLEN];
void initRegion()
{
const RegionInfo *r = regions;
-#ifdef LORA_REGIONCODE
- for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != LORA_REGIONCODE; r++)
+#ifdef REGULATORY_LORA_REGIONCODE
+ for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != REGULATORY_LORA_REGIONCODE; r++)
;
LOG_INFO("Wanted region %d, regulatory override to %s\n", config.lora.region, r->name);
#else
@@ -478,8 +478,8 @@ void RadioInterface::applyModemConfig()
power = loraConfig.tx_power;
- if ((power == 0) || ((power > myRegion->powerLimit) && !devicestate.owner.is_licensed))
- power = myRegion->powerLimit;
+ if ((power == 0) || ((power + REGULATORY_GAIN_LORA > myRegion->powerLimit) && !devicestate.owner.is_licensed))
+ power = myRegion->powerLimit - REGULATORY_GAIN_LORA;
if (power == 0)
power = 17; // Default to this power level if we don't have a valid regional power limit (powerLimit of myRegion defaults
diff --git a/variants/xiao_ble/platformio.ini b/variants/xiao_ble/platformio.ini
index 60e7cecbd5..9d533c0ada 100644
--- a/variants/xiao_ble/platformio.ini
+++ b/variants/xiao_ble/platformio.ini
@@ -3,7 +3,7 @@
extends = nrf52840_base
board = xiao_ble_sense
board_level = extra
-build_flags = ${nrf52840_base.build_flags} -Ivariants/xiao_ble -Ivariants/xiao_ble/softdevice -Ivariants/xiao_ble/softdevice/nrf52 -D EBYTE_E22 -DPRIVATE_HW
+build_flags = ${nrf52840_base.build_flags} -Ivariants/xiao_ble -Ivariants/xiao_ble/softdevice -Ivariants/xiao_ble/softdevice/nrf52 -D EBYTE_E22 -DEBYTE_E22_900M30S -DPRIVATE_HW
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
board_build.ldscript = variants/xiao_ble/nrf52840_s140_v7.ld
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/xiao_ble>
diff --git a/variants/xiao_ble/variant.h b/variants/xiao_ble/variant.h
index 77af08278c..a86ddfde26 100644
--- a/variants/xiao_ble/variant.h
+++ b/variants/xiao_ble/variant.h
@@ -142,6 +142,16 @@ static const uint8_t SCK = PIN_SPI_SCK;
// (which is the default for the sx1262interface code)
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+#ifdef EBYTE_E22_900M30S
+// 10dB PA gain and 30dB rated output; based on PA output table from Ebyte Robin
+#define REGULATORY_GAIN_LORA 10
+#define SX126X_MAX_POWER 20
+#endif
+#ifdef EBYTE_E22_900M33S
+// 25dB PA gain and 33dB rated output; based on TX Power Curve from E22-900M33S_UserManual_EN_v1.0.pdf
+#define REGULATORY_GAIN_LORA 25
+#define SX126X_MAX_POWER 8
+#endif
#endif
/*