The LoRaRF SX126x driver in pymc_core sets TXEN HIGH during RX mode, which is inverted logic for E22-900M30S based modules (like PiMesh-1W). This causes the 1W Power Amplifier to remain constantly ON, resulting in ~2.1A draw instead of ~0.5A - a 4x increase in power consumption that drastically reduces battery life.
Environment
Hardware: Raspberry Pi Zero 2 W + PiMesh-1W HAT (E22-900M30S module)
Software: pymc_core 1.0.7 (installed from dev branch)
The SX126x.py driver sets TXEN HIGH when entering RX mode:
RX/Idle mode: TXEN = HIGH (PA on!) ❌
TX mode: TXEN = HIGH (PA on) ✓
Actual idle current: ~2,100 mA (PA constantly drawing ~1.6A extra)
Impact
Metric
Expected
Actual
Impact
Idle current
500 mA
2,100 mA
4x higher
Idle power
2.0W
8.3W
4x higher
Runtime (14Ah battery)
25 hours
6 hours
75% reduction
For solar-powered remote repeaters, this bug can cause unexpected shutdowns during cloudy periods.
Root Cause
In /usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py:
Line 955-958 (request method - enters RX mode):
# save current txen pin state and set txen pin to highifself._txen!=-1:self._txState=_get_output(self._txen).read()_get_output(self._txen).write(True)# BUG: Should be False for RX
Line 980-983 (listen method):
# save current txen pin state and set txen pin to highifself._txen!=-1:self._txState=_get_output(self._txen).read()_get_output(self._txen).write(True)# BUG: Should be False for RX
# In sx1262_wrapper.py initializationself.txen_active_high_for_tx=config.get("txen_active_high_for_tx",True)# In _control_tx_rx_pins methoddef_control_tx_rx_pins(self,tx_mode:bool)->None:iftx_mode:txen_state=self.txen_active_high_for_txelse:txen_state=notself.txen_active_high_for_txifself.txen_pin!=-1:iftxen_state:self._gpio_manager.set_pin_high(self.txen_pin)else:self._gpio_manager.set_pin_low(self.txen_pin)
Option 2: Use the wrapper's _control_tx_rx_pins exclusively
The sx1262_wrapper.py already has correct logic in _control_tx_rx_pins() (lines 872-887). The issue is that SX126x.py also controls TXEN directly, bypassing the wrapper.
Either:
Remove TXEN control from SX126x.py entirely and let the wrapper handle it
Or pass -1 to SX126x for txen_pin and handle it only in the wrapper
Verification Data
Before Fix (TXEN stuck HIGH)
Monitoring for 30 seconds...
Time Voltage Current (mA) Power (W)
0s 3.91V -2167 mA 8.5W
1s 3.92V -2149 mA 8.4W
...
29s 3.93V -2112 mA 8.3W
After Fix (TXEN LOW during RX)
60-second stability test...
Time Voltage Current Power Note
0s 4.00V 916 mA 3.7W RX/Idle
...
49s 3.93V 2252 mA 8.8W TX <- Brief TX spike (normal)
50s 4.01V 544 mA 2.2W RX/Idle <- Returns to low power
...
============================================================
SUMMARY:
Idle/RX average: 566 mA
TX events: 1
Estimated runtime (14Ah): 24.7 hours
Affected Hardware
This bug likely affects all modules using external PA controlled by TXEN:
PiMesh-1W HAT (E22-900M30S)
Ebyte E22-900M30S
Any SX1262 + external PA with TXEN control
## Summary
The LoRaRF SX126x driver in pymc_core sets TXEN HIGH during RX mode, which is inverted logic for E22-900M30S based modules (like PiMesh-1W). This causes the 1W Power Amplifier to remain constantly ON, resulting in ~2.1A draw instead of ~0.5A - a 4x increase in power consumption that drastically reduces battery life.
## Environment
- **Hardware:** Raspberry Pi Zero 2 W + PiMesh-1W HAT (E22-900M30S module)
- **Software:** pymc_core 1.0.7 (installed from dev branch)
- **OS:** Raspberry Pi OS (Debian Trixie)
- **Python:** 3.13
## Expected Behavior
For E22/PiMesh-1W modules with external PA:
- **RX/Idle mode:** TXEN = LOW (PA off), RXEN = HIGH (LNA on)
- **TX mode:** TXEN = HIGH (PA on), RXEN = LOW (LNA off)
Expected idle current: ~500-600 mA
## Actual Behavior
The SX126x.py driver sets TXEN HIGH when entering RX mode:
- **RX/Idle mode:** TXEN = HIGH (PA on!) ❌
- **TX mode:** TXEN = HIGH (PA on) ✓
Actual idle current: ~2,100 mA (PA constantly drawing ~1.6A extra)
## Impact
| Metric | Expected | Actual | Impact |
|--------|----------|--------|--------|
| Idle current | 500 mA | 2,100 mA | 4x higher |
| Idle power | 2.0W | 8.3W | 4x higher |
| Runtime (14Ah battery) | 25 hours | 6 hours | 75% reduction |
For solar-powered remote repeaters, this bug can cause unexpected shutdowns during cloudy periods.
## Root Cause
In `/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py`:
**Line 955-958 (request method - enters RX mode):**
```python
# save current txen pin state and set txen pin to high
if self._txen != -1:
self._txState = _get_output(self._txen).read()
_get_output(self._txen).write(True) # BUG: Should be False for RX
```
**Line 980-983 (listen method):**
```python
# save current txen pin state and set txen pin to high
if self._txen != -1:
self._txState = _get_output(self._txen).read()
_get_output(self._txen).write(True) # BUG: Should be False for RX
```
**Lines 1054, 1059, 1154, 1164 (post-TX restoration):**
```python
_get_output(self._txen).write(self._txState) # BUG: Restores previous (wrong) state
```
The comments say "set txen pin to high" for RX mode, suggesting this was intentional but incorrect for E22 modules with external PA.
## Workaround / Fix
Patch SX126x.py to set TXEN LOW for RX mode and after TX:
```bash
# Backup original
sudo cp /usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py \
/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py.bak
# Fix RX mode (line 958)
sudo sed -i '958s/_get_output(self._txen).write(True)/_get_output(self._txen).write(False)/' \
/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py
# Fix listen mode (line 983)
sudo sed -i '983s/_get_output(self._txen).write(True)/_get_output(self._txen).write(False)/' \
/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py
# Fix post-TX restoration (lines 1054, 1059, 1154, 1164)
sudo sed -i 's/_get_output(self._txen).write(self._txState)/_get_output(self._txen).write(False)/g' \
/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py
# Restart service
sudo systemctl restart pymc-repeater
```
## Suggested Proper Fix
The correct fix should make TXEN behavior configurable, as different modules may have different logic:
### Option 1: Add `txen_active_high_for_tx` config option
```python
# In sx1262_wrapper.py initialization
self.txen_active_high_for_tx = config.get("txen_active_high_for_tx", True)
# In _control_tx_rx_pins method
def _control_tx_rx_pins(self, tx_mode: bool) -> None:
if tx_mode:
txen_state = self.txen_active_high_for_tx
else:
txen_state = not self.txen_active_high_for_tx
if self.txen_pin != -1:
if txen_state:
self._gpio_manager.set_pin_high(self.txen_pin)
else:
self._gpio_manager.set_pin_low(self.txen_pin)
```
### Option 2: Use the wrapper's _control_tx_rx_pins exclusively
The `sx1262_wrapper.py` already has correct logic in `_control_tx_rx_pins()` (lines 872-887). The issue is that `SX126x.py` also controls TXEN directly, bypassing the wrapper.
Either:
1. Remove TXEN control from SX126x.py entirely and let the wrapper handle it
2. Or pass `-1` to SX126x for txen_pin and handle it only in the wrapper
## Verification Data
### Before Fix (TXEN stuck HIGH)
```
Monitoring for 30 seconds...
Time Voltage Current (mA) Power (W)
0s 3.91V -2167 mA 8.5W
1s 3.92V -2149 mA 8.4W
...
29s 3.93V -2112 mA 8.3W
```
### After Fix (TXEN LOW during RX)
```
60-second stability test...
Time Voltage Current Power Note
0s 4.00V 916 mA 3.7W RX/Idle
...
49s 3.93V 2252 mA 8.8W TX <- Brief TX spike (normal)
50s 4.01V 544 mA 2.2W RX/Idle <- Returns to low power
...
============================================================
SUMMARY:
Idle/RX average: 566 mA
TX events: 1
Estimated runtime (14Ah): 24.7 hours
```
## Affected Hardware
This bug likely affects all modules using external PA controlled by TXEN:
- PiMesh-1W HAT (E22-900M30S)
- Ebyte E22-900M30S
- Any SX1262 + external PA with TXEN control
<!-- github-sync-id:3769005208 -->
Thank you — I’m really glad you’re enjoying it!! Great find!
Please keep sharing more little beauties like that — the more PRs, the better 👍
P.S. If you’re not already there, feel free to join us on Discord:
https://discord.com/channels/1343693475589263471/1431414286974189639
<!-- github-comment-id:3704236144 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The LoRaRF SX126x driver in pymc_core sets TXEN HIGH during RX mode, which is inverted logic for E22-900M30S based modules (like PiMesh-1W). This causes the 1W Power Amplifier to remain constantly ON, resulting in ~2.1A draw instead of ~0.5A - a 4x increase in power consumption that drastically reduces battery life.
Environment
Expected Behavior
For E22/PiMesh-1W modules with external PA:
Expected idle current: ~500-600 mA
Actual Behavior
The SX126x.py driver sets TXEN HIGH when entering RX mode:
Actual idle current: ~2,100 mA (PA constantly drawing ~1.6A extra)
Impact
For solar-powered remote repeaters, this bug can cause unexpected shutdowns during cloudy periods.
Root Cause
In
/usr/local/lib/python3.13/dist-packages/pymc_core/hardware/lora/LoRaRF/SX126x.py:Line 955-958 (request method - enters RX mode):
Line 980-983 (listen method):
Lines 1054, 1059, 1154, 1164 (post-TX restoration):
The comments say "set txen pin to high" for RX mode, suggesting this was intentional but incorrect for E22 modules with external PA.
Workaround / Fix
Patch SX126x.py to set TXEN LOW for RX mode and after TX:
Suggested Proper Fix
The correct fix should make TXEN behavior configurable, as different modules may have different logic:
Option 1: Add
txen_active_high_for_txconfig optionOption 2: Use the wrapper's _control_tx_rx_pins exclusively
The
sx1262_wrapper.pyalready has correct logic in_control_tx_rx_pins()(lines 872-887). The issue is thatSX126x.pyalso controls TXEN directly, bypassing the wrapper.Either:
-1to SX126x for txen_pin and handle it only in the wrapperVerification Data
Before Fix (TXEN stuck HIGH)
After Fix (TXEN LOW during RX)
Affected Hardware
This bug likely affects all modules using external PA controlled by TXEN:
Let me review these changes thank you.
Thank you and great find!, I have applied this fix to the underlying PYMC_CORE lib (in dev branch)
Appreciate the quick response! I'm really enjoying pyMC_Repeater. Thanks for all the work you've put into it.
Thank you — I’m really glad you’re enjoying it!! Great find!
Please keep sharing more little beauties like that — the more PRs, the better 👍
P.S. If you’re not already there, feel free to join us on Discord:
https://discord.com/channels/1343693475589263471/1431414286974189639