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.
Hi Team ,
Anyone help me in CAN interfacing ,i done initialization same as example code bitfield CAN and try with loopback, in loopback its working perfect, and coming in interrupt also but once i remove loopback mode , means loopback mode is 0 and test register also zero. then its stop working , it will not going to CAN interrupt , anyone please guide me, and on more clarification using GPIO 32 and GPIO 33 , so any details specification needed in initialization of these GPIO as CAN TX and CANRX
.
Sanmati,
You mentioned that when you turned off loopback mode, the CAN operation is not working. Please note that a transceiver is required for successful communication as CAN protocol expects an ACK signal.
You can refer to the following app note for common debugging strategies.
Thanks.
Hi sahil ,
All Hardware related to CAN is added on Board But it will not going to CAN interrupt , please refer below configuration for your reference
GPIO_SetupPinMux(32, GPIO_MUX_CPU1, 10);
GPIO_SetupPinOptions(32, GPIO_OUTPUT, GPIO_PUSHPULL);
GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 10);
GPIO_SetupPinOptions(33, GPIO_OUTPUT, GPIO_ASYNC);
void InitCAN(void)
{
ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0;
int16_t iMsg;
//
// Place CAN controller in init state, regardless of previous state. This
// will put controller in idle, and allow the message object RAM to be
// programmed.
//
CanaRegs.CAN_CTL.bit.Init = 1;
CanaRegs.CAN_CTL.bit.SWR = 1;
//
// Wait for busy bit to clear
//
while(CanaRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Clear the message value bit in the arbitration register. This indicates
// the message is not valid and is a "safe" condition to leave the message
// object. The same arb reg is used to program all the message objects.
//
CanaRegs.CAN_IF1CMD.bit.DIR = 1;
CanaRegs.CAN_IF1CMD.bit.Arb = 1;
CanaRegs.CAN_IF1CMD.bit.Control = 1;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.CAN_IF1MCTL.all = 0;
CanaRegs.CAN_CTL.bit.DAR = 1;
CanaRegs.CAN_IF2CMD.bit.DIR = 1;
CanaRegs.CAN_IF2CMD.bit.Arb = 1;
CanaRegs.CAN_IF2CMD.bit.Control = 1;
CanaRegs.CAN_IF2ARB.all = 0;
CanaRegs.CAN_IF2MCTL.all = 0;
CanaRegs.CAN_CTL.bit.ABO = 1;
CanaRegs.CAN_ABOTR =0x02;
// Loop through to program all 32 message objects
for(iMsg = 1; iMsg <= 32; iMsg+=2)
{
//
// Wait for busy bit to clear
//
while(CanaRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Initiate programming the message object
//
CanaRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg;
//
// Wait for busy bit to clear
//
while(CanaRegs.CAN_IF2CMD.bit.Busy)
{
}
//
// Initiate programming the message object
//
CanaRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1;
}
//
// Acknowledge any pending status interrupts.
//
volatile uint32_t discardRead = CanaRegs.CAN_ES.all;
}
uint32_t status = setCANBitRate(100000000, 500000);
uint32_t setCANBitRate(uint32_t sourceClock, uint32_t bitRate)
{
uint32_t desiredRatio;
uint32_t canBits;
uint32_t preDivide;
uint32_t regValue;
uint16_t canControlValue;
//
// Calculate the desired clock rate.
//
desiredRatio = sourceClock / bitRate;
//
// Make sure that the Desired Ratio is not too large. This enforces the
// requirement that the bit rate is larger than requested.
//
if((sourceClock / desiredRatio) > bitRate)
{
desiredRatio += 1;
}
//
// Check all possible values to find a matching value.
//
while(desiredRatio <= CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR)
{
//
// Loop through all possible CAN bit divisors.
//
for(canBits = CAN_MAX_BIT_DIVISOR;
canBits >= CAN_MIN_BIT_DIVISOR;
canBits--)
{
//
// For a given CAN bit divisor save the pre divisor.
//
preDivide = desiredRatio / canBits;
//
// If the calculated divisors match the desired clock ratio then
// return these bit rate and set the CAN bit timing.
//
if((preDivide * canBits) == desiredRatio)
{
//
// Start building the bit timing value by adding the bit timing
// in time quanta.
//
regValue = canBitValues[canBits - CAN_MIN_BIT_DIVISOR];
//
// To set the bit timing register, the controller must be
// placed
// in init mode (if not already), and also configuration change
// bit enabled. The state of the register should be saved
// so it can be restored.
//
canControlValue = CanaRegs.CAN_CTL.all;
CanaRegs.CAN_CTL.bit.Init = 1;
CanaRegs.CAN_CTL.bit.CCE = 1;
//
// Now add in the pre-scalar on the bit rate.
//
regValue |= ((preDivide - 1) & CAN_BTR_BRP_M) |
(((preDivide - 1) << 10) & CAN_BTR_BRPE_M);
//
// Set the clock bits in the and the bits of the
// pre-scalar.
//
CanaRegs.CAN_BTR.all = regValue;
//
// Restore the saved CAN Control register.
//
CanaRegs.CAN_CTL.all = canControlValue;
//
// Return the computed bit rate.
//
return(sourceClock / ( preDivide * canBits));
}
}
//
// Move the divisor up one and look again. Only in rare cases are
// more than 2 loops required to find the value.
//
desiredRatio++;
}
return 0;
}
//
// setupMessageObject - Setup message object as Transmit or Receive
//
void setupMessageObject(uint32_t objID, uint32_t msgID, msgObjType msgType, int16_t msgEnableInterrupt)
{
//
// Wait for busy bit to clear.
//
while(CanaRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Clear and Write out the registers to program the message object.
//
CanaRegs.CAN_IF1CMD.all = 0;
CanaRegs.CAN_IF1MSK.all = 0;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.CAN_IF1MCTL.all = 0;
//
// Set the Control, Mask, and Arb bit so that they get transferred to the
// Message object.
//
CanaRegs.CAN_IF1CMD.bit.Control = 1;
CanaRegs.CAN_IF1CMD.bit.Arb = 1;
CanaRegs.CAN_IF1CMD.bit.Mask = 1;
CanaRegs.CAN_IF1CMD.bit.DIR = 1;
//
// Set direction to transmit
//
if(msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;
}
if(msgType == MSG_OBJ_TYPE_RECEIVE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;
}
if(msgType == MSG_OBJ_TYPE_RXTX_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
CanaRegs.CAN_IF1ARB.bit.Xtd =0;
CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
CanaRegs.CAN_IF1MCTL.bit.UMask =1;
CanaRegs.CAN_IF1MSK.bit.MDir =1;
CanaRegs.CAN_IF1MSK.bit.MXtd =0;
CanaRegs.CAN_IF1MSK.bit.Msk = 0x1FFFFFFF; //msgID;
}
if(msgEnableInterrupt == Enable_Rxinterrupt)
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
CanaRegs.CAN_CTL.bit.IE0 =1;
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;
}
//
// Set Message ID (this example assumes 11 bit ID mask)
CanaRegs.CAN_IF1ARB.bit.ID = msgID;
CanaRegs.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.
//
CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
CanaRegs.CAN_IF1MCTL.bit.EoB = 1;
// Transfer data to message object RAM
CanaRegs.CAN_IF1CMD.bit.MSG_NUM = objID;
}
Okay, will review the code and get back to you.
What device/node are you using to receive the frames? Please note that you need a minimum of two nodes on the CAN bus for successful communication.
Thanks.
Sanmati,
Is there a reason why you are using bit-field as opposed to Driverlib? Note that support for bit-field is deprecated and only Driverlib will be supported/updated moving forward.
I strongly encourage you to take a look at the debug tips in SPRACE5A. And try a C2000ware Driverlib example on your hardware. Since these are tested examples, you can use them to determine if there are any issues in your H/W. It is important to determine whether you have a H/W issue or a S/W issue.
Hareesh,
I will not possible to use drivellib, because already my other application and other code is working in bitfield format and for only can i try to add drivelib its coming another 10 error, so please help me and guide me only for use bitfield
Sanmati,
Within the setupMessageObject function, one thing to note is that IF1CMD should be written in a single 32-bit write. That is because, after a write to this register, the Busy bit is set and it takes a certain number of cycles for the transfer of data from the IFx registers to the Message RAM.
Specifically in the case mentioned below, that might cause erroneous writes.
Instead, a shadow variable can be defined and all values can be fed to it and it can be written to in a single 32-bit write as showed below:
Thanks.
Hi sahil ,
we are already tried this also ,please find the below config if any changes need please revert back.
void setupMessageObject(uint32_t objID, uint32_t msgID, msgObjType msgType, int16_t msgEnableInterrupt)
{
union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
//
// Wait for busy bit to clear.
//
while(CanaRegs.CAN_IF1CMD.bit.Busy)
{
}
//
// Clear and Write out the registers to program the message object.
//
CAN_IF1CMD_SHADOW.all = 0;
CanaRegs.CAN_IF1CMD.all = 0;
CanaRegs.CAN_IF1MSK.all = 0;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.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;
// CanaRegs.CAN_IF1CMD.bit.Control = 1;
// CanaRegs.CAN_IF1CMD.bit.Arb = 1;
// CanaRegs.CAN_IF1CMD.bit.Mask = 1;
// CanaRegs.CAN_IF1CMD.bit.DIR = 1;
//
// Set direction to transmit
//
if(msgType == MSG_OBJ_TYPE_TRANSMIT)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
}
if(msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;
}
if(msgType == MSG_OBJ_TYPE_RECEIVE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;
}
if(msgType == MSG_OBJ_TYPE_RXTX_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
CanaRegs.CAN_IF1ARB.bit.Xtd =0;
CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
CanaRegs.CAN_IF1MCTL.bit.UMask =1;
CanaRegs.CAN_IF1MSK.bit.MDir =1;
CanaRegs.CAN_IF1MSK.bit.MXtd =0;
CanaRegs.CAN_IF1MSK.bit.Msk = 0x1FFFFFFF; //msgID;
}
if(msgEnableInterrupt == Enable_Rxinterrupt)
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
CanaRegs.CAN_CTL.bit.IE0 =1;
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;
CanaRegs.CAN_CTL.bit.EIE =1;
CanaRegs.CAN_CTL.bit.SIE =1;// 3 Error Interrupt Enable
}
else
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =0;
CanaRegs.CAN_CTL.bit.IE0 =0;
CanaRegs.CAN_CTL.bit.EIE =0;
CanaRegs.CAN_CTL.bit.SIE =0;// 3 Error Interrupt Enable
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =0;
}
//
// Set Message ID (this example assumes 11 bit ID mask)
//
CanaRegs.CAN_IF1ARB.bit.ID = msgID;
CanaRegs.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.
//
CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
CanaRegs.CAN_IF1MCTL.bit.EoB = 1;
//
// Transfer data to message object RAM
//
CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
Thanks .
Sanmati,
Debugging code is not something we can support on e2e. Can you please run a Driverlib example on your hardware and see if it works? This way, we can at least ascertain there are no hardware issues in your setup. You can then move your focus to software.