infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

Dave

+ Reply to Thread
Results 1 to 3 of 3

Thread: CAN bus respond to remote request

  1. #1
    Beginner Beginner ewong@calex.com is on a distinguished road
    Join Date
    Nov 2017
    Posts
    3
    Points
    55

    CAN bus respond to remote request

    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_pt r[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_EVE NT_ALERT);

    }

  2. #2
    Advanced Advanced
    Infineon Employee
    Infineon Employee
    DRubeša will become famous soon enough
    Join Date
    Jul 2016
    Location
    Augsburg
    Posts
    116
    Points
    1322.5
    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.

    Click image for larger version

Name:	basic_init.PNG
Views:	0
Size:	5.4 KB
ID:	3206

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

    Click image for larger version

Name:	tx_node_init.PNG
Views:	0
Size:	10.9 KB
ID:	3207
    Click image for larger version

Name:	rx_node_init.PNG
Views:	0
Size:	11.1 KB
ID:	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
    Last edited by DRubeša; Nov 14th, 2017 at 05:57 AM.
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

  3. #3
    Beginner Beginner ewong@calex.com is on a distinguished road
    Join Date
    Nov 2017
    Posts
    3
    Points
    55
    Thanks DRubesa

+ Reply to Thread
Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.