Adding SPI flash

Added by Mary Frantz almost 6 years ago

We have a SPI serial flash device on our board, an M25PE80. It is connected to SPI1 with SPI1_CS1.

I created a baseboard file based on baseboard-industrialio.c and using what was done for the SPI flash in board-mityopmanl138 as a guide. So far I cannot read the flash. Probing the board shows that the SPI1_CS1 is not going low to access the device.

I added this to my baseboard file:

 * SPI Devices:
 *    SPI1_CS1: Flash M25PE80
static struct mtd_partition sys9000_spi_flash_partitions[] = {
    [0] = {
        .name        = "sys9000_fpga",
        .offset        = 0,
        .size        = SZ_1M,
    [1] = {
        .name        = "sys9000_extra",
        .offset        = MTDPART_OFS_APPEND,
        .size        = MTDPART_SIZ_FULL,

// Copied from board-mityomapl138.c in this directory
static struct flash_platform_data sys9000_spi_flash_data = {
    .name        = "m25p80",
    .parts        = sys9000_spi_flash_partitions,
    .nr_parts    = ARRAY_SIZE(sys9000_spi_flash_partitions),
    .type        = "m25p64-nonjedec",

static struct davinci_spi_config spi_M25PE80_config = {
    .io_type    = SPI_IO_TYPE_DMA,
    .c2tdelay    = 8,
    .t2cdelay    = 8,

// Added 12/16/13 SPI1 interface to Sys9000 FPGA
static struct davinci_spi_config spi_9000FPGA_config = {
    .io_type    = SPI_IO_TYPE_DMA,        // restored 04/21/14
    .c2tdelay    = 0,
    .t2cdelay    = 0,

static struct spi_board_info sys9000_spi1_info[] = {
    [0] = {
        .modalias            = "m25p80",
        .platform_data        = &sys9000_spi_flash_data,
        .controller_data    = &spi_M25PE80_config,
        .mode                = SPI_MODE_0,
        .max_speed_hz        = 30000000,
        .bus_num            = 1,
        .chip_select        = 1,

// Added 12/16/13 SPI1_FPGA_CS_N
static u8 spi1_cs[] = {

These partitions show up in the boot log as mdt10 and mtd11

Here's the code to read the flash:

unsigned int FLASH_readFPGA(unsigned int sector, void * pDest, unsigned int size)

    mtd_info_t mtd_info;
    int fd;
    unsigned int nRead;

    // Get semaphore

    GPIO_setOutput(, fpga_spi_sel.pin_num, 0);            // cpu has access

    fd = open("/dev/mtd10", O_RDONLY);
    if (fd < 0)
        error(0, errno,"FLASH_readFPGA() open() failed:");
        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);
        lseek(fd, mtd_info.erasesize * sector , SEEK_SET );            // move to given sector

        // read flash
        nRead = read(fd, pDest, size);                            // read into destination

    } // endelse: fd < 0

    GPIO_setOutput(, fpga_spi_sel.pin_num, 1);            // fpga has access

    // Give semaphore

    return nRead;
} // end: FLASH_readFPGA()

mtd_info.type = 3
mtd_info.size = 4194304
mtd_info.erasesize = 65536

The open() call returns a valid file descriptor. The read() call takes a long time (>10 seconds) and returns 1. The data byte read is 0.

We are using MDK_2012-08-10

Is my baseboard file correct? See attached.

By setting chip_select = 1 in the spi_board_info structure, does that refer to the dedicated chip selects for SPI1 (SPI_CS1), or to the array (spi1_cs1)?


baseboard-sys9000.c View - Custom baseboard file (5.28 KB)

Replies (6)

RE: Adding SPI flash - Added by Michael Williamson almost 6 years ago

Hi Mary,

Have you configured the pin-mux for the DA850_GPIO2_15, which would correspond to the chip select you are selecting for your part?

The way you have configured it is you are having the SPI controller drive that chip select by using the GPIO library, so you need to configure the pin-mux for it appropriately.... The chip_select=1 in the spi_board_info_structure is an index into the spi1_cs array, which is then referring to a GPIO number.


RE: Adding SPI flash - Added by Jonathan Cormier almost 6 years ago

Note that if you want to use the hardware designated chip select for that spibus instead of a gpio then the SPI_INTERN_CS variable is used. Unsure if this applies to a fpga spibus though.

RE: Adding SPI flash - Added by Michael Williamson almost 6 years ago

It would not apply (different driver, different logic handling platform arguments).

RE: Adding SPI flash - Added by Mary Frantz almost 6 years ago

I confirmed with a scope that the chip select was not active.

I added DA850_GPIO2_15 to the the array of gpios in my baseboard file.

I also changed the .type entry in the flash_platform_data structure to "m25pe80".
In this case, there is an error during boot

"unrecognized JEDEC id ffffff"

The open() call then fails.

So, I changed the .type entry to "m25p80-nonjedec"

Now the chip select is active and the read() call returns quickly and returns the number of bytes requested.

The first 16 bytes received are correct (0xFF), but the following bytes are not. Looking with a scope in SPI bus analysis mode shows the data coming from the M25PE80 serial flash is correct, but does not agree with what ends up in the buffer in software. How is this possible? Is there anything on the SOM that conflicts with CS1?


RE: Adding SPI flash - Added by Michael Williamson almost 6 years ago

Is the SPI mode field correct (polarity and phase, CPOL and CPHA is the part in SPI_MODE_0)?

You also look like you are setting the delay fields (c2tdelay and t2cdelay), required?

RE: Adding SPI flash - Added by Mary Frantz almost 6 years ago

The part works in SPI mode 0 or 3, but I tried all four modes (0 - 3). I also tried setting the fields .c2tdelay and .t2cdelay to 0.

As I mentioned, the data appearing on the bus (SOMI), driven by the M25PE80 is correct (as seen with an oscilloscope). That is, it is the same data that I know has been programmed into the part.

Why does the this data not match what ends up in my buffer?

    Add picture from clipboard (Maximum size: 500 MB)