UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor nguyenq
Visitor
6,963 Views
Registered: ‎01-20-2013

CAN communication with Zynq 7000

Hello

I am trying to create a standalone program in C to use the CAN to send and receive messages and display them using the printf. I use the polled examples given by Xilinx :
file:///C:/Xilinx/14.4/ISE_DS/EDK/sw/XilinxProcessorIPLib/drivers/canps_v1_01_a/examples/xcanps_polled_example.c

The program just send a message to a CAN device using the JB3 PIN and wait for an answer on JB4 PIN to display it.
Using oscilloscope I can see both send and receive on each PIN.
The problem is that the program does'nt detect the receive message so it cannot display it (it is always waiting for a message). It is stuck at this instruction :
while(XCanPs_IsRxEmpty(InstancePtr) == TRUE)

I just changed the mode from LOOPBACK to NORMAL :
XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOPBACK);
while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_NORMAL);

I tried the interrupt example and it is the same problem to.

Can someone help me ? Here is the source code :






#include <stdio.h>
#include "platform.h"



/***************************** Include Files *********************************/

#include "xcanps.h"
#include "xparameters.h"
#include "xil_printf.h"



/************************** Constant Definitions *****************************/

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */
#define CAN_DEVICE_ID    XPAR_XCANPS_0_DEVICE_ID

/*
 * Maximum CAN frame length in words.
 */
#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32))

#define FRAME_DATA_LENGTH         8  /* Frame Data field length */

/*
 * Message Id Constant.
 */
#define TEST_MESSAGE_ID            2000

/*
 * The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR)
 * are setup such that CAN baud rate equals 40Kbps, assuming that the
 * the CAN clock is 24MHz. The user needs to modify these values based on
 * the desired baud rate and the CAN clock frequency. For more information
 * see the CAN 2.0A, CAN 2.0B, ISO 11898-1 specifications.
 */

/*
 * Timing parameters to be set in the Bit Timing Register (BTR).
 * These values are for a 40 Kbps baudrate assuming the CAN input clock
 frequency
 * is 24 MHz.
 */
#define TEST_BTR_SYNCJUMPWIDTH        1
#define TEST_BTR_SECOND_TIMESEGMENT    3
#define TEST_BTR_FIRST_TIMESEGMENT    8

/*
 * The Baud rate Prescalar value in the Baud Rate Prescaler Register (BRPR)
 * needs to be set based on the input clock  frequency to the CAN core and
 * the desired CAN baud rate.
 * This value is for a 40 Kbps baudrate assuming the CAN input clock frequency
 * is 24 MHz.
 */
#define TEST_BRPR_BAUD_PRESCALAR    1



/************************** Function Prototypes ******************************/

int CanPsPolledExample(u16 DeviceId);
static int SendFrame(XCanPs *InstancePtr);
static int RecvFrame(XCanPs *InstancePtr);



/************************** Variable Definitions *****************************/

/*
 * Buffers to hold frames to send and receive. These are declared as global so
 * that they are not on the stack.
 * These buffers need to be 32-bit aligned
 */
static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];
static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];

/* Driver instance */
static XCanPs Can;




int main()
{
    int Status;

    xil_printf("CAN Polled Mode Example Test \r\n");

    /*
     * Run the Can Polled example, specify the Device ID that is generated
     * in xparameters.h .
     */
    Status = CanPsPolledExample(CAN_DEVICE_ID);
    if(Status != XST_SUCCESS){
        xil_printf("CAN Polled Mode Example Test Failed\r\n");
        return XST_FAILURE;
    }

    xil_printf("Successfully ran CAN Polled Mode Example Test\r\n");
    return XST_SUCCESS;
}










