/** ****************************************************************************** * File Name : USART.c * Description : This file provides code for the configuration * of the USART instances. ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2019 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "usart.h" #include "gpio.h" /* USER CODE BEGIN 0 */ #include "crc_cal.h" #include "tasks.h" uint8_t USART1_RxBuffer[256]; USART_Buf_TypeDef UART_RxBuff_Struct1 = {255,0,0,0,0,USART1_RxBuffer,&huart1}; uint8_t USART1_TxBuffer[256]; USART_Buf_TypeDef UART_TxBuff_Struct1 = {255,0,0,0,0,USART1_TxBuffer,&huart1}; /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 1, 1); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ // __HAL_UART_ENABLE_IT(&huart1, UART_IT_PE); /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ // __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR); /* Enable the UART Data Register not empty Interrupt */ __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USART1 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ uint8_t UART_GetChar(USART_Buf_TypeDef * ptRx) { uint8_t ucData; ucData = *((*ptRx).pcBufAddr + (*ptRx).ucBufRdInde); if ((*ptRx).ucBufCnt != 0) { if (++(*ptRx).ucBufRdInde == (*ptRx).ucBufSize) { (*ptRx).ucBufRdInde = 0; } __HAL_UART_DISABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//关接收中断 --(*ptRx).ucBufCnt; __HAL_UART_ENABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//开接收中断 } return ucData; } uint8_t UART_ReadChar(USART_Buf_TypeDef * ptRx, uint8_t ucNum) { uint8_t ucData; uint16_t i; i = ucNum; if ((*ptRx).ucBufCnt >= ucNum) { i += (*ptRx).ucBufRdInde; if (i >= (*ptRx).ucBufSize) { i -=((*ptRx).ucBufSize); } } else { i=0; } ucData = *((*ptRx).pcBufAddr + i); return ucData; } void UART_DelChar(USART_Buf_TypeDef * ptRx, uint8_t ucNum) { uint16_t i; if ((*ptRx).ucBufCnt >= ucNum) { __HAL_UART_DISABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//关接收中断 (*ptRx).ucBufCnt -= ucNum; __HAL_UART_ENABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//开接收中断 i = ucNum; i += (*ptRx).ucBufRdInde; if (i >= (*ptRx).ucBufSize) { i -= (*ptRx).ucBufSize; } (*ptRx).ucBufRdInde = i; } else { __HAL_UART_DISABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//关接收中断 i = (*ptRx).ucBufCnt; (*ptRx).ucBufCnt = 0; __HAL_UART_ENABLE_IT(ptRx->ptUartHandel,UART_IT_RXNE);//开接收中断 i += (*ptRx).ucBufRdInde; if (i >= (*ptRx).ucBufSize) { i -= (*ptRx).ucBufSize; } (*ptRx).ucBufRdInde = i; } } void UART_PutChar(USART_Buf_TypeDef * ptTx, uint8_t ucData) { while ((*ptTx).ucBufCnt == (*ptTx).ucBufSize); //发送缓冲满,等待。若有此情况建议增大缓冲区 __HAL_UART_DISABLE_IT(ptTx->ptUartHandel,UART_IT_TXE);//关发送中断 if((*ptTx).ucBufCnt == 0) { if(__HAL_UART_GET_FLAG(ptTx->ptUartHandel, UART_FLAG_TXE)== SET) //check if transmit data register full or not { ptTx->ptUartHandel->Instance->DR = ucData; __HAL_UART_ENABLE_IT(ptTx->ptUartHandel,UART_IT_TXE);//开发送中断 return; } } *((*ptTx).pcBufAddr + (*ptTx).ucBufWrInde) = ucData; if(++(*ptTx).ucBufWrInde == (*ptTx).ucBufSize) { (*ptTx).ucBufWrInde = 0; } ++(*ptTx).ucBufCnt; __HAL_UART_ENABLE_IT(ptTx->ptUartHandel,UART_IT_TXE);//开发送中断 } uint16_t Usart_Send(const uint8_t *Data, uint16_t length) { uint16_t i; for(i = 0; i < length; i++) { UART_PutChar(&UART_TxBuff_Struct1, Data[i]); } return length; } void SendCmdData(const int8_t Mode, const uint8_t *Data, uint16_t Size) { uint8_t i; uint32_t check_sum; uint8_t s_buffer[256] = {0x55, 0xAA, 0x01, 0x00}; s_buffer[4] = Mode; s_buffer[5] = Size; for(i = 0; i < Size; i++) { s_buffer[i + 6] = Data[i]; } check_sum = CRC32_Calculate(s_buffer, Size + 6); s_buffer[Size + 6] = check_sum >> 24; s_buffer[Size + 7] = (check_sum >> 16) & 0xff; s_buffer[Size + 8] = (check_sum >> 8) & 0xff; s_buffer[Size + 9] = check_sum & 0xff; s_buffer[Size + 10] = 0xF0; Usart_Send(s_buffer, Size + 11); } void SendUartDataToTE(uint16_t IDnum,uint8_t Mode, uint16_t Command, uint8_t* Data) { uint8_t SendBuf[150] = {0}; uint8_t CRC_Buf[150] = {0}; uint32_t CRC_Result = 0x00000000; uint8_t DataLength; DataLength = (uint8_t)(Command & 0xFF); SendBuf[0] = FRAME_BEGIN1; SendBuf[1] = FRAME_BEGIN2; SendBuf[2] = (uint8_t)((IDnum >> 8) & 0xFF); SendBuf[3] = (uint8_t)(IDnum & 0xFF);; SendBuf[4] = Mode; SendBuf[5] = DataLength + 2; SendBuf[6] = (uint8_t)((Command >> 8) & 0xFF); SendBuf[7] = DataLength; memcpy(SendBuf + 8, Data, DataLength); memcpy(CRC_Buf, SendBuf, 8 + DataLength); CRC_Result = CRC32_Calculate(CRC_Buf, DataLength + 8); SendBuf[8 + DataLength] = (uint8_t)((CRC_Result >> 24) & 0xFF); SendBuf[9 + DataLength] = (uint8_t)((CRC_Result >> 16) & 0xFF); SendBuf[10 + DataLength] = (uint8_t)((CRC_Result >> 8) & 0xFF); SendBuf[11 + DataLength] = (uint8_t)(CRC_Result & 0xFF); SendBuf[12 + DataLength] = FRAME_END; Usart_Send(SendBuf, DataLength + 13); } void USARTx_Rx_IRQ(USART_Buf_TypeDef *USARTx_RxBuf_Struct) { uint8_t ucData; if(__HAL_UART_GET_FLAG(USARTx_RxBuf_Struct->ptUartHandel,UART_FLAG_RXNE) != RESET) //接收中断 { ucData = (uint8_t)(USARTx_RxBuf_Struct->ptUartHandel->Instance->DR & 0x01FF); if(((USARTx_RxBuf_Struct->ptUartHandel->Instance->SR) & 0x0000) == 0)//无错误 { *((* USARTx_RxBuf_Struct).pcBufAddr + (* USARTx_RxBuf_Struct).ucBufWrInde) = ucData; if(++(* USARTx_RxBuf_Struct).ucBufWrInde >= (* USARTx_RxBuf_Struct).ucBufSize) { (* USARTx_RxBuf_Struct).ucBufWrInde = 0; } if(++(* USARTx_RxBuf_Struct).ucBufCnt > (* USARTx_RxBuf_Struct).ucBufSize) { (* USARTx_RxBuf_Struct).ucBufCnt = (* USARTx_RxBuf_Struct).ucBufSize; (* USARTx_RxBuf_Struct).ucBufOvf = 1; } } __HAL_UART_CLEAR_OREFLAG(USARTx_RxBuf_Struct->ptUartHandel); } } void USARTx_Tx_IRQ(USART_Buf_TypeDef *USARTx_TxBuf_Struct) { if((__HAL_UART_GET_FLAG(USARTx_TxBuf_Struct->ptUartHandel, UART_FLAG_TXE) != RESET) && (__HAL_UART_GET_IT_SOURCE(USARTx_TxBuf_Struct->ptUartHandel, UART_IT_TXE) != RESET)) //发送完成中断 { __HAL_UART_CLEAR_FLAG(USARTx_TxBuf_Struct->ptUartHandel,UART_FLAG_TXE); if((* USARTx_TxBuf_Struct).ucBufCnt) { --(* USARTx_TxBuf_Struct).ucBufCnt; USARTx_TxBuf_Struct->ptUartHandel->Instance->DR = *(USARTx_TxBuf_Struct->pcBufAddr + USARTx_TxBuf_Struct->ucBufRdInde); if(++(* USARTx_TxBuf_Struct).ucBufRdInde >= (* USARTx_TxBuf_Struct).ucBufSize) { (* USARTx_TxBuf_Struct).ucBufRdInde = 0; } } else { /* Disable the UART Transmit Data Register Empty Interrupt */ __HAL_UART_DISABLE_IT(USARTx_TxBuf_Struct->ptUartHandel, UART_IT_TXE); } } } void Data_Process(uint16_t ID, uint8_t Mode, uint16_t Cmd, uint8_t* Data) { static uint8_t PBU_TE_Status_FirstFlag = 0; static uint8_t ErrorCnt_Key_Power = 0; static uint8_t ErrorCnt_Key_Walk = 0; static uint8_t ErrorCnt_Key_Add = 0; static uint8_t ErrorCnt_Key_Dec = 0; if(ID == 0x0101) { switch(Cmd) { case 0x2201: Key_Recv_Status.Status = Data[0]; //Power键判断 if(Key_Recv_Status.Status_Bit.Power == 1) { ErrorCnt_Key_Power++; if(ErrorCnt_Key_Power > 10) { PBU_TE_ErrorCode.ERROR_Bit.Key_Power = 1; } } else { ErrorCnt_Key_Power = 0; PBU_TE_ErrorCode.ERROR_Bit.Key_Power = 0; } //Walk键判断 if(Key_Recv_Status.Status_Bit.Walk == 1) { ErrorCnt_Key_Walk++; if(ErrorCnt_Key_Walk > 10) { PBU_TE_ErrorCode.ERROR_Bit.Key_Walk = 1; } } else { ErrorCnt_Key_Walk = 0; PBU_TE_ErrorCode.ERROR_Bit.Key_Walk = 0; } //Add键判断 if(Key_Recv_Status.Status_Bit.Add == 1) { ErrorCnt_Key_Add++; if(ErrorCnt_Key_Add > 10) { PBU_TE_ErrorCode.ERROR_Bit.Key_Add = 1; } } else { ErrorCnt_Key_Add = 0; PBU_TE_ErrorCode.ERROR_Bit.Key_Add = 0; } //Dec键判断 if(Key_Recv_Status.Status_Bit.Dec == 1) { ErrorCnt_Key_Dec++; if(ErrorCnt_Key_Dec > 10) { PBU_TE_ErrorCode.ERROR_Bit.Key_Dec = 1; } } else { ErrorCnt_Key_Dec = 0; PBU_TE_ErrorCode.ERROR_Bit.Key_Dec = 0; } PBU_TE_ErrorCode.ERROR_Bit.MCU_Fault = Key_Recv_Status.Status_Bit.sync; TE_Online_TimeCnt=SysTime_5ms; TE_Online_Flag = 1; break; default: break; } } else if(ID == 0x0635)//透传0X635的数据 { SendData(ID, Mode, Cmd, Data);//将TE过来的数据直接透传到CAN switch(Cmd) { case 0xc109: { if(PBU_TE_Status_FirstFlag == 0) { PBU_TE_Status_FirstFlag = 1; PBU_TE_Status = HANDSHAKE_YES; } break; } case 0xc502://最后一帧数据 { PBU_TE_Status = UPDATE_FINISH; PBU_RunMode = PBU_RunMode_PowerOff; HAL_Delay(20); break; } default: { break; } } } } void Uart_RxData_Process(USART_Buf_TypeDef *ptUARTRx, uint16_t TimeOutCnt) { uint8_t Mode, CmdLength, DataLength, Data[150], CRC_Buf[150]; uint16_t Cmd, id, i; uint32_t CrcResult, CrcData; uint8_t FrameBegin1, FrameBegin2; static uint32_t DelayTimeCnt1 = 0; static TrueOrFalse_Flag_Struct_t IsWaitRX_Flag = FALSE; /* Detect the data size of the buffer area to meet the minimum frame length */ if(ptUARTRx->ucBufCnt >= 13) { /* Get frame header data */ FrameBegin1 = UART_ReadChar(ptUARTRx, 0); CRC_Buf[0] = FrameBegin1; FrameBegin2 = UART_ReadChar(ptUARTRx, 1); CRC_Buf[1] = FrameBegin2; /* Compare frame header data */ if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2)) { /* Get ID */ CRC_Buf[2] = UART_ReadChar(ptUARTRx, 2); CRC_Buf[3] = UART_ReadChar(ptUARTRx, 3); id = (CRC_Buf[2] << 8) | CRC_Buf[3]; /* Get mode */ Mode = UART_ReadChar(ptUARTRx, 4); CRC_Buf[4] = Mode; /* Comparison mode data */ if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT)) { /* Get data length */ CmdLength = UART_ReadChar(ptUARTRx, 5); CRC_Buf[5] = CmdLength; /* Get the command word */ Cmd = (UART_ReadChar(ptUARTRx, 6) << 8) + UART_ReadChar(ptUARTRx, 7); CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF); CRC_Buf[7] = (uint8_t)(Cmd & 0xFF); DataLength = UART_ReadChar(ptUARTRx, 7); /* Compare the data length with the command word and the data length without the command word by 2 bytes. */ if((CmdLength - DataLength) == 2) { if(ptUARTRx->ucBufCnt < (CmdLength + 11)) { if(IsWaitRX_Flag == FALSE) { DelayTimeCnt1 = SysTime_5ms; IsWaitRX_Flag = TRUE; } if(TimeCntDiff_5ms(DelayTimeCnt1) > TimeOutCnt) { DelayTimeCnt1 = SysTime_5ms; // UART_DelChar(ptUARTRx, ptUARTRx->ucBufCnt); IsWaitRX_Flag = TRUE; } } else { IsWaitRX_Flag = FALSE; for(i = 0; i < DataLength; i++) { Data[i] = UART_ReadChar(ptUARTRx, 8 + i); CRC_Buf[8 + i] = Data[i]; } /* Get CRC check data */ CrcData = (UART_ReadChar(ptUARTRx, 8 + DataLength) << 24) + (UART_ReadChar(ptUARTRx, 9 + DataLength) << 16) + (UART_ReadChar(ptUARTRx, 10 + DataLength) << 8) + UART_ReadChar(ptUARTRx, 11 + DataLength); /* Calculate the CRC check result */ CrcResult = CRC32_Calculate(CRC_Buf, 8 + DataLength); /* Check CRC check result */ if((CrcData - CrcResult) == 0) { /* Data processing */ Data_Process(id, Mode, Cmd, Data); /* Remove parsed data */ UART_DelChar(ptUARTRx, DataLength + 13); } else { /* Delete the first byte and reparse the data */ UART_DelChar(ptUARTRx, 1); } } } else { /* Delete the first byte and reparse the data */ UART_DelChar(ptUARTRx, 1); } } else { /* Delete the first byte and reparse the data */ UART_DelChar(ptUARTRx, 1); } } else { /* Delete the first byte and reparse the data */ UART_DelChar(ptUARTRx, 1); } } } /* USER CODE END 1 */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/