250 lines
9.4 KiB
C
250 lines
9.4 KiB
C
|
||
#include "flexcan_init.h"
|
||
#include "IAP_Task.h"
|
||
#include <flexcan_cfg.h>
|
||
#include <debug.h>
|
||
#include <wdt_refresh.h>
|
||
|
||
|
||
#define TX_PADDING_VAL (0xA5)
|
||
|
||
static uint8_t g_rxFifoDataBuf[8];
|
||
static flexcan_frame_t g_frameBuf;
|
||
|
||
bool busoff_occur_flag = false;//busoff±êÖ¾
|
||
|
||
|
||
void flexcan_config_rx_fifo(flexcan_handle_t *handle,
|
||
flexcan_rx_fifo_config_t *config)
|
||
{
|
||
flexcan_frame_t *rx_fifo_frame = &g_frameBuf;
|
||
rx_fifo_frame->dataBuffer = &g_rxFifoDataBuf[0];
|
||
|
||
flexcan_set_rx_fifo_config(handle, config);
|
||
|
||
for (uint8_t i = 0; i < USED_MB_FOR_FIFO;
|
||
i++) {
|
||
flexcan_set_rx_individual_mask(handle, i, config->filter_tab[i].filter_mask);
|
||
}
|
||
|
||
/* rx by interrupt */
|
||
flexcan_fifo_transfer_t Xfer = {rx_fifo_frame};
|
||
flexcan_receive_fifo_nonblocking(handle, &Xfer);
|
||
}
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn CAN_Send_Msg
|
||
*
|
||
* @brief CAN Transmit function.
|
||
*
|
||
* @param CANx- CAN1 or CAN2
|
||
* ID - Message ID
|
||
* IDE - CAN_Id_Standard or CAN_Id_Extended
|
||
* RTR - CAN_RTR_Data or CAN_RTR_Remote
|
||
* msg - Transmit data buffer.
|
||
* len - Data length.
|
||
*
|
||
* @return 0 - Send successful.
|
||
* 1 - Send failed.
|
||
*/
|
||
uint8_t CAN_Send_Msg( flexcan_handle_t *handle, uint32_t ID, flexcan_frame_format_e ide, flexcan_frame_type_e rtr, uint8_t *msg, uint8_t len, uint8_t tx_index)
|
||
{
|
||
uint16_t i = 0;
|
||
//------------------------------------------------------------------------------
|
||
|
||
flexcan_frame_t frame = {.id = ID,
|
||
.length = len,
|
||
.type = rtr,
|
||
.format = ide,
|
||
.dataBuffer = msg};
|
||
flexcan_mb_transfer_t xfer = {&frame, tx_index};
|
||
|
||
while( ( flexcan_get_mb_state(handle, tx_index) != FLEXCAN_StateIdle ) && (i < 0xFFF) )
|
||
{
|
||
i++;
|
||
}
|
||
|
||
if( i == 0xFFF )
|
||
{
|
||
return 1;
|
||
|
||
}
|
||
else
|
||
{
|
||
flexcan_send_nonblocking(handle, &xfer, TX_PADDING_VAL);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*********************************************************************
|
||
* @fn flexcan_transfer_callback
|
||
*
|
||
* @brief erase Data-Flash block, minimal block is 256B
|
||
*
|
||
* @param Page_Address - the address of the page being erased.
|
||
* Length - Erased data length
|
||
*
|
||
* @return none
|
||
*/
|
||
uint32_t debugaa = 0;
|
||
void flexcan_transfer_callback(flexcan_handle_t *handle,
|
||
flexcan_status_e status, uint32_t result,
|
||
void *userData)
|
||
{
|
||
// uint8_t ip_addr[4] = {0,0,0,0};
|
||
// uint16_t i = 0;
|
||
uint16_t FrameHeader = 0;
|
||
// uint16_t canAddr = 0;
|
||
flexcan_frame_t *buf = (flexcan_frame_t *)userData;
|
||
// uint32_t Rgflexcan_transferCRC = 0;
|
||
static uint8_t canCmdSTT = 0;
|
||
// static uint32_t CANFlashNowLen1 = 0;
|
||
// static uint32_t CANFlashNowLen2 = 0;
|
||
|
||
// uint32_t debugARR1[2] = {0,0};
|
||
//--------------------------------------------------------------
|
||
// ssdk_printf(SSDK_CRIT, "status:0x%x\r\n",status);
|
||
switch (status)
|
||
{
|
||
case FLEXCAN_RX_IDLE:
|
||
break;
|
||
|
||
case FLEXCAN_RX_FIFO_IDLE:
|
||
|
||
|
||
if(OTA_CANRxID == (buf->id))//IDΪ1
|
||
{
|
||
g_canRxMsgFlag = 1;
|
||
FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) );
|
||
|
||
// ssdk_printf(SSDK_CRIT, "FrameHeader:0x%x\r\n",FrameHeader);
|
||
|
||
switch(canCmdSTT)
|
||
{
|
||
case 0:
|
||
if(FrameHeader == CRC_UPDATE )//CRCÖ¸Áî
|
||
{
|
||
memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//¸´ÖÆÊý¾Ý
|
||
|
||
Flash_RxBuf_1.Download_Mode = DOWNLOAD_CAN;
|
||
|
||
if( (FlashBufInitial == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_1.Flash_RxBufSta)) )//³õʼ״̬£¬Ð´Íê³É£¬crc´íÎóÖØ·¢
|
||
{
|
||
Flash_RxBuf_1.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC
|
||
Flash_RxBuf_1.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//Ö¡³¤¶È
|
||
Flash_RxBuf_1.Flash_RxBufLenNow = 0;
|
||
Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 10;
|
||
}
|
||
else if( (FlashBufInitial == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_2.Flash_RxBufSta)) )//³õʼ״̬£¬Ð´Íê³É£¬crc´íÎóÖØ·¢
|
||
{
|
||
Flash_RxBuf_2.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC
|
||
Flash_RxBuf_2.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//Ö¡³¤¶È
|
||
Flash_RxBuf_2.Flash_RxBufLenNow = 0;
|
||
Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 20;
|
||
}
|
||
else{}
|
||
}
|
||
else//ÆäËûÖ¸Áî
|
||
{
|
||
memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//¸´ÖÆÊý¾Ý
|
||
canCmdSTT = 0;
|
||
}
|
||
break;
|
||
|
||
case 10://¶ÁÈ¡flash
|
||
ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//¸ßλ ÊÖ¶¯Ìí¼ÓID£¬·½±ãºóÃæÅжÏ
|
||
ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE);
|
||
|
||
memcpy(&Flash_RxBuf_1.RxData[Flash_RxBuf_1.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//¸´ÖÆÊý¾Ý
|
||
Flash_RxBuf_1.Flash_RxBufLenNow = (Flash_RxBuf_1.Flash_RxBufLenNow) + (buf->length);
|
||
if( (Flash_RxBuf_1.Flash_RxBufLenNow) >= (Flash_RxBuf_1.Flash_RxBufLen) )//½ÓÊÕ³¤¶ÈÂú×ãÒªÇó
|
||
{
|
||
Flash_RxBuf_1.Flash_RxBufSta = FlashBufComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 0;
|
||
}
|
||
else
|
||
{
|
||
|
||
Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 10;
|
||
}
|
||
break;
|
||
|
||
|
||
case 20://»º´æ2
|
||
ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//¸ßλ ÊÖ¶¯Ìí¼ÓID£¬·½±ãºóÃæÅжÏ
|
||
ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE);
|
||
memcpy(&Flash_RxBuf_2.RxData[Flash_RxBuf_2.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//¸´ÖÆÊý¾Ý
|
||
Flash_RxBuf_2.Flash_RxBufLenNow = (Flash_RxBuf_2.Flash_RxBufLenNow) + (buf->length);
|
||
|
||
if( (Flash_RxBuf_2.Flash_RxBufLenNow) >= (Flash_RxBuf_2.Flash_RxBufLen) )//½ÓÊÕ³¤¶ÈÂú×ãÒªÇó
|
||
{
|
||
Flash_RxBuf_2.Flash_RxBufSta = FlashBufComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 0;
|
||
}
|
||
else
|
||
{
|
||
Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//Çл»×´Ì¬
|
||
canCmdSTT = 20;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else if(WDT_CANRxID == (buf->id))//WDT µÄID
|
||
{
|
||
FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) );
|
||
|
||
if(WDT_Refresh == FrameHeader)//ι¹·
|
||
{
|
||
|
||
WDTReFresh_flag = true;//½ÓÊÕµ½Ö¡¾Í¸üÐÂ
|
||
ssdk_printf(SSDK_CRIT, "WDT_Refresh:0x%x\r\n", WDTReFresh_flag);
|
||
}
|
||
}
|
||
else{}
|
||
break;
|
||
|
||
case FLEXCAN_TX_IDLE:
|
||
break;
|
||
|
||
case FLEXCAN_WAKEUP_TIMEOUT:
|
||
break;
|
||
|
||
case FLEXCAN_WAKEUP_MATCH:
|
||
break;
|
||
|
||
case FLEXCAN_ERROR_STATUS:
|
||
busoff_occur_flag = true;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* reinitialize the controller. */
|
||
void flexcan_busoff_recovery_demo(flexcan_handle_t *handle)
|
||
{
|
||
flexcan_deinit(handle);
|
||
flexcan_init(handle, &g_flexcan_config);
|
||
|
||
flexcan_enable_interrupts(handle, FLEXCAN_BusOffInterruptEnable);
|
||
|
||
/* assign fifo only for rx. */
|
||
flexcan_config_rx_fifo(handle, &flexcan_fifo_cfg);
|
||
|
||
/* assign mailbox14-20 for tx. */
|
||
for (uint8_t i = TX_MB_INDEX; i < (TX_MB_INDEX + TX_MAILBOX_NUM);
|
||
i++) {
|
||
|
||
flexcan_set_tx_mb_config(handle, i, true);
|
||
}
|
||
}
|
||
|