654 lines
22 KiB
C
654 lines
22 KiB
C
/*
|
||
* eth_drive.c
|
||
*
|
||
* Created on: 2023年1月5日
|
||
* Author: Administrator
|
||
*/
|
||
|
||
|
||
#include "interface_uart.h"
|
||
#include "interface_config.h"
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
|
||
Timer nmea_timer;
|
||
|
||
static RingBuffer nmea_rx_buf;
|
||
|
||
#define DMA_BUF_SIZE 1400
|
||
uint8_t dma_rx_buffer[DMA_BUF_SIZE] __attribute__((aligned(4)));
|
||
|
||
//__attribute__((aligned(4))) uint8_t dma_buffer[2048]; // GCC语法
|
||
|
||
|
||
//void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void UART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void UART8_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void UART6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void UART7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void DMA2_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void DMA2_Channel9_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
/*********************************************************************
|
||
* @fn USART3_IRQHandler
|
||
*
|
||
* @brief This function handles USART3 global interrupt request.
|
||
*
|
||
* @return none
|
||
*/
|
||
uint8_t state = 0;
|
||
uint8_t char_data[100] = {0};
|
||
unsigned char UART3_RX_cnt = 0;
|
||
void USART3_IRQHandler(void)
|
||
{
|
||
//----------------------------------------------------------
|
||
enter_critical_section();
|
||
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
|
||
{
|
||
imu_buffer1.buf_len = IMU_LEN - DMA_GetCurrDataCounter(IMU_RX_CH);
|
||
|
||
if( (imu_buffer1.dma_buffer[imu_buffer1.active_buf][0] == IMU_IIM46234_HEADER1) && //适配两个传感器
|
||
(imu_buffer1.dma_buffer[imu_buffer1.active_buf][1] == IMU_IIM46234_HEADER2) )
|
||
{
|
||
imu_buffer1.type = IIM46234;
|
||
publishMessage(&imu_buffer1, 1);
|
||
}
|
||
else if( (imu_buffer1.dma_buffer[imu_buffer1.active_buf][0] == IMU_YIS321_HEADER1) &&
|
||
(imu_buffer1.dma_buffer[imu_buffer1.active_buf][1] == IMU_YIS321_HEADER2) )
|
||
{
|
||
imu_buffer1.type = YIS321;
|
||
publishMessage(&imu_buffer1, 1);
|
||
}
|
||
else{}
|
||
|
||
imu_buffer1.active_buf ^= 1;
|
||
|
||
DMA_Cmd(IMU_RX_CH, DISABLE);
|
||
DMA_SetCurrDataCounter(IMU_RX_CH, IMU_LEN);
|
||
// Switch buffer
|
||
IMU_RX_CH->MADDR = (uint32_t)(uintptr_t)&(imu_buffer1.dma_buffer[imu_buffer1.active_buf][0]);
|
||
DMA_Cmd(IMU_RX_CH, ENABLE);
|
||
|
||
USART_ReceiveData(USART3); // clear IDLE flag
|
||
}
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
void UART4_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)
|
||
{
|
||
RTCM_Buffer1.buf_len = RX_BUFFER_LEN - DMA_GetCurrDataCounter(RTCM_RX_CH);
|
||
RTCM_Buffer1.active_buf ^= 1;
|
||
|
||
DMA_Cmd(RTCM_RX_CH, DISABLE);
|
||
DMA_SetCurrDataCounter(RTCM_RX_CH, RX_BUFFER_LEN);
|
||
// Switch buffer
|
||
RTCM_RX_CH->MADDR = (uint32_t)(uintptr_t)&(RTCM_Buffer1.dma_buffer[RTCM_Buffer1.active_buf][0]);
|
||
DMA_Cmd(RTCM_RX_CH, ENABLE);
|
||
printf("rtcm receive\n");
|
||
|
||
USART_ReceiveData(UART4); // clear IDLE flag
|
||
|
||
publishMessage(&RTCM_Buffer1, 1);
|
||
}
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
|
||
void UART8_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
if(USART_GetITStatus(UART8, USART_IT_RXNE) != RESET)
|
||
{
|
||
uint8_t UART_temp = 0;
|
||
UART_temp = USART_ReceiveData(UART8);
|
||
// printf("USART8:%d\n", UART_temp); // 数据
|
||
}
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
|
||
|
||
|
||
void UART6_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
if(USART_GetITStatus(UART6, USART_IT_RXNE) != RESET)
|
||
{
|
||
char ch = USART_ReceiveData(UART6);
|
||
}
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
void UART7_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
if(USART_GetITStatus(UART7, USART_IT_IDLE) != RESET)
|
||
{
|
||
DMA_Cmd(UM982_RX_CH, DISABLE);
|
||
uint16_t received_len = DMA_BUF_SIZE - DMA_GetCurrDataCounter(UM982_RX_CH);
|
||
|
||
// 3. 将数据拷贝到环形缓冲区
|
||
for(uint16_t i = 0; i < received_len; i++)
|
||
{
|
||
uint16_t next_head = (nmea_rx_buf.head + 1) % RING_BUF_SIZE;
|
||
if(next_head != nmea_rx_buf.tail)
|
||
{
|
||
nmea_rx_buf.buffer[nmea_rx_buf.head] = dma_rx_buffer[i];
|
||
nmea_rx_buf.head = next_head;
|
||
}
|
||
else
|
||
{
|
||
nmea_rx_buf.overflow = 1;
|
||
|
||
}
|
||
}
|
||
DMA_SetCurrDataCounter(UM982_RX_CH, DMA_BUF_SIZE);
|
||
DMA_Cmd(UM982_RX_CH, ENABLE);
|
||
|
||
USART_ReceiveData(UART7); // clear IDLE flag
|
||
}
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn DMA1_Channel5_IRQHandler
|
||
*
|
||
* @brief This function handles DMA1 Channel 5 global interrupt request.
|
||
*
|
||
* @return none
|
||
*/
|
||
void DMA1_Channel3_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
imu_buffer1.buf_len = RX_BUFFER_LEN;
|
||
|
||
DMA_ClearITPendingBit(DMA1_IT_TC3);//清零中断
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn DMA2_Channel3_IRQHandler
|
||
*
|
||
* @brief This function handles DMA1 Channel 5 global interrupt request.
|
||
*
|
||
* @return none
|
||
*/
|
||
void DMA2_Channel3_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
RTCM_Buffer1.buf_len = RX_BUFFER_LEN;
|
||
|
||
DMA_ClearITPendingBit(DMA2_IT_TC3);//清零中断
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn DMA2_Channel3_IRQHandler
|
||
*
|
||
* @brief This function handles DMA1 Channel 5 global interrupt request.
|
||
*
|
||
* @return none
|
||
*/
|
||
void DMA2_Channel9_IRQHandler(void)
|
||
{
|
||
enter_critical_section();
|
||
DMA_ClearITPendingBit(DMA2_IT_TC9);//清零中断
|
||
exit_critical_section(0);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @fn DMA_INIT
|
||
*
|
||
* @brief Configures the DMA for USART1.
|
||
*
|
||
* @return none
|
||
*/
|
||
void dmaInit(void)
|
||
{
|
||
DMA_InitTypeDef DMA_InitStructure = {0};
|
||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||
|
||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2|RCC_AHBPeriph_DMA1, ENABLE);
|
||
|
||
DMA_DeInit(RTCM_RX_CH);
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&RTCM_UART->DATAR);
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)&(RTCM_Buffer1.dma_buffer[0][0]);
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||
DMA_InitStructure.DMA_BufferSize = RX_BUFFER_LEN;
|
||
DMA_Init(RTCM_RX_CH, &DMA_InitStructure);
|
||
|
||
DMA_ITConfig(RTCM_RX_CH, DMA_IT_TC, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = RTCM_RX_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
DMA_Cmd(RTCM_RX_CH, ENABLE);
|
||
USART_DMACmd(RTCM_UART, USART_DMAReq_Rx, ENABLE);
|
||
|
||
//IMU DMA接收
|
||
DMA_DeInit(IMU_RX_CH);
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&IMU_UART->DATAR);
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)&(imu_buffer1.dma_buffer[0][0]);
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||
DMA_InitStructure.DMA_BufferSize = IMU_LEN;
|
||
DMA_Init(IMU_RX_CH, &DMA_InitStructure);
|
||
|
||
DMA_ITConfig(IMU_RX_CH, DMA_IT_TC, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = IMU_RX_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
DMA_Cmd(IMU_RX_CH, ENABLE);
|
||
USART_DMACmd(IMU_UART, USART_DMAReq_Rx, ENABLE);
|
||
|
||
|
||
//982 DMA接收
|
||
DMA_DeInit(UM982_RX_CH);
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&UM982_UART->DATAR);
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(uintptr_t)(dma_rx_buffer);
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||
DMA_InitStructure.DMA_BufferSize = DMA_BUF_SIZE;
|
||
DMA_Init(UM982_RX_CH, &DMA_InitStructure);
|
||
|
||
DMA_ITConfig(UM982_RX_CH, DMA_IT_TC, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = UM982_RX_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
DMA_Cmd(UM982_RX_CH, ENABLE);
|
||
USART_DMACmd(UM982_UART, USART_DMAReq_Rx, ENABLE);
|
||
}
|
||
|
||
|
||
|
||
void initUart(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||
USART_InitTypeDef USART_InitStructure1 = {0};
|
||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||
//----------------------------------------------------------------------------
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 | RCC_APB1Periph_UART4 | RCC_APB1Periph_UART6 | RCC_APB1Periph_UART7 | RCC_APB1Periph_UART8, ENABLE);
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
|
||
|
||
/* USART3 TX-->D.8 RX-->D.9 */
|
||
GPIO_PinRemapConfig( GPIO_FullRemap_USART3, ENABLE);//
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||
|
||
USART_InitStructure1.USART_BaudRate = 921600;
|
||
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
|
||
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure1.USART_Parity = USART_Parity_No;
|
||
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(USART3, &USART_InitStructure1);
|
||
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
USART_Cmd(USART3, ENABLE);
|
||
|
||
/* USART4 TX-->B.0 RX-->B.1 */
|
||
GPIO_PinRemapConfig( GPIO_PartialRemap_USART4, ENABLE);//
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||
|
||
USART_InitStructure1.USART_BaudRate = 115200;
|
||
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
|
||
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure1.USART_Parity = USART_Parity_No;
|
||
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(UART4, &USART_InitStructure1);
|
||
USART_ITConfig(UART4, USART_IT_IDLE, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
USART_Cmd(UART4, ENABLE);
|
||
|
||
/* UART6 TX-->C.0 RX-->C.1 */ //接的982的com1
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
|
||
USART_InitStructure1.USART_BaudRate = 115200;
|
||
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
|
||
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure1.USART_Parity = USART_Parity_No;
|
||
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(UART6, &USART_InitStructure1);
|
||
USART_ITConfig(UART6, USART_IT_RXNE, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = UART6_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
USART_Cmd(UART6, ENABLE);
|
||
|
||
/* UART7 TX-->C.2 RX-->C.3 *///接的982的com2
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
|
||
USART_InitStructure1.USART_BaudRate = 115200;
|
||
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
|
||
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure1.USART_Parity = USART_Parity_No;
|
||
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(UART7, &USART_InitStructure1);
|
||
USART_ITConfig(UART7, USART_IT_IDLE, ENABLE);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = UART7_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
USART_Cmd(UART7, ENABLE);
|
||
|
||
|
||
/* UART8 TX-->C.4 RX-->C.5 */
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
||
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
|
||
USART_InitStructure1.USART_BaudRate = 115200;
|
||
USART_InitStructure1.USART_WordLength = USART_WordLength_8b;
|
||
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
|
||
USART_InitStructure1.USART_Parity = USART_Parity_No;
|
||
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(UART8, &USART_InitStructure1);
|
||
USART_Cmd(UART8, ENABLE);
|
||
|
||
dmaInit();
|
||
}
|
||
|
||
|
||
|
||
void uartSendto(USART_TypeDef *USARTx, uint8_t * ucData, uint16_t len)//串口2发送函数
|
||
{
|
||
for(uint16_t i = 0; i<len; i++)
|
||
{
|
||
USART_SendData(USARTx,ucData[i]);
|
||
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET) /* waiting for sending finish */
|
||
{
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void rtcmProcess(void *signal_id)
|
||
{
|
||
(void)signal_id; // 标记变量为已使用,避免编译器警告
|
||
|
||
uartSendto(UART6, (uint8_t *)&(RTCM_Buffer1.dma_buffer[RTCM_Buffer1.active_buf^1][0]), RTCM_Buffer1.buf_len);//直接发送非激活内存
|
||
printf("rtcm forwarding\n");
|
||
}
|
||
|
||
|
||
|
||
|
||
void setDataProcess(void *signal_id)
|
||
{
|
||
(void)signal_id; // 标记变量为已使用,避免编译器警告
|
||
uartSendto(USART3, set_output_data, 20);
|
||
}
|
||
|
||
void setRateProcess(void *signal_id)
|
||
{
|
||
(void)signal_id; // 标记变量为已使用,避免编译器警告
|
||
uartSendto(USART3, set_rate, 20);
|
||
}
|
||
|
||
void setSaveProcess(void *signal_id)
|
||
{
|
||
(void)signal_id; // 标记变量为已使用,避免编译器警告
|
||
uartSendto(USART3, save_cmd, 20);
|
||
}
|
||
|
||
void setSteamProcess(void *signal_id)
|
||
{
|
||
(void)signal_id; // 标记变量为已使用,避免编译器警告
|
||
uartSendto(USART3, stream_cmd, 20);
|
||
}
|
||
|
||
|
||
|
||
|
||
/* /?**?
|
||
* @brief 计算NMEA语句的校验和(XOR异或校验)
|
||
* @param nmea_str 完整的NMEA语句(包含$和*,但不含结尾的CRLF)
|
||
* @return 计算出的8位校验和(0x00~0xFF)
|
||
*/
|
||
uint8_t nmea_checksum(const char *nmea_str)
|
||
{
|
||
uint8_t checksum = 0;
|
||
|
||
// 跳过起始符'$'(如果存在)
|
||
if (*nmea_str == '$') nmea_str++;
|
||
|
||
// 逐字符异或,直到遇到'*'或字符串结束
|
||
while (*nmea_str && *nmea_str != '*') {
|
||
checksum ^= (uint8_t)*nmea_str++;
|
||
}
|
||
return checksum;
|
||
}
|
||
|
||
|
||
/*
|
||
* @brief 验证NMEA语句的校验和
|
||
* @param nmea_str 完整的NMEA语句(如"$GPGGA,...*2A\r\n")
|
||
* @return 校验成功返回1,失败返回0
|
||
*/
|
||
bool nmea_validate_checksum(const char *nmea_str)
|
||
{
|
||
const char *p = nmea_str;
|
||
uint8_t computed_cs, received_cs;
|
||
|
||
// 查找校验和起始位置'*'
|
||
while (*p && *p != '*') p++;
|
||
if (*p != '*') return 0; // 无校验和字段
|
||
|
||
// 提取接收到的校验和(2位十六进制)
|
||
if (!isxdigit(p[1]) || !isxdigit(p[2])) return 0;
|
||
received_cs = (uint8_t)strtol(p+1, NULL, 16);
|
||
|
||
// 计算实际校验和
|
||
computed_cs = nmea_checksum(nmea_str);
|
||
|
||
return (computed_cs == received_cs);
|
||
}
|
||
|
||
void ProcessNMEAFrames(void *signal_id)
|
||
{
|
||
static uint8_t parsing_buf[1024];
|
||
static uint16_t parse_idx = 0;
|
||
bool frame_complete = false;
|
||
static uint8_t debug1s_cnt = 0;
|
||
|
||
debug1s_cnt ++;
|
||
if(debug1s_cnt >= 20)
|
||
{
|
||
debug1s_cnt = 0;
|
||
printf("nmea_buf tail:%d head:%d\n",
|
||
nmea_rx_buf.tail, nmea_rx_buf.head);
|
||
}
|
||
|
||
|
||
|
||
while(nmea_rx_buf.tail != nmea_rx_buf.head && !frame_complete)
|
||
{ // 缓冲区非空且未完成一帧解析
|
||
uint8_t ch = nmea_rx_buf.buffer[nmea_rx_buf.tail];
|
||
nmea_rx_buf.tail = (nmea_rx_buf.tail + 1) % RING_BUF_SIZE;
|
||
|
||
if(nmea_rx_buf.overflow) {
|
||
nmea_rx_buf.tail = nmea_rx_buf.head;
|
||
// 3. 重置溢出标志
|
||
nmea_rx_buf.overflow = 0;
|
||
// 4. 触发错误恢复流程(如重发请求)
|
||
printf("Overflow recovery\n");
|
||
|
||
}
|
||
|
||
|
||
// 帧头检测
|
||
if(ch == '$') {
|
||
if(parse_idx > 0 && parsing_buf[parse_idx-1] == '\n')
|
||
{
|
||
if (nmea_validate_checksum((char *)parsing_buf)) //校验代码
|
||
{
|
||
memcpy(&nema_output1.buffer[0],parsing_buf,parse_idx);
|
||
publishMessage(&nema_output1, 1);
|
||
frame_complete = true; // 标记帧处理完成
|
||
}
|
||
else
|
||
{
|
||
printf("nmea crc error");
|
||
frame_complete = true; // 标记帧处理完成
|
||
}
|
||
}
|
||
parse_idx = 0;
|
||
}
|
||
|
||
// 存储数据
|
||
if(parse_idx < RING_BUF_SIZE-1 && !frame_complete)
|
||
{
|
||
parsing_buf[parse_idx++] = ch;
|
||
|
||
// 帧尾检测
|
||
if(parse_idx >= 2 &&
|
||
parsing_buf[parse_idx-2] == '\r' &&
|
||
parsing_buf[parse_idx-1] == '\n')
|
||
{
|
||
if (nmea_validate_checksum((char *)parsing_buf)) //校验代码
|
||
{
|
||
memcpy(&nema_output1.buffer[0],parsing_buf,parse_idx);
|
||
publishMessage(&nema_output1, 1);
|
||
frame_complete = true; // 标记帧处理完成
|
||
}
|
||
else
|
||
{
|
||
printf("nmea buf error");
|
||
frame_complete = true; // 标记帧处理完成
|
||
}
|
||
parse_idx = 0;
|
||
}
|
||
}
|
||
else if(!frame_complete)
|
||
{
|
||
parse_idx = 0; // 防止溢出
|
||
}
|
||
}
|
||
|
||
timerStart(&nmea_timer, 50, 1); // 100ms后再次触发
|
||
}
|
||
|
||
void navigationRs232Process(void *signal_id)
|
||
{
|
||
uartSendto(UART8, (uint8_t *)&navigation_rs232_output, sizeof(navigation_rs232_output));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
// APP模块的初始化
|
||
void interfaceUartInit(void)
|
||
{
|
||
subscribe(&set_output_data, setDataProcess);
|
||
subscribe(&set_rate, setRateProcess);
|
||
subscribe(&save_cmd, setSaveProcess);
|
||
subscribe(&stream_cmd, setSteamProcess);
|
||
subscribe(&RTCM_Buffer1, rtcmProcess);
|
||
subscribe(&nmea_timer, ProcessNMEAFrames);
|
||
subscribe(&navigation_rs232_output, navigationRs232Process);
|
||
|
||
timerStart(&nmea_timer, 50,1);//50ms
|
||
|
||
printf("interface uart: initial OK %d\n",getCurrentTime());
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|