tc27x cant receive CAN message from canoe using VN5610A CAN interface

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User16362
Level 1
Level 1
Hello,

I made simple program in TASKING IDE where im sending CAN message from CAN node1 to CAN node0. I managed to send and receive CAN message with and without interrupt.

Now what i should do is connect tc27x board with CAN box(VN5610A CAN interface), send CAN message from CANOE and receive it on board but i cant get it working. Im using same code where sending
message from CAN node1 to CAN node0 is working properly, but when i connect CAN node0 to CAN interface, it just wont receive message. I tried using wires with and without termination resistors but still
no success.

My program never exits from while loop in RecV() function, even tho im sure i sent CAN message from CANOE.
Here is my code:

void RecV(void);
void SendMessage(void);
const unsigned id = 0x100 ;

IfxMultican_Can can;
IfxMultican_Can_NodeConfig canNodeConfig;
IfxMultican_Can_Node canSrcNode;
IfxMultican_Can_Node canDstNode;

IfxMultican_Can_MsgObj canSrcMsgObj;
IfxMultican_Can_MsgObj canDstMsgObj;

int main(void)
{
IfxMultican_Can_Config canConfig;
IfxMultican_Can_initModuleConfig(&canConfig, &MODULE_CAN);
IfxMultican_Can_initModule(&can, &canConfig);


IfxMultican_Can_Node_initConfig(&canNodeConfig,&can);
//Node 1
canNodeConfig.baudrate = 500000;
canNodeConfig.nodeId = IfxMultican_NodeId_1;
canNodeConfig.rxPin = &IfxMultican_RXD1B_P14_1_IN;
canNodeConfig.rxPinMode = IfxPort_InputMode_pullUp;
canNodeConfig.txPin = &IfxMultican_TXD1_P14_0_OUT;
canNodeConfig.txPinMode = IfxPort_OutputMode_pushPull;

IfxMultican_Can_Node_init(&canDstNode, &canNodeConfig);

//Node 0

canNodeConfig.nodeId = IfxMultican_NodeId_0;
canNodeConfig.rxPin = &IfxMultican_RXD0B_P20_7_IN;
canNodeConfig.rxPinMode = IfxPort_InputMode_pullUp;
canNodeConfig.txPin = &IfxMultican_TXD0_P20_8_OUT;
canNodeConfig.txPinMode = IfxPort_OutputMode_pushPull;


IfxMultican_Can_Node_init(&canSrcNode, &canNodeConfig);


//Msg

IfxMultican_Can_MsgObjConfig canMsgObjConfig;

IfxMultican_Can_MsgObj_initConfig(&canMsgObjConfig, &canSrcNode);

canMsgObjConfig.msgObjId = 0;
canMsgObjConfig.messageId = id;
canMsgObjConfig.frame = IfxMultican_Frame_transmit;
canMsgObjConfig.control.messageLen = IfxMultican_DataLengthCode_8;
canMsgObjConfig.control.extendedFrame = FALSE;
canMsgObjConfig.control.matchingId = FALSE;
IfxMultican_Can_MsgObj_init(&canSrcMsgObj, &canMsgObjConfig);

//Recv
IfxMultican_Can_MsgObj_initConfig(&canMsgObjConfig, &canDstNode);

canMsgObjConfig.msgObjId = 1;
canMsgObjConfig.messageId = id;
canMsgObjConfig.frame = IfxMultican_Frame_receive;
canMsgObjConfig.control.messageLen = IfxMultican_DataLengthCode_8;
canMsgObjConfig.control.extendedFrame = FALSE;
canMsgObjConfig.control.matchingId = FALSE;

IfxMultican_Can_MsgObj_init(&canDstMsgObj, &canMsgObjConfig);
CanNodeSetInterrupt(IfxMultican_RXD1B_P14_1_IN,IfxMultican_SrcId_0,IfxSrc_Tos_cpu0,IFX_INTPRIO_CAN_NODE1);

//SendMessage();
RecV();
}

