Re: IMX6 SPI read/write

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: IMX6 SPI read/write

3,042 Views
wenjingwang
Contributor II

the SPI clk issue has been fixed now, and i define the spi read/write function, but i'm not sure if it is right:

static int vk32xx_read_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t *dat)

{

        struct spi_message msg;

        uint8_t buf_wdat[2];

        uint8_t buf_rdat[2];

        int status = 0;

        buf_wdat[0] = 0x7f&(((port-1)<<5)|(reg<<1));

        buf_wdat[1] = 0x0;

        buf_rdat[0] = 0x0;

        buf_rdat[1] = 0x0;

        status = spi_write_then_read(spi, buf_wdat, 2, buf_rdat, 2);

        if(status)

                printk("WWJ====vk32xx_read_reg failed status = %d\n", status);

        printk("buf_rdat[0] = 0x%x, buf_rdat[1] = 0x%x\n", buf_rdat[0], buf_rdat[1]);

        *dat = buf_wdat[1];

    return 0;

}

static int vk32xx_write_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t dat)

{

        struct spi_message msg;

        uint8_t buf_reg[2];

        int status = 0;

        struct spi_transfer index_xfer = {

                .len            = 2,

        };

        //spi_message_init(&msg);

        /* register index */

        buf_reg[0] = 0x80|((port-1)<<5)|(reg<<1);

        buf_reg[1] = dat;

  

        status = spi_write(spi, buf_reg, 2);

        if(status)

                printk("WWJ======vk32xx_write_reg failed status = %d\n", status);

        return status;

}

Labels (1)
Tags (3)
4 Replies

1,136 Views
justin_jiang
NXP Employee
NXP Employee

you can refer to our linux bsp.

0 Kudos

1,136 Views
wenjingwang
Contributor II

yes, i tried the below function, but the issue is still:

static int vk32xx_read_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t *dat)

{

         struct spi_message msg;

        unsigned int txdata = 0, rxdata = 0;

        uint8_t buf_wdat[2];

        uint8_t buf_rdat[2];

        int status;

       // mutex_lock(&vk32xxs_lock);

        struct spi_transfer index_xfer = {

                .len            = 2,

                .cs_change      = 1,

        };

        status =0;

        spi_message_init(&msg);

        buf_wdat[1] = 0x7f&(((port-1)<<5)|(reg<<1));

        buf_wdat[0] = 0x00;

        buf_rdat[0] = 0x00;

        buf_rdat[1] = 0x00;

        index_xfer.tx_buf = buf_wdat;

        index_xfer.rx_buf =(void *) buf_rdat;

        spi_message_add_tail(&index_xfer, &msg);

        status = spi_sync(spi, &msg);

        udelay(500);

       if(status)

        {

                printk("spi_sync failed status = %d\n", status);

                return status;

        }

        *dat = buf_rdat[1];

        printk("buf_rdat[1] = 0x%x, buf_rdat[0] = 0x%x\n", buf_rdat[1], buf_rdat[0]);

        printk("buf_wdat[1] = 0x%x, buf_wdat[0] = 0x%x\n", buf_wdat[1], buf_wdat[0]);

        return 0;

}


i have measured the MISO line and the data wave is appeared, but the buf_rdat is still zero. i do not know why?

0 Kudos

1,136 Views
jimmychan
NXP TechSupport
NXP TechSupport

1. Please double check the linux/arch/arm/plat-mxc/include/mach/iomux-mx6q.h.  The pad control of the ECSPI pins should use the MX6Q_ECSPI_PAD_CTRL.

For example:

#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK         \

            (_MX6Q_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))

Should be changed to :

#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK         \

            (_MX6Q_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))

2. You can try to use the "spidev" first. For example :

static struct spi_board_info vk32xx_spi_board_info[] __initdata = {

  

    /* The modalias must be the same as spi device driver name */

    .modalias    = "spidev",

    .max_speed_hz    = 10000000, 

    .bus_num    = 0,

    .chip_select    = 0,

};

3. Then try to use 'ioctl' to test the read/write. You can take the unit_test/test/mxc_spi_test/mxc_spi_test1.c for reference.

Here is an example for your reference :

Below is the timing of SPI read of a SPI device.

pastedImage_7.png

#define DEV_SPI    "/dev/spidev0.0"

static uint8_t spi_transfer(int fd, uint8_t *tx)

{

     int ret;

     uint8_t rx[ARRAY_SIZE(tx)] = {0, };

     struct spi_ioc_transfer tr = {

    .tx_buf = (unsigned long)tx,

    .rx_buf = (unsigned long)rx,

    .len = 2,

    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

    if (ret == 1)

    printf("can't send spi message.\n");

    return rx[1];   // rx[0] is not the data read from the device, rx[1] is the data D7-D0.

}

static void SPI_Write_register(int fd, uint8_t reg, uint8_t val)

{

    uint8_t tx[] = { 0x00, 0x00, };

    tx[0] = 0x80 | reg;     // the first bit is 1 for SPI Write

    tx[1] = val;

    spi_transfer(fd, tx);

}

  

static uint8_t SPI_Read_register(int fd, uint8_t reg)

{

    uint8_t tx[] = { 0x00, 0x00, };

    tx[0] = 0x7F & reg;   // the first bit is 0 for SPI Read

    tx[1] = 0xFF;         

    return spi_transfer(fd, tx);

}

int main()

{

    int fd, res;

    uint8_t val;

    unsigned char mode=0;

    unsigned char bits_per_word = 8;

    unsigned int speed = 10000000;

   fd = open(DEV_SPI, O_RDWR);

   res = ioctl(fd, SPI_IOC_WR_MODE, &mode);

    if (res == -1) {

        printf("can't set spi mode");

        goto exit;

    }

    res = ioctl(fd, SPI_IOC_RD_MODE, &mode);

    if (res == -1) {

        printf("can't set spi mode");

        goto exit;

    }

    res = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);

    if (res == -1) {

        printf("can't set bits per word");

        goto exit;

    }

    res = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits_per_word);

    if (res == -1) {

        printf("can't get bits per word");

        goto exit;

    }

    res = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

    if (res == -1) {

        printf("can't set max speed hz");

        goto exit;

    }

    res = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);

    if (res == -1) {

        printf("can't get max speed hz");

        goto exit;

    }

    //Read the value of the  address 0x00 of SPI device

    val = SPI_Read_register(fd,0x0);

    printf("Read value : %X\n",val);

    // write the 0x1 to the address 0x00 of SPI device

    SPI_Write_register(fd,0x0,0x1);

  

exit:

    close(fd);

    return 0;

}

0 Kudos

1,136 Views
justin_jiang
NXP Employee
NXP Employee


We test the spi on our platform. Do this issue only happen on your platform?

What's HW connection are you using and which version code are you work on?