GPS
The GPS subsystem gives the node position, speed, and heading, keeps the real-time clock honest, and feeds RTK corrections back to the receiver for centimetre-level accuracy. It's two threads in gps_app.c plus the gps_driver and gps_sender_driver.
Receive path
- The receiver streams NMEA over UART1. DMA lands bytes in
GPS_DMA_BUF_SIZEchunks and the ISR pushes them into a ring buffer, then posts the RX semaphore. - The GPS thread wakes, drains the ring buffer completely (in 256-byte chunks), and feeds each chunk to
lwgps_process(). - On a valid, updated fix it calls
telemetry_ingest_gps_lwgps()to fold lat/lon/alt/speed/course/yaw intotelemetry_data(under the GPS seqlock domain), then notifies the lap thread withlap_app_notify_gps_update().
Drain-to-empty
The thread loops until the ring buffer is empty, not just once per wake. If several UART events pile up before the thread is scheduled, it still catches up in one pass instead of falling behind.
RTC sync
The first time a valid fix arrives (rtc_synked_from_gps == 0), the thread calls rtc_update_from_gps() to set the MCU's real-time clock from GPS time. That's where the time_unix column in every CSV line comes from. See Data Format.
RTCM sender path (RTK corrections)
For RTK you have to send correction data to the receiver. Corrections arrive from the NTRIP client and are queued in the RTCM ring buffer.
The GPS Sender thread wakes on the RTCM semaphore, pulls bytes out in GPS_SENDER_TX_DMA_BUF_SIZE chunks, and transmits each chunk over DMA. It waits for a transmit-done semaphore with a timeout (GPS_SENDER_TX_TIMEOUT_TICKS); if the transmit stalls it aborts and retries rather than blocking forever.
Angle handling
telemetry_ingest_gps_lwgps() stores both radians and degrees for course and yaw. Angles are normalized (wrapped) before storage so downstream consumers get a consistent range. The CAN re-broadcast (see CAN) and the lap detector (see Lap Tracking) both rely on the radian heading being clean.
Exposed resources
gps_app owns the ring buffers and semaphores and exposes them so the drivers and NTRIP client can share them:
| Accessor | Returns |
|---|---|
gps_app_get_rb() | GPS RX ring buffer |
gps_app_get_rx_semaphore() | GPS RX semaphore |
gps_app_get_rtcm_rb() | RTCM correction ring buffer |
gps_app_get_rtcm_semaphore() | RTCM ready semaphore |
