CAN bus respond to remote request

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

cross mob
User14115
Level 1
Level 1
Hi All,

First time use XMC4400 and CAN communication. as I cannot find much sample about external CAN communication, so i post here if someone can help me.

It is working fine when I use sample code as loop-back mode on XMC4400 demo board, but it always send back 2 message when i connect it with COM_ETH_V1 kit with external CAN communication.

It is use DAVE 4, and CAN TX address is 0x355.

Another question i have is how can i load different data other than data set by APP?

Thanks
Ed

Here is code i use to respond to remote request, is it right way?


status3 = CAN_NODE_MO_GetStatus((void*)CAN_NODE_1.lmobj_ptr[1]);

// Check receive pending status

if ( status3 & XMC_CAN_MO_STATUS_RX_PENDING)

{

// Clear flag status

CAN_NODE_MO_ClearStatus((void*)CAN_NODE_1.lmobj_ptr[1],XMC_CAN_MO_RESET_STATUS_RX_PENDING);


CAN_NODE_MO_Transmit((void*)CAN_NODE_1.lmobj_ptr[1]); //Send data back
}

status3 = CAN_NODE_GetStatus(&CAN_NODE_1);

if (status3 & XMC_CAN_NODE_STATUS_ALERT_WARNING)

{

// Clear the flag

CAN_NODE_DisableEvent(&CAN_NODE_1,XMC_CAN_NODE_EVENT_ALERT);

}
0 Likes
5 Replies
DRubeša
Employee
Employee
First solution authored First like received
Hi,

so I will try to answer on all your questions with an example that´ve done to explain data updating and remote transmission request.

I´ve used the XMC4700/XMC4800 board but all the following things can be used by you also on XMC4400 board. I saw that you use CAN_NODE APP, so I´ve made an example using the same APP even though I prefer MULTICAN_CONFIG 🙂

First I´ve initialized two CAN nodes....CAN_NODE_0 and CAN_NODE_1. They are used in LOOPBACK mode. Yes, I´m aware that you want to use normal mode but I would always suggest first to develop an application with LOOPBACK mode while that excludes potential hardware issues from the beginning. When you have an issue and the cause can be a hardware or software one, that´s much more difficult to resolve then to deal only with software ones.

2893.attach

Both nodes have the same "General Settings" tab.Then set the CAN_NODE_0 and CAN_NODE_1 as following:

2894.attach
2895.attach

Pretty straightforward and I guess you´ve already done something like this with the basic example that came with the board. CAN_NODE_0 will be our TX_NODE that will reply on remote transmission request and CAN_NODE_1 will be send the request and receive the requested data (RX_NODE). Notice the data that currently TX_NODE has; 0xAA55AA55 and so on. Later on I will change this data, during the execution of "main" routine. That will answer one of your questions 😉

My "main.c" file looks like this:
#include                  //Declarations from DAVE Code Generation (includes SFR declaration)

uint32_t dataToBeTransmitted = 0xDEADBEEF;

void RemoteTransmissionRequest(void);

int main(void)
{
DAVE_STATUS_t status;
uint32_t timerId;

status = DAVE_Init(); /* Initialization of DAVE APPs */

if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");

while(1U)
{

}
}

CAN_NODE_MO_UpdateData(CAN_NODE_0.lmobj_ptr[0], (uint8_t*)&dataToBeTransmitted);

timerId = SYSTIMER_CreateTimer(2000000, SYSTIMER_MODE_PERIODIC,(void*)RemoteTransmissionRequest, NULL);

if (0 != timerId)
{
SYSTIMER_StartTimer(timerId);
}

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
while(1U)
{

}
}

void RemoteTransmissionRequest(void)
{
CAN_NODE_MO_Transmit(CAN_NODE_1.lmobj_ptr[0]);
}

