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.

TMS320F28377D: DCAN unable to enter receive interrupt during normal use

Part Number: TMS320F28377D

I am using the communication function of the F28377D DCAN module,during normal use, there is a very low probability that the CAN communication module of F28377D cannot receive data sent from outside, but its sending function is normal at this time.After carefully checking the code, I found that the program had not been able to enter receive interrupt at this time. At this point, I attempted to reset the peripheral of DCAN and reinitialize the related functions, but it did not work. I tried to read the register CAN_ O_ ERRC searched for the specific error, but could not find the error flag. The relevant bits of this register are all 0, and I really don't know what caused it. I hope everyone can help me, thank you!

Here is my specific code:

volatile unsigned long g_CANATxMsgCount = 0;
volatile unsigned long g_CANARxMsgCount = 0;
volatile unsigned long g_CANAErrCount = 0;
volatile unsigned long g_CANAErrFlag = 0;

tCANMsgObject sRXCANAMessage[8];

unsigned char ucRXCANAMsgData[64];

volatile struct CAN_REG CAN[2];

volatile unsigned int CAN_RX_INT_Judge[2] = {0, 0};

volatile unsigned int ulStatusA = 0;
volatile unsigned int ulStatus_A = 0;
volatile unsigned int CANA_INT_Flag = 0;

void BSPCANAInitGpio(void)
{

EALLOW; 


GPIO_SetupPinMux(30, GPIO_MUX_CPU1, 1);//GPIO30 - CANRXA
GPIO_SetupPinMux(31, GPIO_MUX_CPU1, 1);//GPIO31 - CANTXA

EDIS;


GPIO_SetupPinOptions(30, GPIO_INPUT, GPIO_ASYNC); //CANRXA
GPIO_SetupPinOptions(31, GPIO_OUTPUT, GPIO_PUSHPULL);//CANTXA
}

void BSPCANAInit(void)//initialize the eCAN-A module
{
Uint16 i, Length;
Uint16 *Ptr_Obj;

CANInit(CANA_BASE);

CANClkSourceSelect(CANA_BASE, 0);

CANBitRateSet(CANA_BASE, 200000000, (unsigned long)gBSPConfig.CanaBaudRate * 1000);//250k


CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);


HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_ABO; //Auto-Bus-On Enable

HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_WUBA;//Wake Up on Bus Activity

HWREG(CANA_BASE + CAN_O_CTL) |= CAN_CTL_DAR;//Disable Automatic Retransmission

CANEnable(CANA_BASE);


CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);


for(i = 24; i < 32; i++)
{
sRXCANAMessage[i - 24].ui32MsgID = 0x08FFF100 | i; // CAN message ID - use 1
sRXCANAMessage[i - 24].ui32MsgIDMask = 0; // no mask needed for TX
sRXCANAMessage[i - 24].ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_EXT_FILTER;// enable interrupt on RX
sRXCANAMessage[i - 24].ui32MsgLen = 8; // size of message is 8
sRXCANAMessage[i - 24].pucMsgData = (void *)&ucRXCANAMsgData[(i - 24) * 8];// ptr to message content


CANMessageSet(CANA_BASE, (i + 1), (void *)&sRXCANAMessage[i - 24], MSG_OBJ_TYPE_RX);
}


}

