Electronic – Reading from SPI flash more than 35 bytes causes driver timeout and results to corrupt

driverflashlinuxspi

I have connected SPI flash to my linux board (imx 233 based) running in it's SPI bus.
I have configured kernel, and SPI bus and flash chip to it.

The flash is currently on a breadboard. Before trying to work on linux, I tried separately and I'm able to read and write as I like with a FT2232H chip (FT2232 breakout board by dangerousprototypes.com).
However, linux-board, I had to add pull-up resistors (10k) in the data in and data out lines, the chip was not recognized correctly otherwise.

My actual problem is that now I'm trying to just read raw flash through mtd driver, and everything seems correct, if I read less than 35 bytes.
Immediately if I read more than 35 bytes (36 or more), the driver complains about DMA error:

[  521.700000] mxs-spi 80034000.ssp: DMA transfer timeout
[  521.700000] spi_master spi32766: failed to transfer one message from queue

Also when this happens, most of (if not all) the bytes will be incorrect..
Reading less than 35 bytes will return "immediately" (no timeout), and all bytes read will be correct.

My C code is straight from MTD read example:

int main(int argc, char * argv[])
{

    if (argc != 2)
    {
    printf("Need arguments how many chars to read\nExiting...\n");
    return 1;
    }

    int amount = atoi(argv[1]);
    printf("reading (%d) chars\n", amount);

    mtd_info_t mtd_info;
    int fd = open("/dev/mtd0", O_RDONLY);
    ioctl(fd, MEMGETINFO, &mtd_info);

    printf("MTD type: %u\n", mtd_info.type);
    printf("MTD total size : %u bytes\n", mtd_info.size);
    printf("MTD erase size : %u bytes\n", mtd_info.erasesize);

    /* read buffer */
    unsigned char buf[amount];

    read(fd, buf, sizeof(buf));

    int i = 0;

    for (i = 0; i < amount; i++)
    {
            printf("%i: %X\n",i,buf[i]);
    }
return 0;
} 

The timeout happens "as expected" (10 seconds) in spi-mxs.c:

drivers/spi/spi-msx.c:
static int mxs_spi_txrx_dma(...):
....
ret = wait_for_completion_timeout(&spi->c, msecs_to_jiffies(SSP_TIMEOUT));

Any ideas what might be wrong ? I'm not that good with electronics, so please all suggestions are welcome.

Best Answer

I think it is a problem with the SPI driver. Does it still not work with 3.7 upstream kernel? There were a lot of fixes applied there.