Interfacing nrf 5340 dk with Winbond W25Q128JV serial flash memory breakout board from sparkfun

Greetings,

I am fairly new to SPI interface. I tried interfacing my Winbond serial flash memory breakout board with nrf 5340 dk using the master-slave code that I found. I did modify the overlay file and main file to make it just master code. This is my overlay file.

For the main file, I am only trying to see if SPI communication is established and get a manufacturer id for my flash memory. According to winbond datasheet, I guess I need to enable a reset instruction before reading the part id. Here is my main code:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

#define MY_SPI_MASTER DT_NODELABEL(my_spi_master)

// SPI master functionality
const struct device *spi_dev;

struct spi_cs_control spim_cs = {
    .gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master)),
    .delay = 0,
};


static const struct spi_config spi_cfg = {
    .operation = SPI_WORD_SET(8) |  SPI_MODE_CPHA,
    .frequency = 130000000,
    .slave = 0,
    .cs = &spim_cs,
};

static void spi_init(void)
{
    spi_dev = DEVICE_DT_GET(MY_SPI_MASTER);
    if(!device_is_ready(spi_dev)) {
        printk("SPI master device not ready!\n");
    }
    if(!device_is_ready(spim_cs.gpio.port)){
        printk("SPI master chip select device not ready!\n");
    }
}

// Function to send a single SPI instruction
static int send_spi_instruction(const struct device *spi_dev, const struct spi_config *spi_cfg, uint8_t instruction)
{
    struct spi_buf tx_buf = {
        .buf = &instruction,
        .len = 1,
    };
    struct spi_buf_set tx_bufs = {
        .buffers = &tx_buf,
        .count = 1,
    };

    return spi_write(spi_dev, spi_cfg, &tx_bufs);
}

// Function to perform a software reset on the W25Q128JV
static void reset_flash_device(const struct device *spi_dev, const struct spi_config *spi_cfg)
{
    int err;

    // Send Enable Reset instruction (66h)
    err = send_spi_instruction(spi_dev, spi_cfg, 0x66);
    if (err) {
        printk("Failed to send Enable Reset instruction: %d\n", err);
        return;
    }

    // Wait a little bit to ensure the instruction is processed
    k_sleep(K_MSEC(1));

    // Send Reset instruction (99h)
    err = send_spi_instruction(spi_dev, spi_cfg, 0x99);
    if (err) {
        printk("Failed to send Reset instruction: %d\n", err);
        return;
    }

    // Wait for the device to reset
    k_sleep(K_USEC(30)); // Waiting more than tRST (30μS) as per the datasheet

    printk("Flash device reset successfully.\n");
}


static void read_part_id(void) {
    // Command to read Manufacturer and Device ID, followed by 3 dummy bytes for the address
    uint8_t cmd[] = {0x90, 0x00, 0x00, 0x00};
    uint8_t id_data[2]; // Buffer to store the Manufacturer ID and Device ID

    // Set up the transmit buffer
    struct spi_buf tx_buf = {
        .buf = cmd,
        .len = sizeof(cmd)
    };
    struct spi_buf_set tx_bufs = {
        .buffers = &tx_buf,
        .count = 1
    };

    // Set up the receive buffer
    struct spi_buf rx_buf = {
        .buf = id_data,
        .len = sizeof(id_data)
    };
    struct spi_buf_set rx_bufs = {
        .buffers = &rx_buf,
        .count = 1
    };

    // Send the command and read back the ID data
    int err = spi_transceive(spi_dev, &spi_cfg, &tx_bufs, &rx_bufs);
    if (err) {
        printk("Failed to read Part ID\n");
        return;
    }

    printk("Manufacturer ID: 0x%X, Device ID: 0x%X\n", id_data[0], id_data[1]);
}



void main(void)
{
    int ret;
    spi_init();

    read_part_id(); // Read and print the Part ID

    printk("SPI flash reset complete. Proceeding with application...\n");

     reset_flash_device(spi_dev, &spi_cfg);
}
My wiring details:
Winbond W25Q128JV          nrf5340DK
3.3V                                       Vdd
cs                                           P1.12(SS)
clk                                          P1.15SCK
DI                                           P1.13MOSI
DO                                         P1.14MISO
WP                                         pulled high(active low)
HLD                                        pulled high(active low)
GND                                       GND
My serial terminal output is always 0xff. I am not sure if my SPI communication has been properely established or not. Here is the screenshot of my terminal
Parents Reply Children
Related