#pragma CODE_SECTION(canaISR, ".TI.ramfunc");
interrupt void canaISR(void)
{
unsigned long ulStatus;

ulStatusA++;

CAN_RX_INT_Judge[1] = 0;

// Read the CAN interrupt status to find the cause of the interrupt
ulStatus = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

// If the cause is a controller status interrupt, then get the status
if(ulStatus == CAN_INT_INT0ID_STATUS)
{
ulStatus = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);

//Check to see if an error occurred.
if(((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 7)
&& ((ulStatus & ~(CAN_ES_TXOK | CAN_ES_RXOK)) != 0))
{
g_CANAErrCount++;

g_CANAErrFlag = 1;
}
}
else if(ulStatus == 1)
{
CANIntClear(CANA_BASE, 1);

g_CANATxMsgCount++;

g_CANAErrFlag = 0;
}
else if((ulStatus >= 25) && (ulStatus <= 32))
{
CANMessageGet(CANA_BASE, ulStatus, (void *)&sRXCANAMessage[ulStatus - 25], true);

ulStatus_A = ulStatus;
CANA_INT_Flag = 1;

CANIntClear(CANA_BASE, ulStatus);

g_CANARxMsgCount++;

g_CANAErrFlag = 0;
}
else
{

}

//canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}

void BSPCANTxDataBuffInByteAlterDlc(u8 CANNum, u8 DLC, u32 ID, u8* Data)
{
tCANMsgObject sTXCANMessage;
u16 i;
Uint32 cmd_regdata = 0;

if(CANNum >= 2){CANNum = 0;}//CAN路数错误,设为0
if(DLC > 8){DLC = 8;} //dlc取值错误, 设为8

sTXCANMessage.ui32MsgID = ID; // CAN message ID - use
sTXCANMessage.ui32MsgIDMask = 0; // no mask needed for TX
sTXCANMessage.ui32Flags = /*MSG_OBJ_EXTENDED_ID*/MSG_OBJ_NO_FLAGS;// an extended identifier
sTXCANMessage.ui32MsgLen = DLC; // size of message is 8
sTXCANMessage.pucMsgData = Data; // ptr to message content


if(CANNum == 0)
{
//IF1 Command Register
cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
HWREGH(CANB_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;


for(i = 1; i <= 24; i++)
{
HWREGH(CANB_BASE + CAN_O_IF1CMD) = i;

while(HWREG(CANB_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);


if((HWREG(CANB_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
}
if(i >= 25){return;}

CANMessageSet(CANB_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
}
else
{
//IF1 Command Register
cmd_regdata = CAN_IF1CMD_ARB | CAN_IF1CMD_MASK | CAN_IF1CMD_CONTROL;
HWREGH(CANA_BASE + CAN_O_IF1CMD + 2) = cmd_regdata >> 16;


for(i = 1; i <= 24; i++)
{
HWREGH(CANA_BASE + CAN_O_IF1CMD) = i;

while(HWREG(CANA_BASE + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY);


if((HWREG(CANA_BASE + CAN_O_IF1MCTL) & CAN_IF1MCTL_TXRQST) == 0){break;}
}
if(i >= 25){return;}

CANMessageSet(CANA_BASE, i, (void *)&sTXCANMessage, MSG_OBJ_TYPE_TX);
}

}

u8 CAN_WARN_Flag[2] = {0, 0};
void BSPCANS_WARN_Protect(u8 CANNum)
{
Uint32 regbase;

if(CANNum == 0){regbase = CANB_BASE;}
else {regbase = CANA_BASE;}

if(HWREG(regbase + CAN_O_ES) & CAN_ES_EWARN)
{
EALLOW;
HWREG(regbase + CAN_O_CTL) = CAN_CTL_INIT;

HWREG(regbase + CAN_O_CTL) |= CAN_CTL_SWR;
HWREG(regbase + CAN_O_CTL) |= CAN_CTL_DAR;
HWREG(regbase + CAN_O_CTL) |= CAN_CTL_ABO;
HWREG(regbase + CAN_O_CTL) |= CAN_CTL_WUBA;

if(CANNum == 0){BSPCANBInit();}
else {BSPCANAInit();}

HWREG(regbase + CAN_O_CTL) &= ~CAN_CTL_INIT;
EDIS;

CAN_WARN_Flag[CANNum] = 1;
}
else
{
CAN_WARN_Flag[CANNum] = 0;
}
}


void BSPCANS_Err_Counter(u8 CANNum)
{
Uint32 regbase;

if(CANNum == 0){regbase = CANB_BASE;}
else {regbase = CANA_BASE;}

CAN[CANNum].CAN_Err.bit.TEC = (HWREG(regbase + CAN_O_ERRC) >> 0) & 0xff;
CAN[CANNum].CAN_Err.bit.REC = (HWREG(regbase + CAN_O_ERRC) >> 8) & 0x7f;
CAN[CANNum].CAN_Err.bit.RP = (HWREG(regbase + CAN_O_ERRC) >> 15) & 0x01;

CAN[CANNum].CAN_Sta.bit.LEC = (HWREG(regbase + CAN_O_ES) >> 0) & 0x07;
CAN[CANNum].CAN_Sta.bit.TxOk = (HWREG(regbase + CAN_O_ES) >> 3) & 0x01;
CAN[CANNum].CAN_Sta.bit.RxOk = (HWREG(regbase + CAN_O_ES) >> 4) & 0x01;
CAN[CANNum].CAN_Sta.bit.EPass = (HWREG(regbase + CAN_O_ES) >> 5) & 0x01;
CAN[CANNum].CAN_Sta.bit.EWarn = (HWREG(regbase + CAN_O_ES) >> 6) & 0x01;
CAN[CANNum].CAN_Sta.bit.BOff = (HWREG(regbase + CAN_O_ES) >> 7) & 0x01;
CAN[CANNum].CAN_Sta.bit.PER = (HWREG(regbase + CAN_O_ES) >> 8) & 0x01;
}