Skip to content

SPI: random data length/tx/rx for DMA SPI transfers (eg. size over 32 bytes) "CONFIG_SPI_ROCKCHIP" #19

@mcerveny

Description

@mcerveny

SPI driver CONFIG_SPI_ROCKCHIP (drivers/spi/spi-rockchip.c) does not work for transfers over 32 bytes (switched to DMA transfers, see rockchip_spi_can_dma()). Totally random length/rx/tx are send and received with rk3288 (TinkerBoard, TinkerOS 1.8). Checked with external protocol analyzer and testing code:

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

// SZ <= 32 OK (PIO transfers), >32 radom length send, random data send (checked from logic analyzer), random data received (DMA transfers)
#define SZ 33

int main()
{
	int fd = open("/dev/spidev2.0", O_RDWR);

	uint8_t mode = SPI_MODE_3;
	ioctl(fd, SPI_IOC_WR_MODE, &mode);
	ioctl(fd, SPI_IOC_RD_MODE, &mode);

        struct spi_ioc_transfer xfer;
	memset(&xfer, 0, sizeof(xfer));

	uint8_t tx_buf[SZ] = "\03\0\0\0";  // "\03\0\0\0" read from SPI flash or "\237" Manufacturer and Device ID Read (len 7)
        uint8_t rx_buf[SZ];

	xfer.tx_buf = (unsigned long)&tx_buf;
	xfer.rx_buf = (unsigned long)&rx_buf;
	xfer.len = sizeof(rx_buf);
	xfer.speed_hz = 10000000;
	xfer.bits_per_word = 8;

	int status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);

	printf("status %d\n", status);
	int i;
	for(i=0; i<sizeof(rx_buf); i++) printf("%02x ", rx_buf[i]);
	printf("\n");

	close(fd);

	return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions