Part Number: LAUNCHXL-F28379D
Tool/software:
Hello forum,
I'm facing an issue with the triggering of the Tx interrupt for the channel B canbus regarding the f2837d launchpad.
I think I've set everything properly but the interrupt service routine function is either never entered or, worse, entered continously in kind of a never ending cycle (I'm 100% missing something).
As long as I exclude the interrupt part, the message is trasmitted correctly since I certified it with a can analyzer.
I attach here the main lines concerning the canbus operations combined with the interrupt.
EALLOW;
PieVectTable.CANB0_INT = &canb_isr;
PieCtrlRegs.PIEIER9.bit.INTx7 = 1;
IER |= M_INT9; // abilito l'interrupt per la cputimer1
EDIS;
CanbRegs.CAN_CTL.bit.DAR = 0; // Disable automatic retransmission
CanbRegs.CAN_CTL.bit.Test = 0; // Enable test mode and select external loopback
CanbRegs.CAN_TEST.bit.EXL = 0; // External Loopback
//
// Enable test mode and select external loopback
//
//
// Initialize the message object that will be used for sending CAN
// messages.
//
setupMessageObject(CAN_TX_MSG_OBJ_1, CAN_MSG_ID_0, MSG_OBJ_TYPE_TRANSMIT, 1);
#if 0
setupMessageObject(CAN_TX_MSG_OBJ_2, CAN_MSG_ID_1, MSG_OBJ_TYPE_TRANSMIT, 1);
setupMessageObject(CAN_TX_MSG_OBJ_3, CAN_MSG_ID_2, MSG_OBJ_TYPE_TRANSMIT, 0);
setupMessageObject(CAN_TX_MSG_OBJ_4, CAN_MSG_ID_3, MSG_OBJ_TYPE_TRANSMIT, 0);
setupMessageObject(CAN_TX_MSG_OBJ_5, CAN_MSG_ID_4, MSG_OBJ_TYPE_TRANSMIT, 0);
#endif
CanbRegs.CAN_CTL.bit.Init = 0; // Enable the CAN for operation (0 processa i messaggi normalmente)
CanbRegs.CAN_CTL.bit.IE0 = 1;
CanbRegs.CAN_CTL.bit.SIE = 1;
CanbRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
while(1){
sendCANMessage(CAN_TX_MSG_OBJ_1);
DELAY_US(1000*1000);
}
FUNCTIONS :
void setupMessageObject(uint32_t objID, uint32_t msgID, msgObjType msgType, uint16_t int_tx)
{
//
// Use Shadow variable for IF1CMD. IF1CMD should be written to in
// single 32-bit write.
//
union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
//
// Wait for busy bit to clear.
//
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Clear and Write out the registers to program the message object.
//
CAN_IF1CMD_SHADOW.all = 0;
CanbRegs.CAN_IF1MSK.all = 0;
CanbRegs.CAN_IF1ARB.all = 0;
CanbRegs.CAN_IF1MCTL.all = 0;
//
// Set the Control, Mask, and Arb bit so that they get transferred to the
// Message object.
//
CAN_IF1CMD_SHADOW.bit.Control = 1;
CAN_IF1CMD_SHADOW.bit.Arb = 1;
CAN_IF1CMD_SHADOW.bit.Mask = 1;
CAN_IF1CMD_SHADOW.bit.DIR = 1;
//
// Set direction to transmit
//
if(msgType == MSG_OBJ_TYPE_TRANSMIT)
{
CanbRegs.CAN_IF1ARB.bit.Dir = 1;
}
//
// Set Message ID (this example assumes 11 bit ID mask)
//
CanbRegs.CAN_IF1ARB.bit.ID = (msgID << CAN_MSG_ID_SHIFT);
CanbRegs.CAN_IF1ARB.bit.MsgVal = 1;
//
// Set the data length since this is set for all transfers. This is
// also a single transfer and not a FIFO transfer so set EOB bit.
//
CanbRegs.CAN_IF1MCTL.bit.DLC = messageSize;
CanbRegs.CAN_IF1MCTL.bit.EoB = 1;
// Request a Tx insterrupt
CanbRegs.CAN_IF1MCTL.bit.TxIE = int_tx;
CanbRegs.CAN_IF1MCTL.bit.IntPnd = 0;
//
// Transfer data to message object RAM
//
CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}
//
// sendCANMessage - Transmit data from the specified message object
//
void sendCANMessage(uint32_t objID)
{
//
// Use Shadow variable for IF1CMD. IF1CMD should be written to in
// single 32-bit write.
//
union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
//
// Wait for busy bit to clear.
//
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Write data to transfer into DATA-A and DATA-B interface registers
//
uint16_t index;
for(index = 0; index < messageSize; index++)
{
switch(index)
{
case 0:
CanbRegs.CAN_IF1DATA.bit.Data_0 = ucTXMsgData[index];
break;
case 1:
CanbRegs.CAN_IF1DATA.bit.Data_1 = ucTXMsgData[index];
break;
case 2:
CanbRegs.CAN_IF1DATA.bit.Data_2 = ucTXMsgData[index];
break;
case 3:
CanbRegs.CAN_IF1DATA.bit.Data_3 = ucTXMsgData[index];
break;
case 4:
CanbRegs.CAN_IF1DATB.bit.Data_4 = ucTXMsgData[index];
break;
case 5:
CanbRegs.CAN_IF1DATB.bit.Data_5 = ucTXMsgData[index];
break;
case 6:
CanbRegs.CAN_IF1DATB.bit.Data_6 = ucTXMsgData[index];
break;
case 7:
CanbRegs.CAN_IF1DATB.bit.Data_7 = ucTXMsgData[index];
break;
}
}
//
// Set Direction to write and set DATA-A/DATA-B to be transfered to
// message object
//
CAN_IF1CMD_SHADOW.all = 0;
CAN_IF1CMD_SHADOW.bit.DIR = 1;
CAN_IF1CMD_SHADOW.bit.DATA_A = 1;
CAN_IF1CMD_SHADOW.bit.DATA_B = 1;
//
// Set Tx Request Bit
//
CAN_IF1CMD_SHADOW.bit.TXRQST = 1;
//
// Transfer the message object to the message object specified by
// objID.
//
CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
}
__interrupt void canb_isr(void){
dbg_can++;
if((CanbRegs.CAN_IF1MCTL.bit.IntPnd) && (CanbRegs.CAN_INT.bit.INT0ID == 1)){
GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
comando_feeder = 0;
CanbRegs.CAN_IF1CMD.bit.ClrIntPnd = 1;
}
CanbRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}
2/3 functions are built-in functions basically, the isr one is customized.
Can anyone give me the right tip?
Thanks in advance!
Have a nice day
Alessandro
Some comments may be related to previous lines I'm not working on anymore (sorry for possible misunderstanding).