/*****************************************************************************/
/**
*
* The entry point for showing the XCanPs driver in polled mode. The example
* configures the device for internal loop back mode, then sends a Can
* frame, receives the same Can frame, and verifies the frame contents.
*
* @param    DeviceId is the XPAR_<CANPS_instance>_DEVICE_ID value from
*        xparameters.h
*
* @return    XST_SUCCESS if successful, otherwise driver-specific error code.
*
* @note
*
* If the device is not working correctly, this function may enter an infinite
* loop and will never return to the caller.
*
******************************************************************************/
int CanPsPolledExample(u16 DeviceId)
{
    int Status;
    XCanPs *CanInstPtr = &Can;
    XCanPs_Config *ConfigPtr;

    /*
     * Initialize the Can device.
     */
    ConfigPtr = XCanPs_LookupConfig(DeviceId);
    if(CanInstPtr == NULL){
        return XST_FAILURE;
    }
    Status = XCanPs_CfgInitialize(CanInstPtr, ConfigPtr, ConfigPtr->BaseAddr);
    if(Status != XST_SUCCESS){
        return XST_FAILURE;
    }

    /*
     * Run self-test on the device, which verifies basic sanity of the
     * device and the driver.
     */
    Status = XCanPs_SelfTest(CanInstPtr);
    if(Status != XST_SUCCESS){
        return XST_FAILURE;
    }

    /*
     * Enter Configuration Mode so we can setup Baud Rate Prescaler
     * Register (BRPR) and Bit Timing Register (BTR).
     */
    XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_CONFIG);
    while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_CONFIG);

    /*
     * Setup Baud Rate Prescaler Register (BRPR) and
     * Bit Timing Register (BTR).
     */
    XCanPs_SetBaudRatePrescaler(CanInstPtr, TEST_BRPR_BAUD_PRESCALAR);
    XCanPs_SetBitTiming(CanInstPtr, TEST_BTR_SYNCJUMPWIDTH, TEST_BTR_SECOND_TIMESEGMENT, TEST_BTR_FIRST_TIMESEGMENT);

    /*
     * Enter Loop Back Mode.
     */
    XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOPBACK);
    while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_NORMAL);

    /*
     * Send a frame, receive the frame via the loop back and verify its
     * contents.
     */
    Status = SendFrame(CanInstPtr);
    if(Status != XST_SUCCESS){
        return Status;
    }

    Status = RecvFrame(CanInstPtr);

    return Status;
}


/*****************************************************************************/
/**
*
* Send a CAN frame.
*
* @param    InstancePtr is a pointer to the driver instance
*
* @return    XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note
*
* This function waits until TX FIFO has room for at least one frame before
* sending a frame. So this function may block if the hardware is not built
* correctly.
*
******************************************************************************/
static int SendFrame(XCanPs *InstancePtr)
{
    u8 *FramePtr;
    int Index;
    int Status;

    /*
     * Create correct values for Identifier and Data Length Code Register.
     */
    TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0);
    TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)FRAME_DATA_LENGTH);

    /*
     * Now fill in the data field with known values so we can verify them
     * on receive.
     */
    FramePtr = (u8 *)(&TxFrame[2]);
    //for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) {
    //    *FramePtr++ = (u8)Index;
    //}
    FramePtr[0] = (u8)31;
    FramePtr[1] = (u8)32;
    FramePtr[2] = (u8)33;
    FramePtr[3] = (u8)34;
    FramePtr[4] = (u8)35;
    FramePtr[5] = (u8)36;
    FramePtr[6] = (u8)37;
    FramePtr[7] = (u8)38;
    for(Index=0 ; Index<FRAME_DATA_LENGTH ; Index++){
        xil_printf("send%d : %d \n\r", Index, FramePtr[Index]);
    }




    /*
     * Wait until TX FIFO has room.
     */
    while(XCanPs_IsTxFifoFull(InstancePtr) == TRUE);

    /*
     * Now send the frame.
     *
     * Another way to send a frame is keep calling XCanPs_Send() until it
     * returns XST_SUCCESS. No check on if TX FIFO is full is needed anymore
     * in that case.
     */
    Status = XCanPs_Send(InstancePtr, TxFrame);

    return Status;
}


