SPI receive

I/ trying to read the ID of a Fijitsu FRAM type MB85RS4MT using the Nordic device nRF5340. I can properly initialize the SPI and transmit the RDID =0x9F command. The FRAM returns, what I think is the proper ID, but it won't show up in software. I'm using the synchronous spi_transceive routine. I Initialize the ID buffer prior use with all 0xFF. The data is overwritten with all zeros ?. This is how the DTC and code looks like. I'm really stuck, can it have something to do with double use of GPIOs ???? within the Device Tree visual editor it appears that NFC is disabled (also using pin P0.03). Could it be that the NFC part it somehow blocking proper use of the pins for SPI. (How can I check?) 

The code looks as follows:

______________________________________________________________________________________________________________________________

static int spi_transfer(const struct device *spi_dev, struct spi_config *spi_cfg, uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len)
{
    /// READ github.com/.../65512

    struct spi_buf tx_buffer[1] = {
        {
            .buf = tx_buf,
            .len = tx_len,
        }
    };

    struct spi_buf rx_buffer[2] = {
        {
            .buf = tx_buf,
            .len = tx_len,
        },
        {
            .buf = rx_buf,
            .len = rx_len,
        }
    };

    struct spi_buf_set tx_set = {
        .buffers = tx_buffer,
        .count   = 1,
    };

    struct spi_buf_set rx_set = {
        .buffers = rx_buffer,
        .count   = 2,
    };

#if defined(CONFIG_SPI_ASYNC)
    return spi_transceive_cb(spi_dev, spi_cfg, &tx_set, &rx_set, spi_rdy, NULL);
#else
    /* Synchronous SPI transfer */

    return spi_transceive(spi_dev, spi_cfg, &tx_set, &rx_set);
#endif
}

static int read_id(const struct device *spi_dev, struct spi_config *spi_cfg)
{
    uint8_t id[4]  = { 0xFF };
    uint8_t cmd[1] = { MB85RS4MT_RDID };

    if (0 != spi_transfer(spi_dev, spi_cfg, cmd, sizeof(cmd), id, sizeof(id)))
    {
        return -EIO;
    }

    if (id[0] != 0x04)
    {
        return -EIO;
    }

    if (id[1] != 0x7f)
    {
        return -EIO;
    }

    if (id[2] != 0x49)
    {
        return -EIO;
    }

    if (id[3] != 0x0B)
    {
        return -EIO;
    }

    return 0;
}
________________________________________________________________________________________________________________

So id[4]  is overwritten with all zeros????

I really don't understand what is going on. Note that all connections between the FRAM and nRF are straight forward. Checked the print layout and stuff. 

Parents
  • Have you even read the code that you posted? The zero overwrite is expected when looking how the rx_buffers[2] are set up. It completely overwrites the tx_buf memory.

    Rember that SPI will always both transmit and receive at the same time.

  • Sorry don't know what you mean, 

    I've tried all kind of setups. I understand that the both Tx and Rx is active at the same time. Keeping the issue  

    https://github.com/zephyrproject-rtos/zephyr/issues/65512 in mind I first tried the following as bases, This does not work either. 
    ____________________________________________________________________________________________
    static int spi_transfer(const struct device *spi_dev, struct spi_config *spi_cfg, uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len)
    {
        /// READ github.com/.../65512

        struct spi_buf tx_buffer[1] = {
            {
                .buf = tx_buf,
                .len = tx_len,
            }
        };

        struct spi_buf rx_buffer[1] = {
            {
                .buf = rx_buf,
                .len = rx_len,
            },
        };

        struct spi_buf_set tx_set = {
            .buffers = tx_buffer,
            .count   = 1,
        };

        struct spi_buf_set rx_set = {
            .buffers = rx_buffer,
            .count   = 1,
        };

        #if defined(CONFIG_SPI_ASYNC)
        return spi_transceive_cb(spi_dev, spi_cfg, &tx_set, &rx_set, spi_rdy, NULL);
        #else
        /* Synchronous SPI transfer */

        return spi_transceive(spi_dev, spi_cfg, &tx_set, &rx_set);
        #endif
    }
    static int read_id(const struct device *spi_dev, struct spi_config *spi_cfg)
    {
        uint8_t id[5]  = { 0xFF };
        uint8_t cmd[1] = { MB85RS4MT_RDID };

        if (0 != spi_transfer(spi_dev, spi_cfg, cmd, sizeof(cmd), id, sizeof(id)))
        {
            return -EIO;
        }
    .....
    }

    ___________________________________________________________________

    the tx_buf is 1 byte containing the command. The receive buffer rx_buf  contains the ID memory space of 4 byte + 1 byte for reception during transmission of the RDID command. Same result applies. The complete ID[5] content is zero. I should at least expect some data which is not zero in for index 1..4

    see logic analyzer for the configuration above. Maybe my interpretation of the complete Zephyr SPI concept is wrong but it is very difficult to find proper background information. Especially the tx/rx config part. 

Reply
  • Sorry don't know what you mean, 

    I've tried all kind of setups. I understand that the both Tx and Rx is active at the same time. Keeping the issue  

    https://github.com/zephyrproject-rtos/zephyr/issues/65512 in mind I first tried the following as bases, This does not work either. 
    ____________________________________________________________________________________________
    static int spi_transfer(const struct device *spi_dev, struct spi_config *spi_cfg, uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len)
    {
        /// READ github.com/.../65512

        struct spi_buf tx_buffer[1] = {
            {
                .buf = tx_buf,
                .len = tx_len,
            }
        };

        struct spi_buf rx_buffer[1] = {
            {
                .buf = rx_buf,
                .len = rx_len,
            },
        };

        struct spi_buf_set tx_set = {
            .buffers = tx_buffer,
            .count   = 1,
        };

        struct spi_buf_set rx_set = {
            .buffers = rx_buffer,
            .count   = 1,
        };

        #if defined(CONFIG_SPI_ASYNC)
        return spi_transceive_cb(spi_dev, spi_cfg, &tx_set, &rx_set, spi_rdy, NULL);
        #else
        /* Synchronous SPI transfer */

        return spi_transceive(spi_dev, spi_cfg, &tx_set, &rx_set);
        #endif
    }
    static int read_id(const struct device *spi_dev, struct spi_config *spi_cfg)
    {
        uint8_t id[5]  = { 0xFF };
        uint8_t cmd[1] = { MB85RS4MT_RDID };

        if (0 != spi_transfer(spi_dev, spi_cfg, cmd, sizeof(cmd), id, sizeof(id)))
        {
            return -EIO;
        }
    .....
    }

    ___________________________________________________________________

    the tx_buf is 1 byte containing the command. The receive buffer rx_buf  contains the ID memory space of 4 byte + 1 byte for reception during transmission of the RDID command. Same result applies. The complete ID[5] content is zero. I should at least expect some data which is not zero in for index 1..4

    see logic analyzer for the configuration above. Maybe my interpretation of the complete Zephyr SPI concept is wrong but it is very difficult to find proper background information. Especially the tx/rx config part. 

Children
No Data
Related