/** ****************************************************************************** * @file can_app.c * @author Vincent * @version V1.0.0 * @date 23-12-2015 * @brief ****************************************************************************** * * COPYRIGHT(c) 2015 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 "can_app.h" #include "RefreshMenu.h" #include "protocol.h" //#include "FLASH_Block_Api.h" #include "string.h" #include "flash_if.h" #include "crc_cal.h" /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static void Can_Filter_Config(void); /******************************************************************************* * Function: void CA_Init(CAN_HandleTypeDef*pCan) * Discrible: * Input: * Output: * Return: * Others: * date version author record * ----------------------------------------------- * 20151107 V1.0 VINCENT Create *********************************************************************************/ void CA_Init(void) { MX_CAN_Init(); Can_Filter_Config(); hcan.pTxMsg->ExtId = 0x01; hcan.pTxMsg->RTR = CAN_RTR_DATA; hcan.pTxMsg->IDE = CAN_ID_STD; } /******************************************************************************* * Function: void CAN_RxData_Process(CAN_Buf_TypeDef*ptCANRx) * Discrible: * Input: * Output: * Return: * Others: * date version author record * ----------------------------------------------- * 20151107 V1.0 VINCENT Create *********************************************************************************/ void CA_RxData_Process(CAN_Buf_TypeDef*ptCANRx) { CD_UINT8 ucHeadHighByte,ucHeadLowByte,ucFrameMode; //CD_UINT8 file_headTail[PACKET_128B_SIZE]={0},file_body[PACKET_1K_SIZE]={0}; CD_UINT16 i ; CD_UINT8 ucFrameLength,ucTrail; CD_UINT16 ucKeyCmd; CD_UINT32 ucCRCSum,CrcTemp; static CD_UINT8 frameCrcBuff[FRAME_DATA_SIZE+2]; if((*ptCANRx).ucBufCnt > 8) { /*清除超时标志*/ update.TimeCounter_Update = 0; ucHeadHighByte = cd_ReadChar(ptCANRx,0); //帧头1 ucHeadLowByte = cd_ReadChar(ptCANRx,1); //帧头2 if((PRO_HEAD1 == ucHeadHighByte)&&(PRO_HEAD2 == ucHeadLowByte)) { ucFrameMode = cd_ReadChar(ptCANRx,2); ucFrameLength = cd_ReadChar(ptCANRx,3); ucKeyCmd = ((CD_UINT16)cd_ReadChar(ptCANRx,4) << 8 ) + ((CD_UINT16)cd_ReadChar(ptCANRx,5)); if( FRAME_MODE_WRITE != ucFrameMode) return; if((*ptCANRx).ucBufCnt <(ucFrameLength + 4 + 5 )) return; frameCrcBuff[0] = FRAME_HEAD1; frameCrcBuff[1] = FRAME_HEAD2; frameCrcBuff[2] = 0x07; frameCrcBuff[3] = 0x51; ucTrail = cd_ReadChar(ptCANRx,ucFrameLength + 4 + 4 ); if(PRO_TAIL != ucTrail) { /*帧尾错误*/ cd_DelChar(ptCANRx, 1); update.AckEnable = ENABLE; downLoad.userCmd = CMD_ACK_ERR; downLoad.step = 0xf0; return ; } ucCRCSum = (cd_ReadChar(ptCANRx,ucFrameLength + 4 ) << 24) + \ (cd_ReadChar(ptCANRx,ucFrameLength + 4 + 1 ) << 16) + \ (cd_ReadChar(ptCANRx,ucFrameLength + 4 + 2 ) << 8) + \ cd_ReadChar(ptCANRx,ucFrameLength + 4 + 3 ) ; for(i=2; i< ( ucFrameLength + 4 ); i++) { frameCrcBuff[i+2] = cd_ReadChar(ptCANRx,i); } /*CRC 校验*/ CrcTemp = CRC32_Calculate( (CD_UINT8 *)frameCrcBuff, (ucFrameLength + 4 + 2 ) ); if( ucCRCSum != CrcTemp) { update.AckEnable = ENABLE; downLoad.userCmd = CMD_ACK_ERR; downLoad.step = 0xf1; cd_DelChar(ptCANRx, (ucFrameLength + 4 + 5 )); return ; } cd_DelChar(ptCANRx, (ucFrameLength + 4 + 5 )); switch(ucKeyCmd) { case CMD_UPDATA: //升级指令 //准备升级 if(downLoad.step != 1) { downLoad.step = 1; update.AckEnable = ENABLE; downLoad.userCmd = CMD_ACK_REQ; // /********************test*******************************/ // downLoad.userCmd = CMD_ACK_ERR; downLoad.packageSize = *(uint32_t *)(frameCrcBuff + 15); /*擦除FLASH,剩余最后1k没有擦除,保留其他功能使用**/ FLASH_If_Erase(APPLICATION_ADDRESS); /*清空flash写标志*/ for(i=0;i<1024;i++) { flag_FlashWR[i] = 0; } /*清除超时标志*/ update.TimeCounter_Startup = 0; } break; case CMD_PACKAGE_DATA: //数据包 downLoad.step = 2; downLoad.dataBuff_128B = (CD_UINT8 *)frameCrcBuff + FRAME_HEAD + PACKAGE_DATA_HEAD + 2; downLoad.packagecount = (frameCrcBuff[10] << 8) + frameCrcBuff[9]; if(downLoad.packagecount >= 1024) { downLoad.packagecount = 0; } downLoad.userCmd = CMD_ACK_OK; downLoad.wrenable = ENABLE; // /********************test*******************************/ // if(downLoad.packagecount == 2) // { // downLoad.userCmd = CMD_ACK_ERR; // } break; case CMD_UPDATA_END: //结束包 downLoad.step = 3; update.AckEnable = ENABLE; downLoad.userCmd = CMD_ACK_EOT; break; case 0x2505: downLoad.step = 5; update.AckEnable = ENABLE; break; default: cd_DelChar(ptCANRx, 1); break; } } else { cd_DelChar(ptCANRx, 1); } } } void sendBootInfo(void) { static CD_UINT8 bootInfoBuff[22]={ FRAME_HEAD1,FRAME_HEAD2,0x07,0x15,0x0C,0x0B,0xC1,0x09,'M','C',' ','V','1','.','1','.','0',0x00,0x00,0x00,0x00,0xF0 }; CD_UINT32 crc32Ret; //static CD_UINT8 ucInit_flag = 0; uint8_t i; crc32Ret = CRC32_Calculate( (CD_UINT8 *)bootInfoBuff,17 ); bootInfoBuff[17] = (CD_UINT8)( crc32Ret >> 24 ); bootInfoBuff[18] = (CD_UINT8)( crc32Ret >> 16 ); bootInfoBuff[19] = (CD_UINT8)( crc32Ret >> 8 ); bootInfoBuff[20] = (CD_UINT8)( crc32Ret ); // if(ucInit_flag == 0) // { // ucInit_flag = 1; // hcan.pTxMsg->ExtId = 0x01; // hcan.pTxMsg->RTR = CAN_RTR_DATA; // hcan.pTxMsg->IDE = CAN_ID_STD; // } /*发送第1包数据*/ hcan.pTxMsg->StdId = CAN_RxBuf_Struct1.ID; hcan.pTxMsg->DLC = 8; hcan.pTxMsg->Data[0] = bootInfoBuff[0]; hcan.pTxMsg->Data[1] = bootInfoBuff[1]; for( i=2;i<8;i++) { hcan.pTxMsg->Data[i] = bootInfoBuff[i+2]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } /*发送第2包数据*/ hcan.pTxMsg->DLC = 8; for( i=0;i<8;i++) { hcan.pTxMsg->Data[i] = bootInfoBuff[i+10]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } /*发送第3包数据*/ hcan.pTxMsg->DLC = 4; for( i=0;i<4;i++) { hcan.pTxMsg->Data[i] = bootInfoBuff[i+18]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } } void sendAck(void) { static CD_UINT8 ackBuff_2[16]={ FRAME_HEAD1,FRAME_HEAD2,0x07,0x15,0x0C,0x05,0xA9,0x03,'A','C','K',0x00,0x00,0x00,0x00,0xF0 }; CD_UINT32 crc32Ret; uint8_t i; crc32Ret = CRC32_Calculate( (CD_UINT8 *)ackBuff_2,11 ); ackBuff_2[11] = (CD_UINT8)( crc32Ret >> 24 ); ackBuff_2[12] = (CD_UINT8)( crc32Ret >> 16 ); ackBuff_2[13] = (CD_UINT8)( crc32Ret >> 8 ); ackBuff_2[14] = (CD_UINT8)( crc32Ret ); /*发送第1包数据*/ hcan.pTxMsg->StdId = CAN_RxBuf_Struct1.ID; hcan.pTxMsg->DLC = 8; hcan.pTxMsg->Data[0] = ackBuff_2[0]; hcan.pTxMsg->Data[1] = ackBuff_2[1]; for( i=2;i<8;i++) { hcan.pTxMsg->Data[i] = ackBuff_2[i+2]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } /*发送第2包数据*/ hcan.pTxMsg->DLC = 6; for( i=0;i<6;i++) { hcan.pTxMsg->Data[i] = ackBuff_2[i+10]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } } void sendUpdateAck( CD_UINT16 cmd ,CD_UINT16 packageNum ) { static CD_UINT8 ackBuff[15]={ FRAME_HEAD1,FRAME_HEAD2,0x07,0x15,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0 }; CD_UINT32 crc32Ret; //static CD_UINT8 ucInit_flag = 0; uint8_t i; ackBuff[6] = (CD_UINT8)(cmd >>8); ackBuff[7] = (CD_UINT8)cmd; ackBuff[8] = (CD_UINT8)packageNum; ackBuff[9] = (CD_UINT8)(packageNum>>8); crc32Ret = CRC32_Calculate( (CD_UINT8 *)ackBuff, 10); ackBuff[10] = (CD_UINT8)( crc32Ret >> 24 ); ackBuff[11] = (CD_UINT8)( crc32Ret >> 16 ); ackBuff[12] = (CD_UINT8)( crc32Ret >> 8 ); ackBuff[13] = (CD_UINT8)( crc32Ret ); /*发送第1包数据*/ hcan.pTxMsg->StdId = CAN_RxBuf_Struct1.ID; hcan.pTxMsg->DLC = 8; hcan.pTxMsg->Data[0] = ackBuff[0]; hcan.pTxMsg->Data[1] = ackBuff[1]; for( i=2;i<8;i++) { hcan.pTxMsg->Data[i] = ackBuff[i+2]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } /*发送第2包数据*/ hcan.pTxMsg->DLC = 5; for( i=0;i<5;i++) { hcan.pTxMsg->Data[i] = ackBuff[i+10]; } if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) { MX_CAN_Init(); } } ///******************************************************************************* //* Function: void A_(uint8_t ucStep,uint8_t ucPackagNum,uint8_t ucAck) //* Discrible: //* Input: //* Output: //* Return: //* Others: //* date version author record //* ----------------------------------------------- //* 20151107 V1.0 VINCENT Create //*********************************************************************************/ //void A_(uint8_t ucStep,uint8_t ucPackagNum,uint8_t ucAck) //{ // static CD_UINT8 ucInit_flag = 0; // static CD_UINT8 ucAckBuf[9] ={'U','P',0x04,0x00,0x02,0x00,0x00,0x00,0xF0}; // // CD_UINT8 ucXor = 0x00; // // ucXor ^= ucAckBuf[2]; // ucAckBuf[3] = ucStep; // ucXor ^= ucStep; // ucXor ^= ucAckBuf[4]; // ucAckBuf[5] = ucPackagNum; // ucXor ^= ucPackagNum; // ucAckBuf[6] = ucAck; // ucXor ^= ucAck; // ucAckBuf[7] = ucXor; // // if(ucInit_flag == 0) // { // ucInit_flag = 1; // hcan.pTxMsg->ExtId = 0x01; // hcan.pTxMsg->RTR = CAN_RTR_DATA; // hcan.pTxMsg->IDE = CAN_ID_STD; // } // // hcan.pTxMsg->StdId = CAN_RxBuf_Struct1.ID; // hcan.pTxMsg->DLC = 8; // memset(hcan.pTxMsg->Data,0,8); // for(uint8_t i=0;iDLC;i++) // { // hcan.pTxMsg->Data[i] = ucAckBuf[i]; // } // // if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) // { // MX_CAN_Init(); // } // memset(hcan.pTxMsg->Data,0,8); // hcan.pTxMsg->DLC = 1; // hcan.pTxMsg->Data[0] = ucAckBuf[8]; // // if(HAL_CAN_Transmit(&hcan,20) == HAL_ERROR) // { // MX_CAN_Init(); // } //} /******************************************************************************* * Function: void CA_Init(CAN_HandleTypeDef*pCan) * Discrible: * Input: * Output: * Return: * Others: * date version author record * ----------------------------------------------- * 20151107 V1.0 VINCENT Create *********************************************************************************/ static void Can_Filter_Config(void) { CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage; hcan.pTxMsg = &TxMessage; hcan.pRxMsg = &RxMessage; sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0); } /************************ (C) END OF FILE *********************************/