LBT is not working on WM1302-SPI-AS923

I am using the WM1302-SPI-AS923, but LBT (Listen Before Talk) is not working.

The software I am using is lora_pkt_fwd, included in the following repository:

https://github.com/Lora-net/sx1302_hal

tag: v2.1.0

Since there was no configuration file for SPI, I created one based on the USB version. The modifications are as follows:

pc$ cd sx1302_hal/packet_forwarder
pc$ diff -uN global_conf.json.sx1250.AS923.USB global_conf.json.sx1250.AS923
--- global_conf.json.sx1250.AS923.USB    2026-06-17 11:24:26.770416638 +0900
+++ global_conf.json.sx1250.AS923    2026-07-16 09:54:46.823214266 +0900
@@ -1,7 +1,7 @@
 {
     "SX130x_conf": {
-        "com_type": "USB",
-        "com_path": "/dev/ttyACM0",
+        "com_type": "SPI",
+        "com_path": "/dev/spidev1.0",
         "lorawan_public": true,
         "clksrc": 0,
         "antenna_gain": 0, /* antenna gain, in dBi */
@@ -11,6 +11,7 @@
             "mode": "all_sf" /* high_capacity or all_sf */
         },
         "sx1261_conf": {
+            "spi_path": "/dev/spidev1.1",
             "rssi_offset": 0, /* dB */
             "spectral_scan": {
                 "enable": false,

Since spectral_scan is working correctly, I assume that the SPI communication with the SX126x is functioning properly.

Additionally, when I set enable for “lbt” to false, I confirmed that it works perfectly as a LoRa Gateway. However, when I set it to true, the gateway can receive data transmitted by end devices, but it fails to transmit data back to the server.

The radio environment is good, as there are no other devices nearby utilizing the 920MHz band.

The logs from lora_pkt_fwd are as follows:

is_lbt_channel:72: LBT: select channel 7 (freq:923200000 Hz, bw:0x04)
SX1261: spectral scan aborted
sx1261_set_rx_params:464: SX1261: RX params set to 923200000 Hz (bw:0x04)
sx1261_lbt_start:514: SX1261: LBT started: scan time = 5000us, threshold = -80dBm
INFO: selecting TX Gain LUT index 5
INFO: Applying IQ offset (i:0, q:0)
Setting LoRa syncword 0x34
Disable Fine Sync
Low datarate optimization DISABLED
INFO: tx_start_delay=46901 (48000, radio_bw_delay=19, filter_delay=1016, modem_delay=64)
Start Tx: Freq:923200000 SF10 size:17 preamb:8
--> programming trig delay at 19161286 (613161131)
ERROR: lgw_lbt_tx_status: TIMEOUT on TX start, not started
ERROR: lgw_send: Failed to get LBT TX status, TX aborted
SX1261: LBT stopped
WARNING: [jit] lgw_send failed on rf_chain 0
INFO: [down] PULL_ACK received in 1 ms

Any advice or insights on how to resolve this issue would be greatly appreciated. Thank you.

Hi there,

And Welcome here…

So, I notice in the example it is NOT enabled, you may be assuming too much, :grin:

"spectral_scan": {
    "enable": false,

Just because it worked in an isolated test doesn’t mean the SX1261’s SPI communication is holding up during active gateway operations.

  1. The “Timeout” Strongly Implies a Communication Failure** The logs reveal exactly where the failure happens:

ERROR: lgw_lbt_tx_status: TIMEOUT on TX start, not started ERROR: lgw_send: Failed to get LBT TX status, TX aborted

If the SPI communication with the SX1261 (which handles the LBT scanning) were truly functioning properly, the system wouldn’t throw a timeout when checking the TX status. It would simply report back whether the channel was clear or busy. A timeout strongly suggests that the main chip (SX1302) requested the LBT status from the SX1261 over /dev/spidev1.1 and never received a response.

3. The Scan Aborted Log Right before the errors, the log explicitly states:

SX1261: spectral scan aborted

The Takeaway: Listen Before Talk (LBT) has incredibly strict timing requirements compared to a passive spectral scan. Even if basic SPI communication worked well enough for a casual spectral scan test in the past, the LBT process requires immediate, real-time status checks. The timeout errors directly point to a bottleneck, latency, or complete failure on the SPI bus (spidev1.1) when the system actually demands it.

I would rework the SPI part maybe YMMV

HTH
GL :slight_smile: PJ :v:

First of all, thank you so much for the incredibly fast reply!

So, I notice in the example it is NOT enabled, you may be assuming too much, :grin:

My previous explanation was a bit misleading, sorry about that. I actually confirmed the spectral scan operation using the following standalone utility application, not just the JSON configuration:
sx1302_hal/util_spectral_scan/spectral_scan

If the SPI communication with the SX1261 (which handles the LBT scanning) were truly functioning properly, the system wouldn’t throw a timeout when checking the TX status. It would simply report back whether the channel was clear or busy.

Actually, I believe the SPI communication is functioning correctly. The source code that outputs TIMEOUT on TX start, not started is shown below. As you can see, if the SPI communication were failing, the sx1302_agc_status(&status) check would fail, and it would output failed to get AGC status instead.

sx1302_hal/libloragw/src/loragw_lbt.c:
int lgw_lbt_tx_status(uint8_t rf_chain, bool * tx_ok) {
 :snip
    /* Wait for transmit to be initiated */
    /* Bit 0 in status: TX has been initiated on Radio A */
    /* Bit 1 in status: TX has been initiated on Radio B */
    timeout_start(&tm_start);
    do {
        /* handle timeout */
        if (timeout_check(tm_start, 500) != 0) {
            printf("ERROR: %s: TIMEOUT on TX start, not started\n", __FUNCTION__);
            tx_timeout = true;
            /* we'll still perform the AGC clear status and return an error to upper layer */
            break;
        }

        /* get tx status */
        err = sx1302_agc_status(&status);
        if (err != 0) {
            printf("ERROR: %s: failed to get AGC status\n", __FUNCTION__);
            return -1;
        }
        wait_ms(1);
    } while ((status & (1 << rf_chain)) == 0x00);

Hi there,

So , it’s “Listen :deaf_person: before Talk :backhand_index_pointing_left: :wink:” right, so the Transmit may not have as tight requirements , it’s just dump it an go.
Ah’ but the RECeive transaction :ear: is at issue.

I would stay there.
AGC (Automatic Gain Control) is fundamentally a Receive (RX) function, not a transmit function.

So why is sx1302_agc_status being polled inside a function named lgw_lbt_tx_status?

It all comes down to the Listen part of “Listen Before Talk” (LBT):

  • The Listening Phase: In the SX1302 architecture, the AGC firmware/microcontroller is responsible for managing receiver gain, but it is also tasked with handling the LBT state machine.
  • Checking for Clearance: Before the gateway is allowed to transmit, it must use the receiver chain to measure the channel’s energy level (RSSI).
  • The Polling Loop: The C code in that screenshot is polling the AGC firmware to check the status of that listening phase. It is essentially waiting for the AGC controller to report, “I listened, the channel is clear, and the TX sequence is now allowed to initiate.”

The transmission itself (“dump it and go”) isn’t the bottleneck. The timeout is happening during the time-critical Receive/Listen transaction that LBT strictly requires before it ever lets the transmitter fire.

Maybe slow the whole thing down and turn the Transmit power down for the tests.
I have seen a simpler example of the LBT also , but maybe another vendor?

HTH
GL :slight_smile: PJ :v:

Thank you for your response and support.

As you suggested, I tried slowing things down and lowering the transmit power for testing. Specifically, I did the following:

  • Increased the timeout duration for polling sx1302_agc_status() to slow down the checking process.
  • Modified the tx_gain_lut in global_conf.json.sx1250.AS923 to force the minimum output power for all rf_power levels to reduce any potential power drop or RF noise.

Unfortunately, there was no change in the situation, and the timeout still occurs.

Based on the fact that SPI communication is working but the TX initiation still times out despite these tests, I have a strong suspicion about the hardware design or pin mapping of the WM1302 module, specifically regarding the LBT trigger signal.

Looking at the LBT sequence, where the software starts LBT on the SX1261 and then polls the SX1302 AGC firmware, I assume the SX1302 expects a hardware trigger from the SX1261 (likely via DIO1, DIO2, or DIO3). In a typical SX1302 + SX1261 architecture, once the SX1261 determines the channel is clear, it asserts this hardware signal directly to the SX1302 to trigger the transmission. If this physical connection is missing, or if the software is listening to the wrong pin, the SX1302 will wait endlessly for the trigger, resulting in the exact TIMEOUT on TX start error I am seeing.

Could you please check with your hardware engineering team on the following points?

  1. Hardware Routing: In the WM1302 schematic, is the LBT completion/trigger signal (such as SX1261 DIO[1-3]) physically routed between the SX1261 and the SX1302?
  2. HAL Compatibility: If it is connected, does it use the default pin assignment expected by the standard Semtech sx1302_hal? Or does the WM1302 require a custom patch/configuration to map the correct GPIO for the LBT trigger?
  3. Reproduction: Has Seeed successfully tested and validated LBT functionality (including actual transmission after listening) on the WM1302-SPI-AS923 module in your lab? If so, could you share the exact global_conf.json or HAL modifications used?

Any insights from your hardware team would be greatly appreciated. Thank you again for your time!

1 Like

Hi there,

So, That is some excellent deductive reasoning right there! A completely forgotten or misrouted trace on a production module wouldn’t be the first time it’s happened in the hardware world (however unlikely on a mature run), but your pin mapping theory is definitely Sturdy and worthy of some Seeedineers’ attention… :grin:

I have to admit, I was definitely on the “low hanging fruit” team here tonight just looking at the basic AGC polling loop, but you’ve really drilled down into the actual hardware integration layers. Those HAL pin assignments can absolutely be a trap if a custom board deviates even slightly from the Semtech reference design.

just compare the Xiao 2 vesrions , a basic one was a task. :face_with_peeking_eye:

You’ve laid out the perfect questions for them to investigate. I’m certain someone can respond from Seeed with the actual internal schematics or the specific HAL patch requirements for this module.

Good work isolating this! :+1:
let’s see what comes back.
HTH
GL :slight_smile: PJ :v:

Thank you very much for your prompt response and excellent support!

I really appreciate you taking my technical feedback seriously and reaching out to the hardware engineering team. I understand that verifying these hardware-level details might take a little time.

I will patiently wait for their answer and any updates you can provide.

Thank you again for your continued assistance!

TIA! :pray: :slight_smile:

mizo

1 Like