2025-02-05 00:13:59 +08:00

406 lines
13 KiB
C

/*
* Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
* All rights reserved.
*
* Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
* exclusively with CVA's microcontroller products. This file can be freely
* distributed within development tools that are supporting such microcontroller
* products.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*/
/*! \brief bootloader demo project
*/
/*******************************************************************************
* the includes
******************************************************************************/
#include <stdint.h>
#include <string.h>
#include "private_driver/mcu.h"
#include "bootloader.h"
#include "fls.h"
#include "uds_user.h"
#include "SEGGER_RTT.h"
/*******************************************************************************
* the defines
******************************************************************************/
#define UDS_PHYS_RECV_MSG_ID (0x731)
#define UDS_FUNC_RECV_MSG_ID (0x7DF)
#define UDS_PHYS_RESP_MSG_ID (0x7B1)
#define UDS_TEXT_TX_MSG_ID (0x234)
#define UDS_RECV_BUF (2080)
#define UDS_SEND_BUF (512)
#define CAN_BUFF_MAX_NUM (32)
#define CAN_DATA_BUFFER_SIZE (64u)
#define CAN_BUFFER_FIFO_SIZE (32u)
int64_t Get_Cur_Time_Stamp(void);
static int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t *pData, uint8_t size);
void DebugOutput(const char *message, ...);
/*******************************************************************************
* the typedefs
******************************************************************************/
typedef enum
{
UDS_MSG_IDX_STD_RX_PHYS,
UDS_MSG_IDX_STD_RX_FUNC,
UDS_MSG_IDX_STD_TX,
UDS_MSG_IDX_STD_TEST_TX,
UDS_MSG_IDX_NUM
} Uds_MsgIdIdxType;
typedef struct
{
uint32_t id;
uint8_t data[CAN_DATA_BUFFER_SIZE];
uint8_t len;
uint16_t timeStamp;
uint32_t hrTimeStamp;
} FlexCan_FrameStructureType;
typedef struct
{
FlexCan_FrameStructureType rxMsg[CAN_BUFFER_FIFO_SIZE];
FlexCan_FrameStructureType txMsg[CAN_BUFFER_FIFO_SIZE];
uint8_t wrIdx;
uint8_t rdIdx;
} FlexCan_DataInfoType;
/*******************************************************************************
* the globals
******************************************************************************/
McuType mcu;
volatile uint32_t gSystick1msEvent = 0, gSystick1msCnt = 0, gTestIoEn = 0;
uint32_t gCpuClockFrequency = 0;
int64_t timer_1ms = 0;
uint8_t udsSendBuf[UDS_SEND_BUF] = {0};
uint8_t udsRecvBuf[UDS_RECV_BUF] = {0};
UdsType udsObj;
FlexCan_DataInfoType flexCan_DataInfo;
FlexCanDrv_ControllerCfgType flexCanCfg;
FlexCanDrvType *flexCanDrv_DemoObj;
uint8_t flexCanBoot_EnhanceRxFFCnt = 0;
Uds_ParamsType udsParam = {
.isotpParams.framePadding = true,
.isotpParams.blockSize = 0,
.isotpParams.recvPhysId = UDS_PHYS_RECV_MSG_ID,
.isotpParams.recvFuncId = UDS_FUNC_RECV_MSG_ID,
.isotpParams.sendid = UDS_PHYS_RESP_MSG_ID,
.isotpParams.sendBuf = udsSendBuf,
.isotpParams.sendBufSize = UDS_SEND_BUF,
.isotpParams.recvBuf = udsRecvBuf,
.isotpParams.recvBufSize = UDS_RECV_BUF,
.isotpParams.debug = NULL,
.isotpParams.sendCanMsg = FlexCanBoot_TxMessage,
.isotpParams.getTimeMs = Get_Cur_Time_Stamp,
.p2Server_ms = 50,
.p2xServer_10ms = 500,
.s3Server_ms = 5000,
};
const FlexCanDrv_MsgCfgType msgCfgObj[UDS_MSG_IDX_NUM] = {
{UDS_MSG_IDX_STD_RX_PHYS, 1, UDS_PHYS_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_PHYS */
{UDS_MSG_IDX_STD_RX_FUNC, 1, UDS_FUNC_RECV_MSG_ID, false, FLEXCANDRV_MSGTYPE_RX, DLC_BYTE_8, false, true, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_RX_FUNC */
{UDS_MSG_IDX_STD_TX, 1, UDS_PHYS_RESP_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */
{UDS_MSG_IDX_STD_TEST_TX, 1, UDS_TEXT_TX_MSG_ID, false, FLEXCANDRV_MSGTYPE_TX, DLC_BYTE_8, false, false, 0xFFFFFFFF}, /* CAN_MSGOBJ_STD_TX */
};
/*******************************************************************************
* the functions
******************************************************************************/
int64_t Get_Cur_Time_Stamp(void)
{
return timer_1ms;
}
void SysTick_Handler(void)
{
gSystick1msEvent++;
timer_1ms++;
Uds_Tick(&udsObj);
}
void CAN_ORed_0_31_MB_Handler(void)
{
uint8_t i = 0;
FlexCanDrv_MsgObjType msgObj;
for(i = 0; i < flexCanCfg.msgNum; i++)
{
msgObj.msgBufId = i;
if(FlexCanDrv_GetMsgObjFlag(flexCanDrv_DemoObj, &msgObj))
{
if(flexCanCfg.msgCfg[i].msgType == FLEXCANDRV_MSGTYPE_RX)
{
/* clear message buffer interrupt flag */
FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj);
/* get the new message data */
FlexCanDrv_GetRxMsg(flexCanDrv_DemoObj, &msgObj);
memcpy(flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].data, msgObj.data, msgObj.dlc);
flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].id = msgObj.msgId;
flexCan_DataInfo.rxMsg[flexCan_DataInfo.wrIdx].len = msgObj.dlc;
flexCan_DataInfo.wrIdx++;
if(flexCan_DataInfo.wrIdx >= CAN_BUFFER_FIFO_SIZE)
{
flexCan_DataInfo.wrIdx = 0;
}
}
else
{
/* clear message buffer interrupt flag */
FlexCanDrv_ClearMsgObjFlag(flexCanDrv_DemoObj, &msgObj);
}
}
}
}
bool FlexCanBoot_ReadoutMsg(FlexCan_FrameStructureType *pRxMsgObj)
{
bool ret = false;
if(flexCan_DataInfo.wrIdx != flexCan_DataInfo.rdIdx)
{
memcpy(pRxMsgObj, &flexCan_DataInfo.rxMsg[flexCan_DataInfo.rdIdx], sizeof(FlexCan_FrameStructureType));
flexCan_DataInfo.rdIdx++;
if(flexCan_DataInfo.rdIdx >= CAN_BUFFER_FIFO_SIZE)
{
flexCan_DataInfo.rdIdx = 0;
}
ret = true;
}
return ret;
}
static int8_t FlexCanBoot_TxMessage(uint32_t msgId, const uint8_t *pData, uint8_t size)
{
FlexCanDrv_MsgObjType txMsgObj;
uint8_t msgIdx = 0, i = 0;
for(i = 0; i < flexCanCfg.msgNum; i++)
{
if(msgId == flexCanCfg.msgCfg[i].msgId)
{
msgIdx = i;
break;
}
}
txMsgObj.msgBufId = flexCanCfg.msgCfg[msgIdx].msgBufId;
txMsgObj.dlc = size;
txMsgObj.msgId = flexCanCfg.msgCfg[msgIdx].msgId;
memcpy(&txMsgObj.data[0], pData, size);
FlexCanDrv_SetTxMsg(flexCanDrv_DemoObj, &txMsgObj);
/* transmit standard CAN Tx message */
FlexCanDrv_TransmitMsg(flexCanDrv_DemoObj, &txMsgObj);
return 0;
}
void FlexCanBoot_Init(void)
{
uint32_t busClockFreq = 0;
flexCanDrv_DemoObj = &mcu.flexCanDrv;
/* set PTE4 as MUX 5 - CAN0.RX */
PinsDrv_SetMuxModeSel(&mcu.ptb, 0, PINSDRV_MUX_ALT5);
/* set PTE5 as MUX 5 - CAN0.TX */
PinsDrv_SetMuxModeSel(&mcu.ptb, 1, PINSDRV_MUX_ALT5);
/* get CAN controller default configuration */
FlexCanDrv_GetDefaultCfg(&flexCanCfg);
flexCanCfg.msgNum = sizeof(msgCfgObj) / sizeof(FlexCanDrv_MsgCfgType);
flexCanCfg.msgCfg = msgCfgObj;
flexCanCfg.clkSrc = FLEXCANDRV_CLKSRC_CHICLK;
flexCanCfg.fdEnable = false;
flexCanCfg.fdISOEnable = false;
flexCanCfg.fifoEnable = false;//TODO false?
flexCanCfg.msgBufDataLenSel = FLEXCANDRV_MB_SIZE_BYTE_8;
flexCanCfg.individualMaskEnable = true;
if(flexCanCfg.clkSrc == FLEXCANDRV_CLKSRC_CHICLK)
{
ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_APB, &busClockFreq);
}
else
{
ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SOSC_DIV, &busClockFreq);
}
if(flexCanCfg.fdEnable == true)
{
FlexCanDrv_BitTimingCalc(&flexCanCfg.fdBitTiming,
busClockFreq, /* module clock source: 16M */
2000000, /* baudrate: 2M */
7500, /* sample point: 75% */
2000, /* SJW: 20% */
1); /* FD bit timing */
}
FlexCanDrv_BitTimingCalc(&flexCanCfg.bitTiming,
busClockFreq, /* module clock source: 16M */
500000, /* baudrate: 500K */
7500, /* sample point: 75% */
2500, /* SJW: 20% */
0); /* classic CAN bit timing */
/* initialize CAN module */
FlexCanDrv_Configure(flexCanDrv_DemoObj, &flexCanCfg);
/* enable rx interrupt */
IrqDrv_EnableIrq(CAN_ORed_0_31_MB_IRQn);
}
static uint8_t testdata[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
void TxTestMsg (uint8_t * data)
{
for (uint8_t i = 0; i < 8; i++)
{
testdata[i] = data[i];
}
FlexCanBoot_TxMessage(UDS_TEXT_TX_MSG_ID,testdata,8);
}
void DebugOutput(const char *message, ...)
{
va_list ParamList;
va_start(ParamList, message);
SEGGER_RTT_printf(0, message, &ParamList);
va_end(ParamList);
}
uint8_t BootReqDelay = 0;
uint8_t BootReqFlag = 0;
void BootReqInit(void)
{
/* Setup the clock */
ClockDrv_ModuleClkConfigType clockConfig;
/* Setup the Pll div2 clock */
clockConfig.gating = true;
clockConfig.source = CLOCKDRV_PLL;
clockConfig.div = 1;
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PLL_DIV, &clockConfig);
}
uint32_t rollingcounter;
int main(void)
{
FlexCan_FrameStructureType rxMsg;
/* Setup the clock */
ClockDrv_ModuleClkConfigType clockConfig;
SEGGER_RTT_Init();
SEGGER_RTT_printf(0,"-----INTO BOOT-----\n");
IrqDrv_DisableGlobalInterrupt();
/* Initialize all MCU drivers: flash drv included */
Mcu_Init(&mcu);
WdgDrv_Disable(&mcu.wdgDrv);
/* CAN init */
memset(&flexCan_DataInfo, 0, sizeof(flexCan_DataInfo));
memset(&flexCanCfg, 0, sizeof(flexCanCfg));
/* Enable the clock for all port peripheral */
clockConfig.gating = true;
clockConfig.div = 1;
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTA, &clockConfig);
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTB, &clockConfig);
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTC, &clockConfig);
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTD, &clockConfig);
ClockDrv_ConfigureClock(&mcu.clockDrv, CLOCKDRV_PORTE, &clockConfig);
//STB
/* set PTC1 MUX as GPIO */
PinsDrv_SetMuxModeSel(&mcu.ptc, 9, PINSDRV_MUX_AS_GPIO);
/* set PTC1 as GPIO output */
PinsDrv_SetPinDirection(&mcu.ptc, 9, 1);
PinsDrv_WritePin(&mcu.ptc, 9, 0);
/* get CAN controller default configuration */
FlexCanBoot_Init();
/* UDS init */
Uds_UserInit(&udsObj, &udsParam);
Bootloader_Init(&mcu.flashDrv, &udsObj, &Uds_PositiveResponse, &Uds_NegativeResponse);
/* Set system tick clock, 1ms event */
ClockDrv_GetFreq(&mcu.clockDrv, CLOCKDRV_SYS, &gCpuClockFrequency);
SysTick_Config(gCpuClockFrequency / 1000u);
IrqDrv_EnableIrq(SysTick_IRQn);
#if BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u
Fls_Init(&mcu.flashDrv);
#endif
IrqDrv_EnableGlobalInterrupt();
while(1)
{
if(gSystick1msEvent > 0u)
{
gSystick1msEvent = 0;
gSystick1msCnt++;
if (gSystick1msCnt % 10 == 0)
{
}
if(gSystick1msCnt >= 1000)
{
gSystick1msCnt = 0;
//TxTestMsg(testdata);
}
Bootloader_TimingProcess(1);
Uds_Run(&udsObj);
Bootloader_StateProc();
}
/* Handler user routine */
if(FlexCanBoot_ReadoutMsg(&rxMsg) == true)
{
if((rxMsg.id == UDS_PHYS_RECV_MSG_ID) || (rxMsg.id == UDS_FUNC_RECV_MSG_ID))
{
IsoTp_HandleIncomingCanMsg(&udsObj.isotp, rxMsg.id, rxMsg.data, rxMsg.len);
}
}
}
}