void RecV()
{
IfxMultican_Message msg;
IfxMultican_Message_init(&msg, 0xdead, 0xdeadbeef, 0xdeadbeef, IfxMultican_DataLengthCode_8); // start with invalid values
// wait until Multican received a new message
while( !IfxMultican_Can_MsgObj_isRxPending(&canDstMsgObj) )
{
printf("Waiting for msg...\n");
}
// read message
IfxMultican_Status readStatus = IfxMultican_Can_MsgObj_readMessage(&canDstMsgObj, &msg);

printf("Received something!- %x %x\n",msg.data[0],msg.data[1]);
}

void SendMessage()
{
IfxMultican_Message msgSend;

IfxMultican_Message_init(&msgSend, id,0x00000000,0x00000000,IfxMultican_DataLengthCode_8);
while( IfxMultican_Can_MsgObj_sendMessage(&canSrcMsgObj,&msgSend) == IfxMultican_Status_notSentBusy)
{
printf("CAN bus busy\n");
}
}
0 Likes
7 Replies
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Hi specimen. What CAN bit timing parameters are you using on the Vector side? By default, the iLLD uses these parameters - see IfxCan_Can_initNodeConfig in IfxCan_Can.c:

.baudRate = {
.baudrate = 500000,
.samplePoint = 8000,
.syncJumpWidth = 3,
.prescaler = 0,
.timeSegment1 = 3,
.timeSegment2 = 10
},

Make sure the same parameters are used between the AURIX and the Vector tool.
0 Likes
User16362
Level 1
Level 1
Thank you UC_wrangler for advice. This is info I found while digging around in IfxCan_regdef.h file.


typedef struct _Ifx_CAN_N_BTR_Bits
{
unsigned int BRP : 6; /**< \brief [5:0] Baud Rate Prescaler (rw) */
unsigned int SJW : 2; /**< \brief [7:6] (Re) Synchronization Jump Width (rw) */
unsigned int TSEG1 : 4; /**< \brief [11:8] Time Segment Before Sample Point (rw) */
unsigned int TSEG2 : 3; /**< \brief [14:12] Time Segment After Sample Point (rw) */
unsigned int DIV8 : 1; /**< \brief [15:15] Divide Prescaler Clock by 8 (rw) */
unsigned int reserved_16 : 16; /**< \brief \internal Reserved */
} Ifx_CAN_N_BTR_Bits;

I have also attached screenshot of vector CAN interface settings. Should TSEG1 variable be equal to "Bus timing register 0" and TSEG2 to "Bus timing register 1"?
Also when i try to change "Bus timing register 0" to 4(like it is in Ifx_CAN_N_BTR_Bits struct) and "Bus timing register 1" to 3 CANOE gives me invalid configuration error.

I also found this struct:

typedef volatile struct _Ifx_CAN_N
{
Ifx_CAN_N_CR CR; /**< \brief 0, Node Control Register */
Ifx_CAN_N_SR SR; /**< \brief 4, Node Status Register */
Ifx_CAN_N_IPR IPR; /**< \brief 8, Node Interrupt Pointer Register */
Ifx_CAN_N_PCR PCR; /**< \brief C, Node Port Control Register */
Ifx_CAN_N_BTR BTR; /**< \brief 10, Node Bit Timing Register */
Ifx_CAN_N_ECNT ECNT; /**< \brief 14, Node Error Counter Register */
Ifx_CAN_N_FCR FCR; /**< \brief 18, Node Frame Counter Register */
Ifx_CAN_N_TCCR TCCR; /**< \brief 1C, Node Timer Clock Control Register */
Ifx_CAN_N_TRTR TRTR; /**< \brief 20, Node Timer Receive Timeout Register */
Ifx_CAN_N_TTTR TATTR; /**< \brief 24, Node Timer A Transmit Trigger Register */
Ifx_CAN_N_TTTR TBTTR; /**< \brief 28, Node Timer B Transmit Trigger Register */
Ifx_CAN_N_TTTR TCTTR; /**< \brief 2C, Node Timer C Transmit Trigger Register */
unsigned char reserved_30[208]; /**< \brief 30, \internal Reserved */
} Ifx_CAN_N;

Here I tried changing TATTR to value given in CANOE in "Bus timing register 0" and TBTTR to "Bus timing register 0" but still no success.

