1 /*
2 * Copyright (c) 2025 Croxel Inc.
3 * Copyright (c) 2025 CogniPilot Foundation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/kernel.h>
9 #include <zephyr/init.h>
10 #include <zephyr/sys/check.h>
11 #include <zephyr/sys/ring_buffer.h>
12 #include <zephyr/drivers/uart.h>
13 #include <zephyr/gnss/rtk/decoder.h>
14 #include <zephyr/gnss/rtk/rtk_publish.h>
15 #include <zephyr/gnss/rtk/rtk.h>
16
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(rtk_serial, CONFIG_GNSS_RTK_LOG_LEVEL);
19
20 static const struct device *rtk_serial_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_rtk_serial));
21 static struct ring_buf process_ringbuf;
22 static uint8_t process_buf[2048];
23
gnss_rtk_process_work_handler(struct k_work * work)24 static void gnss_rtk_process_work_handler(struct k_work *work)
25 {
26 static uint8_t work_buf[2048];
27 uint32_t len = ring_buf_get(&process_ringbuf, work_buf, sizeof(work_buf));
28 uint32_t offset = 0;
29
30 ARG_UNUSED(work);
31
32 do {
33 uint8_t *frame;
34 size_t frame_len;
35 int err;
36
37 err = gnss_rtk_decoder_frame_get(work_buf + offset, len - offset,
38 &frame, &frame_len);
39 if (err != 0) {
40 return;
41 }
42
43 LOG_HEXDUMP_DBG(frame, frame_len, "Frame received");
44
45 /* Publish results */
46 struct gnss_rtk_data rtk_data = {
47 .data = frame,
48 .len = frame_len,
49 };
50
51 gnss_rtk_publish_data(&rtk_data);
52 offset += frame_len;
53
54 } while (len > offset);
55 }
56
57 static K_WORK_DELAYABLE_DEFINE(gnss_rtk_process_work, gnss_rtk_process_work_handler);
58
rtk_uart_isr_callback(const struct device * dev,void * user_data)59 static void rtk_uart_isr_callback(const struct device *dev, void *user_data)
60 {
61 ARG_UNUSED(user_data);
62
63 (void)uart_irq_update(dev);
64
65 if (uart_irq_rx_ready(dev)) {
66 int ret;
67
68 do {
69 char c;
70
71 ret = uart_fifo_read(dev, &c, 1);
72 if (ret > 0) {
73 ret = ring_buf_put(&process_ringbuf, &c, 1);
74 }
75 } while (ret > 0);
76
77 /** Since messages come through in a burst at a period
78 * (e.g: 1 Hz), wait until all messages are received before
79 * processing.
80 */
81 (void)k_work_reschedule(&gnss_rtk_process_work, K_MSEC(10));
82 }
83 }
84
rtk_serial_client_init(void)85 static int rtk_serial_client_init(void)
86 {
87 int err;
88
89 ring_buf_init(&process_ringbuf, ARRAY_SIZE(process_buf), process_buf);
90
91 err = uart_irq_callback_user_data_set(rtk_serial_dev, rtk_uart_isr_callback, NULL);
92 if (err < 0) {
93 return err;
94 }
95
96 uart_irq_rx_enable(rtk_serial_dev);
97
98 return 0;
99 }
100
101 SYS_INIT(rtk_serial_client_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
102