/***************************************************************************//** * @file bl_can.c * @brief This file configs the CAN of bootloader. * @version V1.0.0 * @date May-2021 * @author Zhixin Semiconductor * * @note * Copyright (C) 2021 Zhixin Semiconductor Ltd. All rights reserved. * ******************************************************************************/ #include "bl_can.h" #include #include "sysctrl_drv.h" #include "int_drv.h" #include "../cantp/CanTp.h" #define PARCC ((mrcc_reg_t *) PARCC_BASE_ADDR) CAN_MsgBuf_t CAN1RxBuf; uint8_t u8CANMb0DataReceived = 0x0; ResultStatus_t CanInit(void) { ResultStatus_t res = SUCC; uint32_t u32CAN_Rec_MsgId = 0x0; CAN_Config_t canConfig = { .mbMaxNum = 14, .rxFifoEn = DISABLE, .mode = CAN_MODE_NORMAL, #if (BL_INTERFACE == BL_INTERFACE_CAN_FD) .fdEn = ENABLE, #elif (BL_INTERFACE == BL_INTERFACE_CAN) .fdEn = DISABLE, #else /* nothing */ #endif .bitTiming = { .propSeg = 8, .phaseSeg1 = 4, .phaseSeg2 = 3, .preDivider = 2, .rJumpwidth = 3 }, #if (BL_INTERFACE == BL_INTERFACE_CAN_FD) .payload0 = CAN_PAYLOAD_SIZE_64, .payload1 = CAN_PAYLOAD_SIZE_64, #elif (BL_INTERFACE == BL_INTERFACE_CAN) .payload0 = CAN_PAYLOAD_SIZE_8, .payload1 = CAN_PAYLOAD_SIZE_8, #else /* nothing */ #endif .bitTimingFdData = { .propSeg = 2, .phaseSeg1 = 3, .phaseSeg2 = 2, .preDivider = 1, .rJumpwidth = 1 } }; SYSCTRL_ResetModule(SYSCTRL_CAN_ID); SYSCTRL_EnableModule(SYSCTRL_CAN_ID); /* CAN Receive MsgID definition for E16 Head Light Left/Right mounting side */ if ((MEM_ADR_LR_DET == LEFT_ECU)&&(MEM_ADR_LR_DET_INV == LEFT_ECU_INV)) { u32CAN_Rec_MsgId = (uint32_t)0x773; } else if((MEM_ADR_LR_DET == RIGHT_ECU)&&(MEM_ADR_LR_DET_INV == RIGHT_ECU_INV)) { u32CAN_Rec_MsgId = (uint32_t)0x774; } else { u32CAN_Rec_MsgId = (uint32_t)0x773; } /* ********************************************************************** */ if(CAN_Init(CAN_ID, &canConfig) != SUCC) { res = ERR; } else { /*CAN_FdTdcEnable(CAN_ID, 8U);*/ /*Use Mb0 to receive message come from ID 0x6D4*/ if(ERR == CAN_MbReceive(CAN_ID, CAN_REC_MB, CAN_MSG_ID_STD, u32CAN_Rec_MsgId)) { res = ERR; } /*Use Mb0 to receive message come from CAN function Address ID 0x7DF*/ if(ERR == CAN_MbReceive(CAN_ID, CAN_FUNCADDR_REC_MB, CAN_MSG_ID_STD, CAN_REC_FUNC_ADDR)) { res = ERR; } /*Install interrupt function for MB interrupt*/ CAN05_InstallMbCallBackFunc(CAN_ID, CAN05_MB_INT_0TO15,Can1MbCbf); CAN_IntMask(CAN_ID, CAN_INT_ALL, MASK, 0U,0U,0U,0U); CAN_IntMask(CAN_ID, CAN_INT_HOST_MEM_ERR, UNMASK, 0U,0U,0U,0U); CAN_IntMask(CAN_ID, CAN_INT_CAN_MEM_ERR, UNMASK, 0U,0U,0U,0U); /*Unmask MB0 Interrupt*/ if(ERR == CAN_MbIntMask(CAN_ID, CAN_REC_MB,UNMASK)) { res = ERR; } /*Unmask MB2 Interrupt*/ if(ERR == CAN_MbIntMask(CAN_ID, CAN_FUNCADDR_REC_MB,UNMASK)) { res = ERR; } if(res == SUCC) { INT_SetPriority(CAN1_MbGroup1_IRQ_NUM, 0x01U); INT_EnableIRQ(CAN1_MbGroup1_IRQ_NUM); } } return res; } void CanReset(void) { CAN_Deinit(CAN_ID); INT_SetPriority(CAN1_MbGroup1_IRQ_NUM, 0x00U); INT_DisableIRQ(CAN1_MbGroup1_IRQ_NUM); SYSCTRL_ResetModule(SYSCTRL_CAN_ID); SYSCTRL_DisableModule(SYSCTRL_CAN_ID); } void Can1MbCbf(uint32_t mbIdx) { MessageBuf_t rxMessage; if((mbIdx == CAN_REC_MB) || (mbIdx == CAN_FUNCADDR_REC_MB)) { if(SUCC == CAN_GetMsgBuff(CAN_ID, mbIdx, &CAN1RxBuf)) { /*Currently do nothing*/ } } CanReadOneFrame(&rxMessage); network_prerecv_frame(&rxMessage); u8CANMb0DataReceived = 0x01; } void ErrorTrap(void) { while(true) { } } void CanReadOneFrame(MessageBuf_t *buf) { buf->len =CAN1RxBuf.dataLen; buf->msgId = CAN1RxBuf.msgId; memcpy(buf->data, CAN1RxBuf.data, buf->len); } void CanTransmitMsg(uint8_t *data, uint8_t len) { ResultStatus_t status = BUSY; uint32_t u32CAN_Send_MsgId = 0x0; CAN_MessageInfo_t txInfo = { .idType = CAN_MSG_ID_STD, .dataLen = (len > 8U)?8U:len, .remoteFlag = RESET, .fdEn = DISABLE, .fdPadding = 0x00U, .brsEn = DISABLE }; /* CAN Send MsgID definition for E16 Head Light Left/Right mounting side */ if ((MEM_ADR_LR_DET == LEFT_ECU)&&(MEM_ADR_LR_DET_INV == LEFT_ECU_INV)) { u32CAN_Send_MsgId = (uint32_t)0x77B; } else if((MEM_ADR_LR_DET == RIGHT_ECU)&&(MEM_ADR_LR_DET_INV == RIGHT_ECU_INV)) { u32CAN_Send_MsgId = (uint32_t)0x77C; } else { u32CAN_Send_MsgId = (uint32_t)0x77B; } /* ********************************************************************** */ while(BUSY == status) { status = CAN_Send(CAN_ID, CAN_SEND_MB, &txInfo, u32CAN_Send_MsgId, data); } if(ERR == status) { ErrorTrap(); } }