If you have any advice please let me know. Thank you
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Hi Specimen. The Vector tool shows the bit timing information in a fancy graphical way. Compare that to Figure 21-12 CAN Bus Bit Timing Standard on page 1641 of tc23x_tc22x_um_v1.1.pdf:
- Sync Seg (in the manual) is the orange bar (in Vector's tool)
- The ticks show there are 8 Tq per bit
- TSEG1 is the blue bar
- The Sample Point is the red arrow
- TSEG2 is the green bar

It's okay for the Vector tool and the AURIX to use a different Tq, as long as the relative numbers match: the sample point should be the same (75%) on both sides.

There's a fair bit of magic in the iLLD's IfxMultican_Node_setFastBitTiming() function, which calculates TSEG1 and TSEG2.

Can you add this samplePoint line, to coerce the sample point to be 75% instead of 80%?
canNodeConfig.baudrate = 500000;
canNodeConfig.samplePoint = 75000;


Then let the function run, and post what the result is in the NBTRx register.

It could also be a termination issue - but you can usually get away without it for two nodes if it's a short cable run.
0 Likes
User16362
Level 1
Level 1
Thanks for helping me UC_wrangler.

I searched for IfxMultican_Node_setFastBitTiming() but i haven't found it anywhere.

I tried adding canNodeConfig.samplePoint = 7500; (btw did you mean 7500 instead of 75000 ?) and still no success. I tried to read samplePoint, synchJumpWidth and baudrate values after setting them and,
for example, if i set samplePoint to 7500, when i try to printf that value i get 7000. This happens for whatever value i put, when I printf it, i get 500 less value.

Code which I used for reading values is next:

void GetNodeConfig()
{
IfxMultican_Can_NodeConfig config;
IfxMultican_Can_Node_getConfig(&canDstNode, &config);
Ifx_CAN_N *hwNode = canDstNode.node;

printf("Baudrate %d, sampling point %d, synchJumpWidth %d \n", config.baudrate, config.samplePoint, config.synchJumpWidth);
}

3623.attach

I tried to use both 7500 and 8000 for samplePoint but without success.

I was also monitoring NBTRx registers(NTBR0,NTBR1,...,NTBR7) and noting appears there, since it never receives CAN message I guess.

I attached screenshot what is stored in those registers when I send CAN message from board directly(from node0 to node1 on board, instead from CAN interface to node1 on board).

3622.attach

I tried using cables with and without 120 ohm termination but situation is still same.

Thank you
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Hi specimen. Yes, I should have said samplePoint=7500 🙂

Working backwards from NBTR=0x3EC9, only the sample point needs some tweaking (but it's probably close enough to work):

- BRP=9 means: fCAN=100 MHz / (9+1) => 10 MHz => Tq=100ns
- TSEG1=14, TSEG2=4 means the bit timing is (14+1 plus 4+1 plus 1 sync seg) = 20 Tq per bit => 20 * 100 ns = 500K
- TSEG1=14, TSEG2=4 means the sample point is at (1 sync seg plus 14+1 = 16) / 20 Tq per bit = 80%

Could it be something simpler like CANL and CANH swapped? What do those look like on a scope?
0 Likes
User16362
Level 1
Level 1
Thanks for helping me UC_wrangler.

Im sure that i havent swapped CANL and CANH wires(I tried swapping them anyway, again no success).

So actually values from NBTRx register should be equal to values in CANOe(Bus timing register 0 in CANOe should be same as TSEG1 value and Bus timing register 1 should be same as TSEG2 )?

When i try to change Bus timing register 0 to "0F" (because 14+1 is F in hex) and Bus timing register 1 to "03" CANOe gives me "Invalid configuration error".
I also read in documentation that TSEG1 value can be only in rage 02-15 and TSEG2 value in range 1-7.

Should i maybe pick one set of given values in CANOe and set register values to that values given in CANOe?

I posted screenshot where you can see all available "sets" of values.

3630.attach

Thank you
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Hi Specimen. The AURIX NBTRx isn't the same as Vector's BTR0 and BTR1 registers. Just make sure the sampling point and baud rate is the same. SJW=2 is probably your best bet.

In your last Vector screenshot, the baud rate shows 250 - shouldn't that be 500?
0 Likes