This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I know the initialization process shown in the figure, and I am not sure about the other register parameters except for the CCE and INIT registers
I have also seen examples :D:\ti-processor-sdk-rtos-j721e-evm-08_04_00_06\mcusw\mcal_drv\mcal,
I can see the logic and process, but I cannot see the parameters in the registers and the operations on the registers when sending information, which makes me confused when developing drivers.
Please provide me with a function to initialize the MCU_MCAN0 register (including register parameters) and a function to send information (including register parameters). I would greatly appreciate it
Also uncertain about the write address of the message to be sent,
I filled in the register values myself according to my understanding of the manual as shown below, it must be incorrect because I didn't see any waveform changes on J1 MCU_CAN0.
To initialize the MCU_MCAN0 register, you would typically set the various configuration parameters such as the bit timing, message filters, and interrupt settings. For sending information, you would need to set up the message object with the appropriate data and then trigger the transmission.
Yes,I know the procedure must be like that you said.I have found a demo on DSP280039 about Initialize MCAN registers,Iearned it and program a myself code below.
/* * mcan.c * * Created on: 2023年11月30日 * Author: 18780 */ #include "cslr_soc_baseaddress.h" #include "cslr_mcu_ctrl_mmr.h" #include "cslr_main_ctrl_mmr.h" #include "cslr_wkup_ctrl_mmr.h" #include "Stdint.h" #include "hw_mcanss.h" #include "mcan.h" #include "common.h" MCAN_INIT gsMcanInitParams; MCAN_TxBufElement gsMCAN_TxBuf; // // Defines. // #define NUM_OF_MSG (2U) #define MCAN_STD_ID_FILTER_NUM (0U) #define MCAN_EXT_ID_FILTER_NUM (0U) #define MCAN_FIFO_0_NUM (0U) #define MCAN_FIFO_0_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES) #define MCAN_FIFO_1_NUM (0U) #define MCAN_FIFO_1_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES) #define MCAN_RX_BUFF_NUM (1U) #define MCAN_RX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES) #define MCAN_TX_BUFF_SIZE (NUM_OF_MSG) #define MCAN_TX_FQ_SIZE (0U) #define MCAN_TX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64BYTES) #define MCAN_TX_EVENT_SIZE (0U) #define MCANSS_STD_ID_FILTER_SIZE_WORDS (1U) #define MCANSS_EXT_ID_FILTER_SIZE_WORDS (2U) // // Defining Starting Addresses for Message RAM Sections, // (Calculated from Macros based on User defined configuration above) // #define MCAN_STD_ID_FILT_START_ADDR (0x0U) #define MCAN_EXT_ID_FILT_START_ADDR (MCAN_STD_ID_FILT_START_ADDR + ((MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U))) #define MCAN_FIFO_0_START_ADDR (MCAN_EXT_ID_FILT_START_ADDR + ((MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U))) #define MCAN_FIFO_1_START_ADDR (MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM)) #define MCAN_RX_BUFF_START_ADDR (MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM)) #define MCAN_TX_BUFF_START_ADDR (MCAN_RX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_RX_BUFF_ELEM_SIZE) * 4U * MCAN_RX_BUFF_NUM)) #define MCAN_TX_EVENT_START_ADDR (MCAN_TX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_TX_BUFF_ELEM_SIZE) * 4U * (MCAN_TX_BUFF_SIZE + MCAN_TX_FQ_SIZE))) uint32_t MCAN_getMsgObjSize(uint32_t elemSize) { uint32_t objSize[8] = {4,5,6,7,8,10,14,18}; return(objSize[elemSize]); } uint32_t MCAN_getDataSize(uint32_t dlc) { uint32_t dataSize[16] = {0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64}; return(dataSize[dlc]); } uint32_t MCAN_getTxBufReqPend(uint32_t baseAddr) { return(CSL_REG32_RD(baseAddr + MCAN_TXBRP)); } int32_t MCAN_txBufAddReq(uint32_t baseAddr, uint32_t bufNum) { int32_t status; uint32_t regVal; if(32 > bufNum) { regVal = CSL_REG32_RD(baseAddr + MCAN_TXBAR); regVal |= ((uint32_t) 1U << bufNum); CSL_REG32_WR(baseAddr + MCAN_TXBAR, regVal); status = STW_SOK; } else { status = STW_EFAIL; } return status; } void MCANInit( uint32_t MCANBaseAddr,MCAN_INIT *psMcanInitParams ) { uint32_t uMCAN_CCCR = 0; uint32_t uMCAN_NBTP = 0; uint32_t uMCAN_TDCR = 0; uint32_t uMCAN_SIDFC = 0; uint32_t uMCAN_XIDFC = 0; uint32_t uMCAN_RXESC = 0; uint32_t uMCAN_TXESC = 0; uint32_t uMCAN_RXBC = 0; uint32_t uMCAN_TXBC = 0; ClrData( psMcanInitParams,sizeof(MCAN_INIT) ); psMcanInitParams->sInitParams.fdMode = 0; psMcanInitParams->sInitParams.brsEnable = 0; psMcanInitParams->sInitParams.txpEnable = 0; psMcanInitParams->sInitParams.efbi = 0; psMcanInitParams->sInitParams.pxhddisable = 0; psMcanInitParams->sInitParams.darEnable = 1; psMcanInitParams->sBitTimingParams.dataRatePrescalar = 7; psMcanInitParams->sBitTimingParams.dataTimeSeg1 = 11; psMcanInitParams->sBitTimingParams.dataTimeSeg2 = 10; psMcanInitParams->sBitTimingParams.dataSynchJumpWidth = 8; psMcanInitParams->sTdcParams.tdcf = 0x14; psMcanInitParams->sTdcParams.tdco = 0x14; psMcanInitParams->sMsgRAMConfigParams.flssa = MCAN_STD_ID_FILT_START_ADDR; psMcanInitParams->sMsgRAMConfigParams.lss = MCAN_STD_ID_FILTER_NUM; psMcanInitParams->sMsgRAMConfigParams.rxBufElemSize = MCAN_RX_BUFF_ELEM_SIZE; psMcanInitParams->sMsgRAMConfigParams.rxBufStartAddr = MCAN_RX_BUFF_START_ADDR; psMcanInitParams->sMsgRAMConfigParams.txBufElemSize = MCAN_TX_BUFF_ELEM_SIZE; psMcanInitParams->sMsgRAMConfigParams.txBufMode = 1; psMcanInitParams->sMsgRAMConfigParams.txBufNum = MCAN_TX_BUFF_SIZE; psMcanInitParams->sMsgRAMConfigParams.txStartAddr = MCAN_TX_BUFF_START_ADDR; uMCAN_CCCR = CSL_REG32_RD(MCANBaseAddr + MCAN_CCCR); uMCAN_CCCR |= psMcanInitParams->sInitParams.fdMode << 8;//配置FOD位 uMCAN_CCCR |= psMcanInitParams->sInitParams.brsEnable << 9;//配置BRSE uMCAN_CCCR |= psMcanInitParams->sInitParams.txpEnable << 14;//配置TXP位 uMCAN_CCCR |= psMcanInitParams->sInitParams.efbi << 13;//配置FFBI位 uMCAN_CCCR |= psMcanInitParams->sInitParams.pxhddisable << 12;//配置PXHD位 uMCAN_CCCR |= psMcanInitParams->sInitParams.darEnable << 6;//配置DAR位 CSL_REG32_WR(MCANBaseAddr + MCAN_CCCR, uMCAN_CCCR); uMCAN_NBTP |= (psMcanInitParams->sBitTimingParams.dataRatePrescalar & 0x1F)<< 16; uMCAN_NBTP |= (psMcanInitParams->sBitTimingParams.dataSynchJumpWidth & 0xF); uMCAN_NBTP |= (psMcanInitParams->sBitTimingParams.dataTimeSeg1 & 0x1F) << 8; uMCAN_NBTP |= (psMcanInitParams->sBitTimingParams.dataTimeSeg2 & 0xF) << 4; CSL_REG32_WR(MCANBaseAddr + MCAN_NBTP, uMCAN_NBTP); uMCAN_TDCR |= psMcanInitParams->sTdcParams.tdcf & 0x7F; uMCAN_TDCR |= (psMcanInitParams->sTdcParams.tdco & 0x7F) << 8; CSL_REG32_WR(MCANBaseAddr + MCAN_TDCR, uMCAN_TDCR); uMCAN_SIDFC |= (psMcanInitParams->sMsgRAMConfigParams.flssa & 0x3FFF) << 2; uMCAN_SIDFC |= (psMcanInitParams->sMsgRAMConfigParams.lss & 0xFF) << 16; CSL_REG32_WR(MCANBaseAddr + MCAN_SIDFC, uMCAN_SIDFC); uMCAN_XIDFC |= (psMcanInitParams->sMsgRAMConfigParams.flesa & 0x3FFF) << 2; uMCAN_XIDFC |= (psMcanInitParams->sMsgRAMConfigParams.lse & 0x7F) << 16; CSL_REG32_WR(MCANBaseAddr + MCAN_XIDFC, uMCAN_XIDFC); uMCAN_RXESC |= (psMcanInitParams->sMsgRAMConfigParams.rxBufElemSize & 0x7 ) << 8 ; CSL_REG32_WR(MCANBaseAddr + MCAN_RXESC, uMCAN_RXESC); uMCAN_RXBC |= (psMcanInitParams->sMsgRAMConfigParams.rxBufStartAddr & 0x3FFF) << 2; CSL_REG32_WR(MCANBaseAddr + MCAN_RXBC, uMCAN_RXBC); uMCAN_TXESC |= psMcanInitParams->sMsgRAMConfigParams.txBufElemSize & 0x7; CSL_REG32_WR(MCANBaseAddr + MCAN_TXESC, uMCAN_TXESC); uMCAN_TXBC |= (psMcanInitParams->sMsgRAMConfigParams.txBufMode & 0x1) << 30; uMCAN_TXBC |= (psMcanInitParams->sMsgRAMConfigParams.txBufNum & 0x3F) << 16; uMCAN_TXBC |= (psMcanInitParams->sMsgRAMConfigParams.txStartAddr & 0x3FFF) << 2; CSL_REG32_WR(MCANBaseAddr + MCAN_TXBC, uMCAN_TXBC); } void MCAN_writeMsg(uint32_t baseAddr, uint32_t elemAddr, const MCAN_TxBufElement *elem) { uint32_t regVal = 0, loopCnt = 0U; regVal = 0U; regVal |= (((uint32_t) (elem->id << MCANSS_TX_BUFFER_ELEM_ID_SHIFT)) | ((uint32_t) (elem->rtr << MCANSS_TX_BUFFER_ELEM_RTR_SHIFT)) | ((uint32_t) (elem->xtd << MCANSS_TX_BUFFER_ELEM_XTD_SHIFT)) | ((uint32_t) (elem->esi << MCANSS_TX_BUFFER_ELEM_ESI_SHIFT))); CSL_REG32_WR(baseAddr + elemAddr, regVal); elemAddr += 4U; regVal = 0U; regVal |= ((uint32_t) (elem->dlc << MCANSS_TX_BUFFER_ELEM_DLC_SHIFT)) | ((uint32_t) (elem->brs << MCANSS_TX_BUFFER_ELEM_BRS_SHIFT)) | ((uint32_t) (elem->fdf << MCANSS_TX_BUFFER_ELEM_FDF_SHIFT)) | ((uint32_t) (elem->efc << MCANSS_TX_BUFFER_ELEM_EFC_SHIFT)) | ((uint32_t) (elem->mm << MCANSS_TX_BUFFER_ELEM_MM_SHIFT)); CSL_REG32_WR(baseAddr + elemAddr, regVal); elemAddr += 4U; loopCnt = 0U; /* Framing words out of the payload bytes and writing it to message RAM */ while((4U <= (MCAN_getDataSize(elem->dlc) - loopCnt)) && (0U != (MCAN_getDataSize(elem->dlc) - loopCnt))) { regVal = 0U; regVal |= ((uint32_t)elem->data[loopCnt] | ((uint32_t)elem->data[(loopCnt + 1U)] << 8U) | ((uint32_t)elem->data[(loopCnt + 2U)] << 16U) | ((uint32_t)elem->data[(loopCnt + 3U)] << 24U)); CSL_REG32_WR(baseAddr + elemAddr, regVal); elemAddr += 4U; loopCnt += 4U; } /* Framing a word out of remaining payload bytes and writing it to * message RAM */ if(0U < (MCAN_getDataSize(elem->dlc) - loopCnt)) { regVal = 0U; regVal |= ((uint32_t)elem->data[loopCnt] | ((uint32_t)elem->data[(loopCnt + 1U)] << 8U) | ((uint32_t)elem->data[(loopCnt + 2U)] << 16U) | ((uint32_t)elem->data[(loopCnt + 3U)] << 24U)); CSL_REG32_WR(baseAddr + elemAddr, regVal); } } void MCAN_writeMsgRam(uint32_t baseAddr, uint32_t bufNum, const MCAN_TxBufElement *elem) { uint32_t startAddr = 0U, elemSize = 0U, elemAddr = 0U; startAddr = CSL_REG32_RD(baseAddr + MCAN_TXBC); elemSize = CSL_REG32_RD(baseAddr + MCAN_TXESC) & 0x7; startAddr = (uint32_t) (startAddr >> 2U) & 0x3FFF; elemSize = MCAN_getMsgObjSize(elemSize); elemSize *= 4U; elemAddr = startAddr + (elemSize * bufNum); elemAddr += MCAN_MCAN_MSG_MEM; MCAN_writeMsg(CSL_MCU_MCAN0_MSGMEM_RAM_BASE, elemAddr, elem); }
However,I'v got the CAN message like this:
Baudrate is not 500Kbps,there is no DATA field,control field has no ID erther.I have tried my best to read the register manual :J721E_registers5.pdf section 4.2 MCAN,I've no idear.
if I set:
#define MCAN_RX_BUFF_NUM (0U)//without receive function
I can get a correct struct of CAN message with wrong baudrate and wrong ID ,as is shown below:
By the way, for the same BitTimingParams, the debugging results last night and this morning were different. Last night, it was still 2us each bit, and this morning it was 5.4us each bit.
I really don't know how to solve this problem. I don't know how to solve it
Regarding the differences in debugging results, it's possible that there may be some environmental or configuration changes causing the variation in timing.
Additionally, double-check the BitTimingParams and ensure that they are set consistently.
Look forward to your feedback