From 44d0774b39cb1dd8632b1e91fc390bf8ba434246 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 15 Aug 2025 19:22:36 +0200 Subject: [PATCH] ttwrplus: updated GPS driver --- platform/drivers/GPS/GPS_ttwrplus.c | 150 ----------------------- platform/drivers/GPS/gps_zephyr.c | 89 ++++++++++++++ platform/drivers/GPS/gps_zephyr.h | 59 +++++++++ platform/targets/ttwrplus/CMakeLists.txt | 3 +- platform/targets/ttwrplus/hwconfig.h | 2 + platform/targets/ttwrplus/platform.c | 27 ++++ 6 files changed, 179 insertions(+), 151 deletions(-) delete mode 100644 platform/drivers/GPS/GPS_ttwrplus.c create mode 100644 platform/drivers/GPS/gps_zephyr.c create mode 100644 platform/drivers/GPS/gps_zephyr.h diff --git a/platform/drivers/GPS/GPS_ttwrplus.c b/platform/drivers/GPS/GPS_ttwrplus.c deleted file mode 100644 index 92d55893..00000000 --- a/platform/drivers/GPS/GPS_ttwrplus.c +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2023 - 2025 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, see * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - - -#if DT_NODE_HAS_STATUS(DT_ALIAS(gps), okay) -#define UART_GPS_DEV_NODE DT_ALIAS(gps) -#else -#error "Please select the correct gps UART device" -#endif - -#define NMEA_MSG_SIZE 82 - -K_MSGQ_DEFINE(gps_uart_msgq, NMEA_MSG_SIZE, 10, 4); - -static const struct device *const gps_dev = DEVICE_DT_GET(UART_GPS_DEV_NODE); - -// receive buffer used in UART ISR callback -static char rx_buf[NMEA_MSG_SIZE]; -static uint16_t rx_buf_pos; - - -static void gps_serialCb(const struct device *dev, void *user_data) -{ - uint8_t c; - - if (uart_irq_update(gps_dev) == false) - return; - - if (uart_irq_rx_ready(gps_dev) == false) - return; - - // read until FIFO empty - while (uart_fifo_read(gps_dev, &c, 1) == 1) - { - if (c == '$' && rx_buf_pos > 0) - { - // terminate string - rx_buf[rx_buf_pos] = '\0'; - - // if queue is full, message is silently dropped - k_msgq_put(&gps_uart_msgq, &rx_buf, K_NO_WAIT); - - // reset the buffer (it was copied to the msgq) - rx_buf_pos = 0; - rx_buf[rx_buf_pos++] = '$'; - } - else if (rx_buf_pos < (sizeof(rx_buf) - 1)) - { - rx_buf[rx_buf_pos++] = c; - } - } -} - - -void gps_init(const uint16_t baud) -{ - int ret = 0; - - // Check if GPS UART is ready - if (device_is_ready(gps_dev) == false) - { - printk("UART device not found!\n"); - return; - } - - ret = uart_irq_callback_user_data_set(gps_dev, gps_serialCb, NULL); - if (ret < 0) - { - if (ret == -ENOTSUP) - { - printk("Interrupt-driven UART support not enabled\n"); - } - else if (ret == -ENOSYS) - { - printk("UART device does not support interrupt-driven API\n"); - } - else - { - printk("Error setting UART callback: %d\n", ret); - } - - return; - } - - uart_irq_rx_enable(gps_dev); -} - -void gps_terminate() -{ - gps_disable(); -} - -void gps_enable() -{ - pmu_setGPSPower(true); -} - -void gps_disable() -{ - pmu_setGPSPower(false); -} - -bool gps_detect(uint16_t timeout) -{ - return true; -} - -int gps_getNmeaSentence(char *buf, const size_t maxLength) -{ - k_msgq_get(&gps_uart_msgq, buf, K_FOREVER); - return 0; -} - -bool gps_nmeaSentenceReady() -{ - return k_msgq_num_used_get(&gps_uart_msgq) != 0; -} - -void gps_waitForNmeaSentence() -{ - while (k_msgq_num_used_get(&gps_uart_msgq) != 0) - { - sleepFor(0, 100); - } -} diff --git a/platform/drivers/GPS/gps_zephyr.c b/platform/drivers/GPS/gps_zephyr.c new file mode 100644 index 00000000..a0a2b7eb --- /dev/null +++ b/platform/drivers/GPS/gps_zephyr.c @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2023 - 2025 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include + +#if !DT_NODE_HAS_STATUS(DT_ALIAS(gps), okay) +#error "Please select the correct gps UART device" +#endif + +static const struct device *const gpsDev = DEVICE_DT_GET(DT_ALIAS(gps)); +static struct nmeaRbuf ringBuf; + +static void uartRxCallback(const struct device *dev, void *user_data) +{ + uint8_t c; + + if(uart_irq_update(dev) == false) + return; + + if(uart_irq_rx_ready(dev) == false) + return; + + // read until FIFO empty + while(uart_fifo_read(dev, &c, 1) == 1) + nmeaRbuf_putChar(&ringBuf, c); +} + +void gpsZephyr_init() +{ + int ret = 0; + + // Check if GPS UART is ready + if(device_is_ready(gpsDev) == false) { + printk("UART device not found!\n"); + return; + } + + ret = uart_irq_callback_user_data_set(gpsDev, uartRxCallback, NULL); + if(ret < 0) { + switch(ret) { + case -ENOTSUP: + printk("Interrupt-driven UART support not enabled\n"); + break; + + case -ENOSYS: + printk("UART device does not support interrupt-driven API\n"); + break; + + default: + printk("Error setting UART callback: %d\n", ret); + break; + } + } + + nmeaRbuf_reset(&ringBuf); + uart_irq_rx_enable(gpsDev); +} + +void gpsZephyr_terminate() +{ + uart_irq_rx_disable(gpsDev); +} + +int gpsZephyr_getNmeaSentence(void *priv, char *buf, const size_t maxLength) +{ + (void) priv; + + return nmeaRbuf_getSentence(&ringBuf, buf, maxLength); +} diff --git a/platform/drivers/GPS/gps_zephyr.h b/platform/drivers/GPS/gps_zephyr.h new file mode 100644 index 00000000..ffa6ebeb --- /dev/null +++ b/platform/drivers/GPS/gps_zephyr.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2021 - 2025 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef GPS_ZEPHYR_H +#define GPS_ZEPHYR_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialise the GPS driver. + * This function does not turn on the GPS module. + */ +void gpsZephyr_init(); + +/** + * Terminate the GPS driver. + */ +void gpsZephyr_terminate(); + +/** + * Retrieve a NMEA sentence from the GPS. + * If the sentence is longer than the maximum size of the destination buffer, + * the characters not written in the destination are lost. + * + * @param priv: unused parameter, for function signature compatibility. + * @param buf: pointer to NMEA sentence destination buffer. + * @param maxLen: maximum acceptable size for the destination buffer. + * @return the length of the extracted sentence or -1 if the sentence is longer + * than the maximum allowed size. If the ring buffer is empty, zero is returned. + */ +int gpsZephyr_getNmeaSentence(void *priv, char *buf, const size_t maxLength); + +#ifdef __cplusplus +} +#endif + +#endif /* GPS_STM32_H */ diff --git a/platform/targets/ttwrplus/CMakeLists.txt b/platform/targets/ttwrplus/CMakeLists.txt index 845cd7e5..125259f9 100644 --- a/platform/targets/ttwrplus/CMakeLists.txt +++ b/platform/targets/ttwrplus/CMakeLists.txt @@ -17,7 +17,8 @@ target_sources(app ${OPENRTX_ROOT}/platform/drivers/baseband/radio_ttwrplus.cpp ${OPENRTX_ROOT}/platform/drivers/baseband/AT1846S_SA8x8.cpp ${OPENRTX_ROOT}/platform/drivers/baseband/SA8x8.c - ${OPENRTX_ROOT}/platform/drivers/GPS/GPS_ttwrplus.c + ${OPENRTX_ROOT}/platform/drivers/GPS/gps_zephyr.c + ${OPENRTX_ROOT}/platform/drivers/GPS/nmea_rbuf.c ${OPENRTX_ROOT}/platform/drivers/audio/audio_ttwrplus.c ${OPENRTX_ROOT}/platform/drivers/NVM/flash_zephyr.c ${OPENRTX_ROOT}/platform/drivers/NVM/nvmem_ttwrplus.c diff --git a/platform/targets/ttwrplus/hwconfig.h b/platform/targets/ttwrplus/hwconfig.h index 3a678b63..40f52f56 100644 --- a/platform/targets/ttwrplus/hwconfig.h +++ b/platform/targets/ttwrplus/hwconfig.h @@ -29,7 +29,9 @@ #define CONFIG_SCREEN_WIDTH DT_PROP(DISPLAY, width) #define CONFIG_SCREEN_HEIGHT DT_PROP(DISPLAY, height) #define CONFIG_PIX_FMT_BW + #define CONFIG_GPS +#define CONFIG_NMEA_RBUF_SIZE 128 #define CONFIG_BAT_LIPO #define CONFIG_BAT_NCELLS 1 diff --git a/platform/targets/ttwrplus/platform.c b/platform/targets/ttwrplus/platform.c index ff930fdf..c1901eee 100644 --- a/platform/targets/ttwrplus/platform.c +++ b/platform/targets/ttwrplus/platform.c @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include @@ -52,6 +54,24 @@ static hwInfo_t hwInfo = // RGB led color data static struct led_rgb led_color = {0}; +static void gpsEnable(void *priv) +{ + (void) priv; + pmu_setGPSPower(true); +} + +static void gpsDisable(void *priv) +{ + (void) priv; + pmu_setGPSPower(false); +} + +static const struct gpsDevice gps = +{ + .enable = gpsEnable, + .disable = gpsDisable, + .getSentence = gpsZephyr_getNmeaSentence +}; void platform_init() { @@ -107,6 +127,7 @@ void platform_init() void platform_terminate() { + gpsZephyr_terminate(); pmu_terminate(); } @@ -219,3 +240,9 @@ const hwInfo_t *platform_getHwInfo() return &hwInfo; } +const struct gpsDevice *platform_initGps() +{ + gpsZephyr_init(); + + return &gps; +}