/*****************************************************************************/
/**
*
* This function receives a frame and verifies its contents.
*
* @param    InstancePtr is a pointer to the driver instance.
*
* @return    XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note
*
* This function waits until RX FIFO becomes not empty before reading a frame
* from it. So this function may block if the hardware is not built
* correctly.
*
******************************************************************************/
static int RecvFrame(XCanPs *InstancePtr)
{
    u8 *FramePtr;
    int Status;
    int Index;

    /*
     * Wait until a frame is received.
     */
    while(XCanPs_IsRxEmpty(InstancePtr) == TRUE);

    /*
     * Receive a frame and verify its contents.
     */
    Status = XCanPs_Recv(InstancePtr, RxFrame);
    if(Status == XST_SUCCESS){
        /*
         * Verify Identifier and Data Length Code.
         */
        if (RxFrame[0] !=
            (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0))
            return XST_LOOPBACK_ERROR;

        if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1])
            return XST_LOOPBACK_ERROR;

        /*
         * Verify Data field contents.
         */
        FramePtr = (u8 *)(&RxFrame[2]);
        //for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) {
        //    if (*FramePtr++ != (u8)Index) {
        //        return XST_LOOPBACK_ERROR;
        //    }
        //}
        for (Index=0 ; Index<FRAME_DATA_LENGTH ; Index++){
            xil_printf("receive%d : %d \n\r", Index, FramePtr[Index]);
        }

    }

    return Status

0 Kudos
7 Replies
Visitor nguyenq
Visitor
6,961 Views
Registered: ‎01-20-2013

Re: CAN communication with Zynq 7000

I use the Zedboard

0 Kudos
Scholar austin
Scholar
6,949 Views
Registered: ‎02-27-2008

Re: CAN communication with Zynq 7000

n,

 

Have you also posted on zedboard.org?  Thet have their own forums.  Of course, you are welcome to ask here.

 

 

Austin Lesea
Principal Engineer
Xilinx San Jose
0 Kudos
Visitor nguyenq
Visitor
6,940 Views
Registered: ‎01-20-2013

Re: CAN communication with Zynq 7000

Hello

Yes I have also posted in Zedboard forum here :

http://www.zedboard.org/content/can-communication-gpio

0 Kudos
Explorer
Explorer
6,932 Views
Registered: ‎08-14-2007

CAN topology

What does your CAN bus look like? 

 

Shortcuts can be taken when you know what you are doing, but for now, to get going easily you need:

 

* CAN physical layers for each node

* twisted pair wiring

* 120 ohm terminator on each end of the bus

* At least 2 nodes on the bus (the Tx node wait for the Rx node(s) to ACKnowledge the message, otherwise it is deemed invalid by all receiving nodes.  Your node won't ACK its own message

 

It's also helpful to have tools like Canalyzer to show what is on the bus independent of your own code as well.  They can also transmit test messages for you, and act as an ACKing node.

Martin Thompson
martin.j.thompson@trw.com
http://www.conekt.co.uk/capabilities/electronic-hardware
0 Kudos
Visitor nguyenq
Visitor
6,923 Views
Registered: ‎01-20-2013

Re: CAN topology

Hello

 

Yes I have all the hardware needed. Now I have 3 CAN devices, CANUSB and the Zedboard connected to the bus

0 Kudos
Visitor ugurkebir
Visitor
702 Views
Registered: ‎02-08-2019

Re: CAN topology

Hello,

I have same problem. Did you solve this problem ?

0 Kudos
Moderator
Moderator
675 Views
Registered: ‎07-31-2012

Re: CAN topology

Hi @ugurkebir ,

This is an old post which is resolved by zedboardorg at http://www.zedboard.org/content/can-communication-gpio .

Please refer to https://github.com/zpcaams/can-ps7-xilinx with CAN PHY properly connected.

Regards

Praveen


-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos