Quantcast
Channel: Infineon Forums
Viewing all articles
Browse latest Browse all 9892

CAN bus respond to remote request

$
0
0
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.

Attachment 3206

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

Attachment 3207
Attachment 3208

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:
Code:

#include <DAVE.h>                //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:
Code:

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:

Code:

  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

Code:

  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:

Code:

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
?????

Viewing all articles
Browse latest Browse all 9892

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>