Hi all,
I’m evaluating the High-Precision GNSS-TAA-KIT EVB (GD32 MCU + LG290P + 4G module) for use as a
standalone NTRIP rover ? no host PC, the on-board modem pulls RTCM from a caster, the MCU
forwards it to the LG290P over UART3, and the module computes an RTK fix. I can’t get it to RTK, and
I’ve traced it to three separate issues in the OpenEVB firmware/example code. Posting the full
diagnosis in case others have hit the same thing, and to ask Quectel for a fix.
Key point up front: the LG290P itself is fine ? when I feed the exact same RTCM to the module
directly over its USB port, it goes to RTK fix within seconds. The problems are all in the
MCU/NTRIP firmware path.
Repo for reference: GitHub - quectel-open-source/OpenEVB: OPENEVB is an innovative evaluation platform built upon the GD32F4 series, engineered to significantly expedite the development process involving Quectel GNSS modules such as the LCx9H and LCx6G. This platform serves as a comprehensive solution for developers working on GNSS - related projects. · GitHub
Module FW: LG290P03AANR01A04S
TL;DR
| # | Issue | Effect |
|---|---|---|
| 1 | NTRIP client sends a malformed (v1/v2 hybrid) HTTP request | 403 Forbidden from standard BKG casters |
| 2 | MCU UART3 TX never reaches the LG290P | RTCM “sent” but never applied ? stays GPS-only |
| 3 | UART3 baud hardcoded to 115200, overriding saved 460800 | Garbled data; resets every boot |
Bugs 1 and 2 are both hard blockers for standalone RTK.
Bug 1 ? NTRIP client sends an invalid HTTP request ? 403
quectel/example/src/example_ntrip_client.c:128?133 builds the request as:
GET /<mountpoint> HTTP/1.0\r\n
User-Agent: <ua>\r\n
Host: <host>:<port>\r\n
Authorization: Basic <base64>\r\n
\r\n
This is neither valid NTRIP v1 nor v2:
- NTRIP v1 ?
HTTP/1.0, and noHostheader. - NTRIP v2 ?
HTTP/1.1, withHostandNtrip-Version: Ntrip/2.0.
The EVB sends HTTP/1.0 with a Host header but without Ntrip-Version. A
BKG Caster 2.0.36 (PositioNZ-RT and most national CORS networks run this) sees the Host
header, treats the request as v2, finds no Ntrip-Version, and rejects it:
HTTP/1.1 403 Forbidden
Server: NTRIP BKG Caster 2.0.36/2.0
The request is built inside the precompiled libqntrip.lib, so it can’t be corrected in
application code.
Confirmed it’s the request format, not credentials/account:
- A standard Python NTRIP v2 client (
HTTP/1.1+Ntrip-Version: Ntrip/2.0) using the same
credentials and mountpoint connects fine to the same caster (ICY 200 OK/ accepted, RTCM
streaming). - The EVB authenticates fine against a non-BKG caster (rtk2go.com / SNIP) ?
SOURCETABLE 200 OK.
So modem, TLS/TCP and credentials all work; only strict BKG casters reject the request.
Bug 2 ? MCU UART3 TX doesn’t reach the LG290P ? corrections never applied
The MCU forwards RTCM to the module over UART3 (GNSS COM1, pins PA0/PA1, ql_uart.c:489?496):
// example_ntrip_client.c
:257 QL_LOG_I("Receiving rtcm & sending GGA...");
:268 Ql_Uart_Write(UART3, NtripClientBuffer, length, 0);
On the debug console the MCU receives ~1.3 kB RTCM every second and calls Ql_Uart_Write(UART3, ?), and it reads NMEA back from the LG290P on UART3 (RX works). But GGA fix quality stays at
1 (GPS-only) forever ? corrections are never applied. Sending a PQTM command out UART3 from the
console gets no response from the module.
Isolation:
- Same RTCM fed to the LG290P over its USB interface ? RTK fix in seconds (module + RTCM are good).
- MCU reads NMEA on UART3 but writes don’t reach the module ? the UART3 TX direction is
the fault.
Ql_Uart_Write() uses a fire-and-forget DMA with timeout=0 (ql_uart.c:825?867) ? it starts the
DMA and returns immediately without waiting for completion, which seems worth checking as a cause.
Bug 3 ? UART3 baud hardcoded to 115200, overriding saved 460800
The LG290P defaults to 460800 on GNSS COM1, and the EVB’s own param defaults match. But the
example re-inits UART3 at 115200:
// example_ntrip_client.c:387
Ql_Uart_Init("GNSS COM1", UART3, 115200, 8192, 2048);
Console then shows:
UART3 BaudNow 115200 BaudCfg 460800 - GNSS COM1
So the MCU writes RTCM at 115200 while the module listens at 460800 ? every byte is garbage.
uart -c 3 -b 460800 fixes it for the session but the hardcoded Ql_Uart_Init() resets it to
115200 on every reboot, so it can’t be made persistent for standalone use. (Moot while Bug 2
stands, but would corrupt data the instant TX is fixed.)
Questions for Quectel
- Bug 1: can the NTRIP client be updated to send a spec-compliant request ? proper v2
(HTTP/1.1+Host+Ntrip-Version: Ntrip/2.0) or clean v1 (noHost)? This affects every
BKG-caster CORS network, not just PositioNZ-RT. - Bug 2: any known issue with MCU?LG290P writes on UART3 on this EVB (DMA TX completion, or
board routing)? This is the hard blocker ? even working around Bug 1 with an external relay, the
module never gets corrections. - Bug 3: can UART3 be initialized at 460800 (or read from saved config) instead of hardcoded
115200? - Has anyone got the GNSS-TAA-KIT doing standalone NTRIP RTK against a BKG caster? Keen to know
if there’s a firmware build or config that works.
Happy to run debug firmware and share full console logs / packet captures.
Environment
- EVB: High-Precision GNSS-TAA-KIT (GD32 MCU + LG290P + 4G module)
- Module FW:
LG290P03AANR01A04S - Source: OpenEVB ? GitHub - quectel-open-source/OpenEVB: OPENEVB is an innovative evaluation platform built upon the GD32F4 series, engineered to significantly expedite the development process involving Quectel GNSS modules such as the LCx9H and LCx6G. This platform serves as a comprehensive solution for developers working on GNSS - related projects. · GitHub
- NTRIP lib:
quectel/component/quecrtk/libqntrip.lib(precompiled) - Reference caster: PositioNZ-RT, NTRIP BKG Caster 2.0.36/2.0
Thanks!



