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); }
