# HG changeset patch # User Ideenmodellierer # Date 1730663585 -3600 # Node ID 7c996354b8acdffe76cc05bd28d0c46080102b22 # Parent eb4109d7d1e9ef88179adcc10774565eb7c055dc Moved UART6 into a separate unit: UART6 connects internal devices. As a first step the existing code sections have been moved into a new unit. As well the code of the external GNSS sensor has been copied into this unit as starting point for the further development. Later the internal part can be integrated into the common uart (code cleanup). diff -r eb4109d7d1e9 -r 7c996354b8ac Common/Inc/configuration.h --- a/Common/Inc/configuration.h Sun Nov 03 18:19:51 2024 +0100 +++ b/Common/Inc/configuration.h Sun Nov 03 20:53:05 2024 +0100 @@ -73,7 +73,7 @@ #define ENABLE_CO2_SUPPORT /* Enable to have GPS sensor functionality available */ -/* #define ENABLE_GNSS_SUPPORT */ +#define ENABLE_GNSS_SUPPORT /* Enable to have Sentinel rebreather interface available */ /* #define ENABLE_SENTINEL_MODE */ @@ -91,6 +91,6 @@ #define ENABLE_FAST_COMM /* Enable to have position sensor support active */ -/* #define ENABLE_GNSS */ +#define ENABLE_GPIO_V2 #endif diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Inc/uart.h --- a/Small_CPU/Inc/uart.h Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Inc/uart.h Sun Nov 03 20:53:05 2024 +0100 @@ -29,7 +29,7 @@ #define BUFFER_NODATA_HIGH (0xA5) -UART_HandleTypeDef huart1, huart6; +UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void); void MX_USART1_UART_DeInit(void); @@ -59,7 +59,7 @@ void UART_setTargetChannel(uint8_t channel); void UART_MUX_SelectAddress(uint8_t muxAddress); void UART_SendCmdString(uint8_t *cmdString); -void UART_SendCmdUbx(uint8_t *cmd, uint8_t len); +void UART_SendCmdUbx(const uint8_t *cmd, uint8_t len); void UART_ReadData(uint8_t sensorType); void UART_WriteData(void); void UART_FlushRxBuffer(void); diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Inc/uart_Internal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Small_CPU/Inc/uart_Internal.h Sun Nov 03 20:53:05 2024 +0100 @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * @file uartInternal.h + * @author heinrichs weikamp gmbh + * @version V0.0.1 + * @date 03-November-2024 + * @brief button control + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 heinrichs weikamp

+ * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef UARTINTERNAL_H +#define UARTINTERNAL_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32f4xx_hal.h" + + +#define BUFFER_NODATA_LOW (0x15) /* The read function needs a signiture which indicates that no data for processing is available.*/ +#define BUFFER_NODATA_HIGH (0xA5) + + +UART_HandleTypeDef huart6; + +void MX_USART6_UART_Init(void); +void MX_USART6_DMA_Init(void); +void MX_USART6_UART_DeInit(void); +void GNSS_IO_init(void); + +void UART6_StartDMA_Receiption(void); + +void UART_clearRx6Buffer(void); +void UART6_SendCmdUbx(const uint8_t *cmd, uint8_t len); +void UART6_ReadData(void); +void UART6_WriteData(void); +void UART6_Gnss_ProcessData(uint8_t data); + +#ifdef __cplusplus +} +#endif + +#endif /* UARTINTERNAL_H */ + +/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/baseCPU2.c --- a/Small_CPU/Src/baseCPU2.c Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Src/baseCPU2.c Sun Nov 03 20:53:05 2024 +0100 @@ -143,6 +143,7 @@ #include "tm_stm32f4_otp.h" #include "externalInterface.h" #include "uart.h" +#include "uart_Internal.h" #include "GNSS.h" @@ -235,7 +236,7 @@ static void GPIO_Power_MainCPU_Init(void); static void GPIO_Power_MainCPU_ON(void); static void GPIO_Power_MainCPU_OFF(void); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 static void GPIO_LED_RED_OFF(void); static void GPIO_LED_RED_ON(void); static void GPIO_LED_GREEN_OFF(void); @@ -412,24 +413,24 @@ if (global.mode == MODE_BOOT) { GPIO_Power_MainCPU_OFF(); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 GPIO_LED_GREEN_ON(); #endif HAL_Delay(100); // for GPIO_Power_MainCPU_ON(); GPIO_Power_MainCPU_ON(); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 GPIO_LED_GREEN_OFF(); GPIO_LED_RED_ON(); GPIO_VIBRATION_ON(); #endif HAL_Delay(100); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 GPIO_LED_RED_OFF(); GPIO_VIBRATION_OFF(); #endif } -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 GPIO_LED_RED_OFF(); GPIO_LED_GREEN_OFF(); GPIO_VIBRATION_OFF(); @@ -440,7 +441,7 @@ SPI_Start_single_TxRx_with_Master(); /* be prepared for the first data exchange */ Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 // GNSS tests GNSS_IO_init(); GPIO_GPS_ON(); @@ -449,16 +450,6 @@ GNSS_Init(&GNSS_Handle, &huart6); #endif -#if 0 - HAL_Delay(1000); - GNSS_LoadConfig(&GNSS_Handle); - HAL_Delay(250); - GNSS_GetUniqID(&GNSS_Handle); - GNSS_ParseBuffer(&GNSS_Handle); - HAL_Delay(250); - GNSS_GetPVTData(&GNSS_Handle); - GNSS_ParseBuffer(&GNSS_Handle); -#endif /* * Demo code from SimpleMethod * called 1/second @@ -899,7 +890,7 @@ HAL_GPIO_WritePin( GPIOC, MAINCPU_CONTROL_PIN, GPIO_PIN_SET); } -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 static void GPIO_LED_GREEN_ON(void) { HAL_GPIO_WritePin( GPIOA, LED_CONTROL_PIN_GREEN, GPIO_PIN_RESET); } @@ -1045,7 +1036,7 @@ HAL_GPIO_Init( GPIOH, &GPIO_InitStruct); GPIO_Power_MainCPU_OFF(); -#ifdef ENABLE_GNSS +#ifdef ENABLE_GPIO_V2 GPIO_LED_GREEN_OFF(); GPIO_LED_RED_OFF(); GPIO_VIBRATION_OFF(); diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/scheduler.c --- a/Small_CPU/Src/scheduler.c Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Src/scheduler.c Sun Nov 03 20:53:05 2024 +0100 @@ -827,6 +827,9 @@ } externalInterface_HandleUART(); +#ifdef ENABLE_GPIO_V2 + UART6_HandleUART(); +#endif /* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */ if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/stm32f4xx_it_v3.c --- a/Small_CPU/Src/stm32f4xx_it_v3.c Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Src/stm32f4xx_it_v3.c Sun Nov 03 20:53:05 2024 +0100 @@ -61,7 +61,9 @@ extern UART_HandleTypeDef huart1; extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_tx; - +extern UART_HandleTypeDef huart6; +extern DMA_HandleTypeDef hdma_usart6_rx; +extern DMA_HandleTypeDef hdma_usart6_tx; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ @@ -247,6 +249,17 @@ HAL_DMA_IRQHandler(&hdma_usart1_tx); } +#ifdef ENABLE_GPIO_V2 +void DMA2_Stream1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_usart6_rx); +} + +void DMA2_Stream6_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_usart6_tx); +} +#endif /******************************************************************************/ /* STM32F4xx Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ @@ -314,6 +327,13 @@ HAL_UART_IRQHandler(&huart1); } +#ifdef ENABLE_GPIO_V2 +void USART6_IRQHandler(void) +{ + HAL_UART_IRQHandler(&huart6); +} +#endif + /** * @brief This function handles PPP interrupt request. * @param None diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/uart.c --- a/Small_CPU/Src/uart.c Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Src/uart.c Sun Nov 03 20:53:05 2024 +0100 @@ -28,6 +28,11 @@ #include "data_exchange.h" #include /* memset */ +#ifdef ENABLE_GPIO_V2 +extern UART_HandleTypeDef huart6; +extern void UART6_RxCpltCallback(UART_HandleTypeDef *huart); +extern void UART6_TxCpltCallback(UART_HandleTypeDef *huart); +#endif /* Private variables ---------------------------------------------------------*/ @@ -38,16 +43,13 @@ -DMA_HandleTypeDef hdma_usart1_rx, hdma_usart1_tx, hdma_usart6_rx, hdma_usart6_tx; +DMA_HandleTypeDef hdma_usart1_rx, hdma_usart1_tx; uint8_t rxBuffer[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ uint8_t txBuffer[CHUNK_SIZE]; /* tx uses less bytes */ uint8_t txBufferQue[TX_BUF_SIZE]; /* In MUX mode command may be send shortly after each other => allow q 1 entry que */ uint8_t txBufferQueLen; -uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ -uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ - static uint8_t rxWriteIndex; /* Index of the data item which is analysed */ static uint8_t rxReadIndex; /* Index at which new data is stared */ static uint8_t lastCmdIndex; /* Index of last command which has not been completely received */ @@ -154,102 +156,6 @@ HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn); } - -void GNSS_IO_init() { - - GPIO_InitTypeDef GPIO_InitStruct = { 0 }; - /* Peripheral clock enable */ - __HAL_RCC_USART6_CLK_ENABLE() - ; - - __HAL_RCC_GPIOA_CLK_ENABLE() - ; - /**USART6 GPIO Configuration - PA11 ------> USART6_TX - PA12 ------> USART6_RX - */ - GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FAST; - GPIO_InitStruct.Alternate = GPIO_AF8_USART6; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* USART6 DMA Init */ - /* USART6_RX Init */ - hdma_usart6_rx.Instance = DMA2_Stream1; - hdma_usart6_rx.Init.Channel = DMA_CHANNEL_5; - hdma_usart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_usart6_rx.Init.PeriphInc = DMA_PINC_DISABLE; - hdma_usart6_rx.Init.MemInc = DMA_MINC_ENABLE; - hdma_usart6_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_usart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_usart6_rx.Init.Mode = DMA_NORMAL; - hdma_usart6_rx.Init.Priority = DMA_PRIORITY_LOW; - hdma_usart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - HAL_DMA_Init(&hdma_usart6_rx); - - __HAL_LINKDMA(&huart6, hdmarx, hdma_usart6_rx); - - /* USART6_TX Init */ - hdma_usart6_tx.Instance = DMA2_Stream6; - hdma_usart6_tx.Init.Channel = DMA_CHANNEL_6; - hdma_usart6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; - hdma_usart6_tx.Init.PeriphInc = DMA_PINC_DISABLE; - hdma_usart6_tx.Init.MemInc = DMA_MINC_ENABLE; - hdma_usart6_tx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_usart6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_usart6_tx.Init.Mode = DMA_NORMAL; - hdma_usart6_tx.Init.Priority = DMA_PRIORITY_LOW; - hdma_usart6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - HAL_DMA_Init(&hdma_usart6_tx); - - __HAL_LINKDMA(&huart6, hdmatx, hdma_usart6_tx); - - /* USART6 interrupt Init */ - HAL_NVIC_SetPriority(USART6_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(USART6_IRQn); - - MX_USART6_DMA_Init(); - -} - -void MX_USART6_DMA_Init() { - /* DMA controller clock enable */ - __HAL_RCC_DMA2_CLK_ENABLE(); - - /* DMA interrupt init */ - /* DMA2_Stream2_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); - /* DMA2_Stream6_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn); -} - - -void MX_USART6_UART_DeInit(void) -{ - HAL_DMA_Abort(&hdma_usart6_rx); - HAL_DMA_DeInit(&hdma_usart6_rx); - HAL_DMA_Abort(&hdma_usart6_tx); - HAL_DMA_DeInit(&hdma_usart6_tx); - HAL_UART_DeInit(&huart6); - HAL_UART_DeInit(&huart6); -} - -void MX_USART6_UART_Init(void) { - huart6.Instance = USART6; - huart6.Init.BaudRate = 9600; - huart6.Init.WordLength = UART_WORDLENGTH_8B; - huart6.Init.StopBits = UART_STOPBITS_1; - huart6.Init.Parity = UART_PARITY_NONE; - huart6.Init.Mode = UART_MODE_TX_RX; - huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart6.Init.OverSampling = UART_OVERSAMPLING_16; - HAL_UART_Init(&huart6); -} - void UART_MUX_SelectAddress(uint8_t muxAddress) { uint8_t indexstr[4]; @@ -309,7 +215,7 @@ } } -void UART_SendCmdUbx(uint8_t *cmd, uint8_t len) +void UART_SendCmdUbx(const uint8_t *cmd, uint8_t len) { if(len < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */ { @@ -395,6 +301,12 @@ } UART_StartDMA_Receiption(); } +#ifdef ENABLE_GPIO_V2 + if(huart == &huart6) + { + UART6_RxCpltCallback(huart); + } +#endif } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { @@ -410,6 +322,12 @@ txBufferQueLen = 0; } } +#ifdef ENABLE_GPIO_V2 + if(huart == &huart6) + { + UART6_TxCpltCallback(huart); + } +#endif } uint8_t isEndIndication(uint8_t index) @@ -545,8 +463,6 @@ { uint8_t active = 1; - uint8_t ComState = externalInterface_GetSensorState(sensorId + EXT_INTERFACE_MUX_OFFSET); - if(time_elapsed_ms(LastCmdRequestTick, HAL_GetTick()) > 300) /* UART activity should be inactive 300ms after last command */ { active = 0; diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/uartProtocol_GNSS.c --- a/Small_CPU/Src/uartProtocol_GNSS.c Sun Nov 03 18:19:51 2024 +0100 +++ b/Small_CPU/Src/uartProtocol_GNSS.c Sun Nov 03 20:53:05 2024 +0100 @@ -62,7 +62,7 @@ void uartGnss_SendCmd(uint8_t GnssCmd) { - uint8_t* pData; + const uint8_t* pData; uint8_t txLength = 0; switch (GnssCmd) diff -r eb4109d7d1e9 -r 7c996354b8ac Small_CPU/Src/uart_Internal.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Small_CPU/Src/uart_Internal.c Sun Nov 03 20:53:05 2024 +0100 @@ -0,0 +1,542 @@ +/** + ****************************************************************************** + * @file uart_Internal.c + * @author heinrichs weikamp gmbh + * @version V0.0.1 + * @date 03-November-2044 + * @brief Control functions for devices connected to the internal UART + * + @verbatim + ============================================================================== + ##### How to use ##### + ============================================================================== + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 heinrichs weikamp

+ * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "uart.h" +#include "uart_Internal.h" +#include "uartProtocol_GNSS.h" +#include "GNSS.h" +#include "externalInterface.h" +#include "data_exchange.h" +#include /* memset */ + + +static uint8_t isEndIndication6(uint8_t index); +static uint8_t gnssState = UART_GNSS_INIT; + +/* Private variables ---------------------------------------------------------*/ + + +#define TX_BUF_SIZE (40u) /* max length for commands */ +#define CHUNK_SIZE (25u) /* the DMA will handle chunk size transfers */ +#define CHUNKS_PER_BUFFER (6u) + +#define REQUEST_INT_SENSOR_MS (1500) /* Minimum time interval for cyclic sensor data requests per sensor (UART mux) */ +#define COMMAND_TX_DELAY (30u) /* The time the sensor needs to recover from a invalid command request */ +#define TIMEOUT_SENSOR_ANSWER (300) /* Time till a request is repeated if no answer was received */ + + +static receiveStateGnss_t rxState = GNSSRX_READY; +static uint8_t GnssConnected = 0; /* Binary indicator if a sensor is connected or not */ + +static uint8_t writeIndex = 0; + +static uint8_t dataToRead = 0; + +DMA_HandleTypeDef hdma_usart6_rx, hdma_usart6_tx; + +uint8_t tx6Buffer[CHUNK_SIZE]; /* tx uses less bytes */ +uint8_t tx6BufferQue[TX_BUF_SIZE]; /* In MUX mode command may be send shortly after each other => allow q 1 entry que */ +uint8_t tx6BufferQueLen; + +uint8_t rxBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ +uint8_t txBufferUart6[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ + +static uint8_t rx6WriteIndex; /* Index of the data item which is analysed */ +static uint8_t rx6ReadIndex; /* Index at which new data is stared */ + +static uint8_t dmaRx6Active; /* Indicator if DMA reception needs to be started */ +static uint8_t dmaTx6Active; /* Indicator if DMA reception needs to be started */ + + +/* Exported functions --------------------------------------------------------*/ + +void UART_clearRx6Buffer(void) +{ + uint16_t index = 0; + do + { + rxBufferUart6[index++] = BUFFER_NODATA_LOW; + rxBufferUart6[index++] = BUFFER_NODATA_HIGH; + } while (index < sizeof(rxBufferUart6)); + + rx6ReadIndex = 0; + rx6WriteIndex = 0; +} + +void GNSS_IO_init() { + + GPIO_InitTypeDef GPIO_InitStruct = { 0 }; + /* Peripheral clock enable */ + __HAL_RCC_USART6_CLK_ENABLE() + ; + + __HAL_RCC_GPIOA_CLK_ENABLE() + ; + /**USART6 GPIO Configuration + PA11 ------> USART6_TX + PA12 ------> USART6_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FAST; + GPIO_InitStruct.Alternate = GPIO_AF8_USART6; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USART6 DMA Init */ + /* USART6_RX Init */ + hdma_usart6_rx.Instance = DMA2_Stream1; + hdma_usart6_rx.Init.Channel = DMA_CHANNEL_5; + hdma_usart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_usart6_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart6_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart6_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart6_rx.Init.Mode = DMA_NORMAL; + hdma_usart6_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_usart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_usart6_rx); + + __HAL_LINKDMA(&huart6, hdmarx, hdma_usart6_rx); + + /* USART6_TX Init */ + hdma_usart6_tx.Instance = DMA2_Stream6; + hdma_usart6_tx.Init.Channel = DMA_CHANNEL_5; + hdma_usart6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_usart6_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart6_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart6_tx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart6_tx.Init.Mode = DMA_NORMAL; + hdma_usart6_tx.Init.Priority = DMA_PRIORITY_LOW; + hdma_usart6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_usart6_tx); + + __HAL_LINKDMA(&huart6, hdmatx, hdma_usart6_tx); + + /* USART6 interrupt Init */ + HAL_NVIC_SetPriority(USART6_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(USART6_IRQn); + + MX_USART6_DMA_Init(); + +} + +void MX_USART6_DMA_Init() { + /* DMA controller clock enable */ + __HAL_RCC_DMA2_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA2_Stream2_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); + /* DMA2_Stream6_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn); +} + + +void MX_USART6_UART_DeInit(void) +{ + HAL_DMA_Abort(&hdma_usart6_rx); + HAL_DMA_DeInit(&hdma_usart6_rx); + HAL_DMA_Abort(&hdma_usart6_tx); + HAL_DMA_DeInit(&hdma_usart6_tx); + HAL_UART_DeInit(&huart6); + HAL_UART_DeInit(&huart6); +} + +void MX_USART6_UART_Init(void) { + huart6.Instance = USART6; + huart6.Init.BaudRate = 9600; + huart6.Init.WordLength = UART_WORDLENGTH_8B; + huart6.Init.StopBits = UART_STOPBITS_1; + huart6.Init.Parity = UART_PARITY_NONE; + huart6.Init.Mode = UART_MODE_TX_RX; + huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart6.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&huart6); +} + + + +void UART6_SendCmdUbx(const uint8_t *cmd, uint8_t len) +{ + if(len < TX_BUF_SIZE) /* A longer string is an indication for a missing 0 termination */ + { + if(dmaRx6Active == 0) + { + UART_StartDMA_Receiption(); + } + memcpy(tx6Buffer, cmd, len); + if(HAL_OK == HAL_UART_Transmit_DMA(&huart6,tx6Buffer,len)) + { + dmaTx6Active = 1; + } + } +} + +uint8_t isEndIndication6(uint8_t index) +{ + uint8_t ret = 0; + if(index % 2) + { + if(rxBufferUart6[index] == BUFFER_NODATA_HIGH) + { + ret = 1; + } + } + else + { + if(rxBufferUart6[index] == BUFFER_NODATA_LOW) + { + ret = 1; + } + } + + return ret; +} + +void UART6_StartDMA_Receiption() +{ + if(dmaRx6Active == 0) + { + if(((rx6WriteIndex / CHUNK_SIZE) != (rx6ReadIndex / CHUNK_SIZE)) || ((isEndIndication6(rx6WriteIndex)) && (isEndIndication6(rx6WriteIndex + 1)))) /* start next transfer if we did not catch up with read index */ + { + if(HAL_OK == HAL_UART_Receive_DMA (&huart6, &rxBufferUart6[rx6WriteIndex], CHUNK_SIZE)) + { + dmaRx6Active = 1; + } + } + } +} + + + +void UART6_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if(huart == &huart6) + { + dmaRx6Active = 0; + rx6WriteIndex+=CHUNK_SIZE; + if(rx6WriteIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + rx6WriteIndex = 0; + } + UART6_StartDMA_Receiption(); + } +} +void UART6_TxCpltCallback(UART_HandleTypeDef *huart) +{ + if(huart == &huart6) + { + dmaTx6Active = 0; + UART6_WriteData(); + if(tx6BufferQueLen) + { + memcpy(tx6Buffer, tx6BufferQue, tx6BufferQueLen); + HAL_UART_Transmit_DMA(&huart6,tx6Buffer,tx6BufferQueLen); + dmaTx6Active = 1; + tx6BufferQueLen = 0; + } + } +} + +void UART6_ReadData() +{ + uint8_t localRX = rx6ReadIndex; + uint8_t futureIndex = rx6ReadIndex + 1; + uint8_t moreData = 0; + + if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + futureIndex = 0; + } + + if((!isEndIndication6(localRX)) || (!isEndIndication6(futureIndex))) do + { + while((!isEndIndication6(localRX)) || (moreData)) + { + moreData = 0; + UART6_Gnss_ProcessData(rxBufferUart6[localRX]); + + if(localRX % 2) + { + rxBufferUart6[localRX] = BUFFER_NODATA_HIGH; + } + else + { + rxBufferUart6[localRX] = BUFFER_NODATA_LOW; + } + + localRX++; + rx6ReadIndex++; + if(rx6ReadIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + localRX = 0; + rx6ReadIndex = 0; + } + futureIndex++; + if(futureIndex >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + futureIndex = 0; + } + } + if(!isEndIndication6(futureIndex)) + { + moreData = 1; + } + } while(moreData); +} + +void UART6_WriteData(void) +{ + if(huart6.hdmatx->State == HAL_DMA_STATE_READY) + { + huart6.gState = HAL_UART_STATE_READY; + dmaTx6Active = 0; + } + if(huart6.hdmarx->State == HAL_DMA_STATE_READY) + { + huart6.RxState = HAL_UART_STATE_READY; + dmaRx6Active = 0; + } +} + +void UART6_Gnss_SendCmd(uint8_t GnssCmd) +{ + const uint8_t* pData; + uint8_t txLength = 0; + + switch (GnssCmd) + { + case GNSSCMD_LOADCONF_0: pData = configUBX; + txLength = sizeof(configUBX) / sizeof(uint8_t); + break; + case GNSSCMD_LOADCONF_1: pData = setNMEA410; + txLength = sizeof(setNMEA410) / sizeof(uint8_t); + break; + case GNSSCMD_LOADCONF_2: pData = setGNSS; + txLength = sizeof(setGNSS) / sizeof(uint8_t); + break; + case GNSSCMD_GET_PVT_DATA: pData = getPVTData; + txLength = sizeof(getPVTData) / sizeof(uint8_t); + break; + case GNSSCMD_GET_NAV_DATA: pData = getNavigatorData; + txLength = sizeof(getNavigatorData) / sizeof(uint8_t); + break; + + default: + break; + } + if(txLength != 0) + { + UART6_SendCmdUbx(pData, txLength); + } +} + +void UART6_Gnss_Control(void) +{ + static uint32_t warmupTick = 0; + + switch (gnssState) + { + case UART_GNSS_INIT: gnssState = UART_GNSS_WARMUP; + warmupTick = HAL_GetTick(); + UART_clearRxBuffer(); + break; + case UART_GNSS_WARMUP: if(time_elapsed_ms(warmupTick,HAL_GetTick()) > 1000) + { + gnssState = UART_GNSS_LOADCONF_0; + } + break; + case UART_GNSS_LOADCONF_0: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_0); + gnssState = UART_GNSS_LOADCONF_1; + rxState = GNSSRX_DETECT_ACK_0; + break; + case UART_GNSS_LOADCONF_1: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_1); + gnssState = UART_GNSS_LOADCONF_2; + rxState = GNSSRX_DETECT_ACK_0; + break; + case UART_GNSS_LOADCONF_2: UART6_Gnss_SendCmd(GNSSCMD_LOADCONF_2); + gnssState = UART_GNSS_IDLE; + rxState = GNSSRX_DETECT_ACK_0; + break; + case UART_GNSS_IDLE: UART6_Gnss_SendCmd(GNSSCMD_GET_PVT_DATA); + gnssState = UART_GNSS_GET_PVT; + rxState = GNSSRX_DETECT_HEADER_0; + break; + default: + break; + } +} + +void UART6_Gnss_ProcessData(uint8_t data) +{ + GNSS_Handle.uartWorkingBuffer[writeIndex++] = data; + switch(rxState) + { + case GNSSRX_DETECT_ACK_0: + case GNSSRX_DETECT_HEADER_0: if(data == 0xB5) + { + writeIndex = 0; + memset(GNSS_Handle.uartWorkingBuffer,0, sizeof(GNSS_Handle.uartWorkingBuffer)); + GNSS_Handle.uartWorkingBuffer[writeIndex++] = data; + rxState++; + } + break; + case GNSSRX_DETECT_ACK_1: + case GNSSRX_DETECT_HEADER_1: if(data == 0x62) + { + rxState++; + } + else + { + rxState = GNSSRX_DETECT_HEADER_0; + } + break; + case GNSSRX_DETECT_ACK_2: if(data == 0x05) + { + rxState++; + } + else + { + rxState = GNSSRX_DETECT_HEADER_0; + } + break; + case GNSSRX_DETECT_ACK_3: if((data == 0x01) || (data == 0x00)) + { + GnssConnected = 1; + rxState = GNSSRX_READY; + } + else + { + rxState = GNSSRX_DETECT_HEADER_0; + } + break; + case GNSSRX_DETECT_HEADER_2: if(data == 0x01) + { + rxState++; + } + else + { + rxState = GNSSRX_DETECT_HEADER_0; + } + break; + case GNSSRX_DETECT_HEADER_3: + switch(data) + { + case 0x21: rxState = GNSSRX_READ_NAV_DATA; + dataToRead = 20; + break; + case 0x07: rxState = GNSSRX_READ_PVT_DATA; + dataToRead = 92; + break; + case 0x02: rxState = GNSSRX_READ_POSLLH_DATA; + break; + default: rxState = GNSSRX_DETECT_HEADER_0; + break; + } + break; + case GNSSRX_READ_NAV_DATA: + case GNSSRX_READ_PVT_DATA: + case GNSSRX_READ_POSLLH_DATA: if(dataToRead > 0) + { + dataToRead--; + } + else + { + switch(rxState) + { + case GNSSRX_READ_NAV_DATA: GNSS_ParseNavigatorData(&GNSS_Handle); + break; + case GNSSRX_READ_PVT_DATA: GNSS_ParsePVTData(&GNSS_Handle); + break; + case GNSSRX_READ_POSLLH_DATA: GNSS_ParsePOSLLHData(&GNSS_Handle); + break; + default: rxState = GNSSRX_DETECT_HEADER_0; + break; + } + rxState = GNSSRX_DETECT_HEADER_0; + gnssState = UART_GNSS_IDLE; + } + break; + default: rxState = GNSSRX_READY; + break; + } +} + + +void UART6_HandleUART() +{ + static uint8_t retryRequest = 0; + static uint32_t lastRequestTick = 0; + static uint32_t TriggerTick = 0; + static uint8_t timeToTrigger = 0; + uint32_t tick = HAL_GetTick(); + + if(gnssState != UART_GNSS_INIT) + { + UART6_ReadData(); + UART6_WriteData(); + } + if(gnssState == UART_GNSS_INIT) + { + lastRequestTick = tick; + TriggerTick = tick - 10; /* just to make sure control is triggered */ + timeToTrigger = 1; + retryRequest = 0; + } + else if(((retryRequest == 0) /* timeout or error */ + && (((time_elapsed_ms(lastRequestTick,tick) > (TIMEOUT_SENSOR_ANSWER)) && (gnssState != UART_GNSS_IDLE)) /* retry if no answer after half request interval */ + || (gnssState == UART_GNSS_ERROR)))) + { + /* The channel switch will cause the sensor to respond with an error message. */ + /* The sensor needs ~30ms to recover before he is ready to receive the next command => transmission delay needed */ + + TriggerTick = tick; + timeToTrigger = COMMAND_TX_DELAY; + retryRequest = 1; + } + + else if(time_elapsed_ms(lastRequestTick,tick) > 1000) /* switch sensor and / or trigger next request */ + { + lastRequestTick = tick; + TriggerTick = tick; + retryRequest = 0; + timeToTrigger = 1; + + if((gnssState == UART_GNSS_GET_PVT)) /* timeout */ + { + gnssState = UART_GNSS_IDLE; + } + timeToTrigger = 1; + } + if((timeToTrigger != 0) && (time_elapsed_ms(TriggerTick,tick) > timeToTrigger)) + { + timeToTrigger = 0; + UART6_Gnss_Control(); + } + +} + + +/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/