Technical Deep-Dive RF / Embedded Systems · Sub-GHz LoRa · 433/470/868/915 MHz
A purely technical write-up based on hands-on experience with the SX1262 LoRa transceiver, covering hardware design, driver configuration, and the usual gotchas. Questions and corrections welcome.
1. The SX1262 at a Glance
The SX1262 is Semtech's second-generation LoRa transceiver, and compared to the first-generation SX1276/SX1278 it is a ground-up redesign — the LoRa modem is now a fully digital DSP engine rather than a discrete analog modulator/demodulator pair.
Feature
SX1278 (Gen 1)
SX1262 (Gen 2)
Modem architecture
Discrete LoRa modulator + demodulator
Integrated DSP, fully digital demodulation
Max TX power
+20 dBm (PA_BOOST)
+22 dBm
RX sensitivity (SF12/125 kHz)
≈ −137 dBm
≈ −148 dBm (TCXO version)
Sleep current
≈ 1 µA
≈ 1.2 µA (≈ 1.6 µA with RTC)
Supply voltage
1.8–3.6 V
1.8–3.6 V
LDRO (Low Data Rate Optimize)
Manual configuration
Auto or manual via register
Blocking immunity
Mediocre
Noticeably better (improved front-end AGC)
Package
QFN-28
QFN-24
A few takeaways from the bench:
+22 dBm is the datasheet ceiling — you will only hold it with a DCDC supply and a decent matching network. On an LDO, continuous TX tends to sag by about 1 dB.
The ~3 dB sensitivity improvement is real and it matters: with identical antennas, my measured range on the SX1262 ran 30–40% farther than an equivalent SX1278 setup.
The blocking immunity claim checks out too. With a 2.4 GHz Wi-Fi router sitting right next to the bench, packet error rates on 433 MHz were far lower than the SX1278 rig.
2. Hardware Design Notes (Field-Tested Pitfalls)
2.1 Power: Use the DCDC, Skip the LDO
The SX1262 has a built-in buck converter — all it needs is a 4.7 µH inductor and 4.7/10 µF of output capacitance. Measured figures:
DCDC mode: ~118 mA at +22 dBm TX, from a 3.3 V input
LDO mode (SetDRegulatorMode): ~148 mA under the same conditions
For duty-cycled transmitters (downlinks, beacons), DCDC mode saves roughly 20% and runs the die cooler, which also means less frequency drift. The one catch: buck switching noise can cost you a hair of RX sensitivity. Keep the inductor away from the crystal and RF traces — 3 mm of separation was enough in my layout.
2.2 Crystal: Just Use a TCXO
The SX1262 supports either a TCXO or a plain XTAL, and the difference is temperature stability:
XTAL (±10 ppm): fine at room temperature, but across the industrial range (−40 to 85 °C) the drift exceeds what LoRa tolerates (25% of symbol duration) — high spreading factors simply stop receiving.
TCXO (±0.5–2 ppm): two or three dollars more, problem gone.
For anything outdoor or wide-temperature, a TCXO is non-negotiable. Power it from the chip's DIO3 rail at 1.8 V (SetDio3TcxoCtrl) and hang a 100 nF decoupling capacitor on DIO3.
2.3 Matching Network and Antenna Switch
SX1262 TX/RX ── L/C matching ── TX/RX switching ── (optional external PA/LNA) ── antenna
Up to +22 dBm the internal PA is all you need. For more (the +30 dBm-class modules), you cascade an external PA.
Follow the Semtech reference design: DIO2 drives the TX/RX switch (SetDio2AsRfSwitchCtrl), and the RFO/RFI pins reach the antenna through a simple pi-network. The BOM cost is negligible.
Layout rules I don't break:
50 Ω microstrip on the top layer, layer 2 an unbroken ground plane;
No power rails and no via fields anywhere near the antenna feed;
0402 passives in the matching network, placed symmetrically.
3. Driver Notes: SPI Timing and the Commands That Matter
The SX1262 driver isn't hard — SPI runs up to 16 MHz — but a few command sequences must be followed to the letter:
3.1 Two Rules to Burn Into Memory
1. After waking from sleep, wait for BUSY to drop, then send GetStatus to clear the state.
Wake: NSS low → wait for BUSY=0 → send GetStatus (0xC0)
Half of all "it transmits fine most of the time" bugs live here.
2. Wait for BUSY to release after every command.
SX1262 commands execute asynchronously. Anything you send while BUSY is high gets ignored. Your driver needs:
while(gpio_read(BUSY_PIN) == 1) { timeout--; if(!timeout) return -1; }
3.2 A Typical Init Sequence
// 1. Wake up
sx1262_wakeup();
// 2. Standby, RC source
sx1262_set_standby(STANDBY_RC);
// 3. TCXO config (if fitted)
sx1262_set_dio3_as_tcxo_ctrl(TCXO_CTRL_1_8V, 320); // 5 ms startup
// 4. Calibrate
sx1262_calibrate(0x7F); // full calibration
// 5. DCDC and RF switch
sx1262_set_dio2_as_rf_switch_ctrl(true);
sx1262_set_regulator_mode(USE_DCDC);
// 6. Frequency (470 MHz example)
sx1262_set_rf_frequency(470000000);
// 7. LoRa parameters
sx1262_set_packet_type(PACKET_TYPE_LORA);
sx1262_set_modulation_params(SF9, BW_125KHZ, CR_4_5, LORA_PKT_EXPLICIT);
sx1262_set_buffer_base_address(0x00, 0x00);
sx1262_set_packet_params(preamble=8, header=EXPLICIT, len=255, CRC=ON, IQ=STANDARD);
3.3 LDRO: Don't Guess, Compute
This is the most commonly missed gotcha. Once symbol duration exceeds 16 ms, LDRO must be enabled — the link will still handshake, but stability falls apart. The math:
SymbolDuration(ms) = (2^SF / BW) × 1000
SF12 @ 125 kHz = 32.8 ms → LDRO required
SF9 @ 125 kHz = 4.1 ms → not needed
Compute it in software from SF and BW; don't rely on defaults.
3.4 Max Payload vs. Sensitivity Quick Table
SF
Bandwidth
Max payload
Sensitivity
SF7
125 kHz
222 B
−123 dBm
SF9
125 kHz
123 B
−129 dBm
SF12
125 kHz
53 B
−137 dBm (−148 dBm with LDRO)
SF7
500 kHz
253 B
−113 dBm
Heads-up: at SF12/125 kHz you only get 53 bytes of payload. If your application needs 100-byte frames, you are either raising the SF or fragmenting.
4. Debugging: Getting a Link Up and Stable
4.1 The Order That Works
Fix one side as a continuous-wave transmitter: SetTxContinuousWave, then check frequency accuracy and output power on a spectrum analyzer — an RTL-SDR is good enough.
Then close the receive path: transmit from the fixed side, read back RSSI/SNR via GetPacketStatus on the receiving end.
Protocol last: add CRC, addressing, retries.
4.2 Troubleshooting Cheat Sheet
Symptom
Likely cause
How to check
TX power below spec
LDO supply / poor match / frequency error
Switch to DCDC, VNA the match
Nothing received, but RSSI looks normal
LDRO off / IQ polarity mismatch / SF or BW mismatch
Compare ModulationParams on both ends
Random dropped packets
Crystal drift / timing violations / short preamble
Try preamble 8 → 12
BUSY stuck high
Malformed SPI command / chip not woken
Logic analyzer on the SPI bus
CRC errors on receive
Supply ripple / antenna mismatch
Check PA supply decoupling
Sensitivity short of spec
Poor noise figure / wrong LDRO / TCXO offset
Feed in a margin-level signal from a signal source
4.3 A Classic "Can't Get Range" Case Study
Recent debug session: 433 MHz, SF10, BW125, link dying at 800 m. The findings:
RSSI at the failure point was about −118 dBm against a theoretical SF10 sensitivity of −132 dBm — 14 dB of headroom, so sensitivity wasn't the problem.
On the SDR, the TX spectrum was 8 kHz off-frequency — a ±10 ppm XTAL drifting in cold weather.
Swapped in a TCXO: the link now held to 2.6 km, still at −130 dBm.
Moral of the story: for long-range links, a TCXO isn't optional.
5. Measured Power Numbers
Typical current draw at 3.3 V, SF9/BW125 (varies a bit board to board — treat these as orders of magnitude):
State
Current
STANDBY_RC
1.6 mA
RX continuous
5.3 mA
TX @ +14 dBm
46 mA
TX @ +22 dBm
118 mA
SLEEP (RTC retained)
1.6 µA
SLEEP (deep)
0.5 µA
For a battery node (2000 mAh Li-ion) sending a 30-byte packet every 30 s at SF9 — TX 46 mA × 40 ms + RX 5.3 mA × 120 ms, sleeping the rest — the math works out to roughly two years. In practice, sleep duty cycle and quiescent current decide everything; the MCU usually burns more than the radio.
6. Where the SX1262 Fits (and Doesn't)
Good fit:
Long-range (>1 km), low-power, small-payload IoT nodes;
Upgrading an aging SX1278 design (sensitivity and blocking both improve);
Battery-powered sensors targeting 1–5 year lifetimes.
Poor fit:
Large payloads (>100 B/frame — look at 2.4 GHz or cellular instead);
Low-latency real-time control (LoRa is slow by nature);
Dense networks (co-channel nodes will collide; you'll need ADR or LBT).