void CAN_RXNode_Receive_IRQHandler(void)
{
XMC_CAN_STATUS_t status;

status = CAN_NODE_MO_Receive(CAN_NODE_1.lmobj_ptr[0]);

if (status == XMC_CAN_STATUS_SUCCESS)
{
if (dataToBeTransmitted == CAN_NODE_1.lmobj_ptr[0]->mo_ptr->can_data[0])
{
XMC_GPIO_ToggleOutput(LED2.gpio_port, LED2.gpio_pin);
}
}
}

void CAN_TXNode_Transmit_IRQHandler(void)
{
XMC_GPIO_ToggleOutput(LED1.gpio_port, LED1.gpio_pin);
}


Here you can see some other things that I´ve used like SYSTIMER and DIGITAL_IO APPs which I´ve named here LED1 and LED2 while they are connected to two LEDs located on my board to easily verify that remote transmission was successful. This you don´t need, you can easily debug and verify that what you got is really what you expect. For the sake of this example, I´ve included it here.

One of the more important lines that may interest you is:
 CAN_NODE_MO_UpdateData(CAN_NODE_0.lmobj_ptr[0], (uint8_t*)&dataToBeTransmitted);


This is exactly the way how you can overwrite APP CAN TX data field. You just need to specify which MO should be updated, in my case that´s the MO0 (in your case may be some other) and address of the data to be updated. You can also do something like this:

  CAN_NODE_0.lmobj_ptr[0]->mo_ptr->can_data[0] = 0xDEADBEEF;
XMC_CAN_MO_UpdateData(CAN_NODE_0.lmobj_ptr[0]->mo_ptr);


or

  CAN_NODE_0.lmobj_ptr[0]->mo_ptr->can_data_byte = 0xDE;
XMC_CAN_MO_UpdateData(CAN_NODE_0.lmobj_ptr[0]->mo_ptr);


Depends what do you need and what do you prefer at the end. Going back to the example. I´ve started a timer that every 2 second will call a function and remote transmission request will be issued. How to issue request is given inside "RemoteTransmissionRequest" function:

void RemoteTransmissionRequest(void)
{
CAN_NODE_MO_Transmit(CAN_NODE_1.lmobj_ptr[0]);
}


If you´ve followed my steps you can see that DIR bitfield inside MOSTAT register for a message object assigned to RX_NODE is 0. For receiving node that means that remote frame is scheduled for the transmission once the TXRQ = 1. Now it´s only necessary to set the TXRQ to 1 and this will issue the remote transmission request. For this we used "CAN_NODE_MO_Transmit" function on RX_NODE. Once the remote transmission request occurred, TX_NODE acknowledges that request by transmitting predefined data and this is verified by toggling the LED1 light as a part of a TX interrupt handler routine. RX_NODE receives the data and inside the RX interrupt handler routine we want to verify that the received data matches with the expected data. Once this is true, we toggle second LED (LED2) to verify that we successful performed remote transmission. And this whole procedure will repeat every 2 seconds indefinively.

I hope this example was helpful for you and that you see that using remote transmission is simple and that you are comfortable with adapting it to your application.

Best regards,
Deni
0 Likes
User14115
Level 1
Level 1
Thanks DRubesa
0 Likes
User21465
Level 1
Level 1
Hello,

Can someone provide me with necessary APPs and configurations in order for this code to work, such as setting up the interrupt handlers.
Or the whole project archive if it's available.

Thanks
0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked
Hi,

I doubt we could find the exact archive as this is an old thread. Let us know if you are facing any issues with setting up interrupts. You can always check the APP Info section to understand the App configuration values.

Best Regards,
Vasanth
0 Likes
lock attach
Attachments are accessible only for community members.
hkwoo
Level 1
Level 1
First solution authored 10 sign-ins 5 sign-ins

Hi Vasanth

I have same problem how to configure CAN app respond the remote request. It seems that the code does not sent remote request to TX Node. I do not know, send RX MO is equal to send out remote frame?

I followed your suggest to build DAVE project. However, there is not any interrupt generated.

Please find zip is my Dave project. Please advise my problem. FYI I am using XMC4400

 

0 Likes