Jump to content
  • 0

petalinux pmodCAN


daeroro

Question

Hi, 

I'm using zybo-z7 10 and pmod CAN.

Now I'm trying to build pmod CAN petalinux user app.

But first of all, I want to handle spi transfer, so I build spi example code.

 

I'm using petalinux 2017.4 and vivado 2018.2. 

And hardware design referenced from here :

https://reference.digilentinc.com/learn/programmable-logic/tutorials/pmod-ips/start

 

and device tree (in ~/CAN_fpga/project-spec/meta-user/recipes-bsp/device-tree/files/system_user.dtsi) :

/include/ "system-conf.dtsi"
/ {
};

&spi0 {
  is-decoded-cs = <0>;
  num-cs = <1>;
  status = "okay";

  spidev@0x00 {
    compatible = "spidev";
    spi-max-frequency = <10000000>;
    reg = <0>;
  };
};

 

and the user app code:

-------------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define SPI_DEV    "/dev/spidev32766.0"

int main(void)
{
    int fd, i;
    int rbuf[128];
    const char * name = SPI_DEV;
    int readcount = 8;
    int msglen = 8;

    if((fd = open(SPI_DEV, O_RDWR))<0)
    {
        perror("Open error: ");
        exit(-1);
    }
    printf("Open success\n");

    dumpstat(name, fd);

    printf("before do_msg\n");

    if (msglen)
        do_msg(fd, msglen);

    printf("after do_msg\n");

    if (readcount)
        do_read(fd, readcount);


    return 0;
}
 

static void do_read(int fd, int len)
{
    unsigned char    buf[32], *bp;
    int        status;

    /* read at least 2 bytes, no more than 32 */
    if (len < 2)
        len = 2;
    else if (len > sizeof(buf))
        len = sizeof(buf);
    memset(buf, 0, sizeof buf);

    status = read(fd, buf, len);
    if (status < 0) {
        perror("read");
        return;
    }
    if (status != len) {
        fprintf(stderr, "short read\n");
        return;
    }

    printf("read(%2d, %2d): %02x %02x,", len, status, buf[0], buf[1]);


    status -= 2;
    bp = buf + 2;
    while (status-- > 0)
        printf(" %02x", *bp++);


    printf("\n");
}

static void do_msg(int fd, int len)
{
    struct spi_ioc_transfer    xfer[2];
    unsigned char        buf[32], *bp;
    int            status;

    memset(xfer, 0, sizeof xfer);
    memset(buf, 0, sizeof buf);

    if (len > sizeof buf)
        len = sizeof buf;

    buf[0] = 0xaa;
    xfer[0].tx_buf = (unsigned long)buf;
    xfer[0].len = 1;

    xfer[1].rx_buf = (unsigned long) buf;
    xfer[1].len = len;

    printf("before do_msg ioctl\n");

    status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);

    printf("after do_msg ioctl\n");
    if (status < 0) {

        printf("status : %d\n", status);
        perror("SPI_IOC_MESSAGE");
        return;
    }

    printf("response(%2d, %2d): ", len, status);
    for (bp = buf; len; len--)
        printf(" %02x", *bp++);
    printf("\n");
}

static void dumpstat(const char *name, int fd)
{
    __u8    lsb, bits;
    __u32    mode, speed;

    if (ioctl(fd, SPI_IOC_RD_MODE32, &mode) < 0) {
        perror("SPI rd_mode");
        return;
    }
    if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
        perror("SPI rd_lsb_fist");
        return;
    }
    if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
        perror("SPI bits_per_word");
        return;
    }
    if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
        perror("SPI max_speed_hz");
        return;
    }
    
    printf("%s: spi read mode 0x%x, %d bits %sper word, %d Hz max\n",
        name, mode, bits, lsb ? "(lsb first) " : "", speed);

}

------------------------------------------------------------------------------------------------------------------------------

I want to control spi in duplex mode using ioctl() bolded above code.

 

But the result is :

1161170300_2019-05-3114-18-41.png.8086dc0934326d9d38aa52534ae5cffa.png

- SPI transfer timed out   -> ioctl() function doesn't work properly, I think.

 

Could you give me some advice?

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

Hi @daeroro,

#define SPI_DEV    "/dev/spidev32766.0" 

Judging by the .dtsi this should be something else... probably something like spidev1.0. You will need to change to the right device name. To determine which is the right name please run

ls /dev/ | grep spi

on the running petalinux target.

-Ciprian

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...