diff --git a/platform/drivers/GPS/gps_stm32.cpp b/platform/drivers/GPS/gps_stm32.cpp new file mode 100644 index 00000000..e8096318 --- /dev/null +++ b/platform/drivers/GPS/gps_stm32.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * 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 * + ***************************************************************************/ + +#include +#include +#include "nmea_rbuf.h" +#include "gps_stm32.h" + +#if defined(CONFIG_GPS_STM32_USART1) + #define PORT USART1 + #define IRQn USART1_IRQn + #define IRQHandler USART1_IRQHandler + #define CLK_EN() (RCC->APB2ENR |= RCC_APB2ENR_USART1EN); + #define CLK_DIS() (RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN); +#elif defined(CONFIG_GPS_STM32_USART2) + #define PORT USART2 + #define IRQn USART2_IRQn + #define IRQHandler USART2_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_USART2EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN); +#elif defined(CONFIG_GPS_STM32_USART3) + #define PORT USART3 + #define IRQn USART3_IRQn + #define IRQHandler USART3_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_USART3EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN); +#elif defined(CONFIG_GPS_STM32_UART4) + #define PORT UART4 + #define IRQn UART4_IRQn + #define IRQHandler UART4_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_UART4EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_UART4EN); +#elif defined(CONFIG_GPS_STM32_UART5) + #define PORT UART5 + #define IRQn UART5_IRQn + #define IRQHandler UART5_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_UART5EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_UART5EN); +#elif defined(CONFIG_GPS_STM32_USART6) + #define PORT USART6 + #define IRQn USART6_IRQn + #define IRQHandler USART6_IRQHandler + #define CLK_EN() (RCC->APB2ENR |= RCC_APB2ENR_USART6EN); + #define CLK_DIS() (RCC->APB2ENR &= ~RCC_APB2ENR_USART6EN); +#elif defined(CONFIG_GPS_STM32_UART7) + #define PORT UART7 + #define IRQn UART7_IRQn + #define IRQHandler UART7_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_UART7EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_UART7EN); +#elif defined(CONFIG_GPS_STM32_UART8) + #define PORT UART8 + #define IRQn UART8_IRQn + #define IRQHandler UART8_IRQHandler + #define CLK_EN() (RCC->APB1ENR |= RCC_APB1ENR_UART8EN); + #define CLK_DIS() (RCC->APB1ENR &= ~RCC_APB1ENR_UART8EN); +#else + #error No USART defined! +#endif + +static nmeaRbuf nmea; + +void IRQHandler() +{ + #if defined(STM32H743xx) + if(PORT->ISR & USART_ISR_RXNE_RXFNE) { + PORT->ISR = 0; + nmeaRbuf_putChar(&nmea, PORT->RDR); + } + #else + if(PORT->SR & USART_SR_RXNE) { + PORT->SR = 0; + nmeaRbuf_putChar(&nmea, PORT->DR); + } + #endif +} + +void gpsStm32_init(const uint16_t baud) +{ + CLK_EN(); + __DSB(); + + uint32_t quot = rcc_getPeriphClock(PORT); + quot = (2 * quot) / baud; + + PORT->BRR = (quot / 2) + (quot & 1); + PORT->CR3 |= USART_CR3_ONEBIT; + PORT->CR1 = USART_CR1_RE + | USART_CR1_RXNEIE; + + NVIC_SetPriority(IRQn, 14); + + nmeaRbuf_reset(&nmea); +} + +void gpsStm32_terminate() +{ + gpsStm32_disable(NULL); + CLK_DIS(); +} + +void gpsStm32_enable(void *priv) +{ + (void) priv; + + PORT->CR1 |= USART_CR1_UE; + + NVIC_ClearPendingIRQ(IRQn); + NVIC_EnableIRQ(IRQn); +} + +void gpsStm32_disable(void *priv) +{ + (void) priv; + + PORT->CR1 &= ~USART_CR1_UE; + NVIC_DisableIRQ(USART6_IRQn); +} + +int gpsStm32_getNmeaSentence(void *priv, char *buf, const size_t maxLength) +{ + (void) priv; + + return nmeaRbuf_getSentence(&nmea, buf, maxLength); +} diff --git a/platform/drivers/GPS/gps_stm32.h b/platform/drivers/GPS/gps_stm32.h new file mode 100644 index 00000000..f6a0554f --- /dev/null +++ b/platform/drivers/GPS/gps_stm32.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * 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_STM32_H +#define GPS_STM32_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialise the GPS driver. + * This function does not turn on the GPS module. + * + * @param baud: baud rate of GPS serial interface. + */ +void gpsStm32_init(const uint16_t baud); + +/** + * Shut down the GPS module and terminate the GPS driver. + */ +void gpsStm32_terminate(); + +/** + * Turn on the GPS module. + * + * @param priv: unused parameter, for function signature compatibility. + */ +void gpsStm32_enable(void *priv); + +/** + * Turn off GPS module. + * + * @param priv: unused parameter, for function signature compatibility. + */ +void gpsStm32_disable(void *priv); + +/** + * 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 gpsStm32_getNmeaSentence(void *priv, char *buf, const size_t maxLength); + +#ifdef __cplusplus +} +#endif + +#endif /* GPS_STM32_H */