ESP32 SPI external flash driver help
Posted: Mon Oct 18, 2021 8:30 am
Hello. I have recently written my own I2C driver, now I am trying to work with the SPI and write my own external flash memory driver.
The flash chip datasheet:
https://datasheet-pdf.com/PDF/GD5F1GQ4U ... ice-791680
I have a function that is supposed to send some data over SPI:
I initialise SPI bus:
Note that spi_device_handle_t I have created as global because I may need to access the SPI functions from other components so it is more convenient to have it global even thought this may not be the best solution.
My full .c file:
my full .h file:
And in my main.c I do:
I am trying to understand a little bit more about how SPI works and how can I read from registers.
https://ibb.co/3Skn8nL
For example, when I send the command 9F ( Read ID), do I also need to send something else? For example, do I need to send the addresses as shown in Read ID command description?
The result I get from my read_id command is:
The flash chip datasheet:
https://datasheet-pdf.com/PDF/GD5F1GQ4U ... ice-791680
I have a function that is supposed to send some data over SPI:
Code: Select all
static void spi_cmd(spi_device_handle_t spi, const uint8_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd; //The data is the cmd itself
t.user=(void*)0; //D/C needs to be set to 0
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}
I initialise SPI bus:
Code: Select all
void SPI_init(){
esp_err_t ret;
//spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num=PIN_NUM_MISO,
.mosi_io_num=PIN_NUM_MOSI,
.sclk_io_num=PIN_NUM_CLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
.max_transfer_sz=PARALLEL_LINES*320*2+8
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=10*1000*1000, //Clock out at 10 MHz
.mode=0, //SPI mode 0
.spics_io_num=PIN_NUM_CS, //CS pin
.queue_size=7, //We want to be able to queue 7 transactions at a time
//.pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
};
My full .c file:
Code: Select all
#include "GD5F1GQ4UEYIG.h"
spi_device_handle_t external_flash;
static void spi_cmd(spi_device_handle_t spi, const uint8_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd; //The data is the cmd itself
t.user=(void*)0; //D/C needs to be set to 0
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}
uint32_t GD5F1_get_id(spi_device_handle_t spi)
{
//get_id cmd
spi_cmd(spi, 0x9F);
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=8*3;
t.flags = SPI_TRANS_USE_RXDATA;
t.user = (void*)1;
esp_err_t ret = spi_device_polling_transmit(spi, &t);
assert( ret == ESP_OK );
return *(uint32_t*)t.rx_data;
}
void GD5F1_init(spi_device_handle_t spi)
{
//detect LCD type
uint32_t GD5F1_id = GD5F1_get_id(spi);
printf("GD5F1_id: %08X\n", GD5F1_id);
}
void SPI_init(){
esp_err_t ret;
//spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num=PIN_NUM_MISO,
.mosi_io_num=PIN_NUM_MOSI,
.sclk_io_num=PIN_NUM_CLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
.max_transfer_sz=PARALLEL_LINES*320*2+8
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=10*1000*1000, //Clock out at 10 MHz
.mode=0, //SPI mode 0
.spics_io_num=PIN_NUM_CS, //CS pin
.queue_size=7, //We want to be able to queue 7 transactions at a time
//.pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
};
//Initialize the SPI bus
ret=spi_bus_initialize(EEPROM_HOST, &buscfg, DMA_CHAN);
ESP_ERROR_CHECK(ret);
//Attach the LCD to the SPI bus
ret=spi_bus_add_device(EEPROM_HOST, &devcfg, &external_flash);
ESP_ERROR_CHECK(ret);
}
Code: Select all
#ifndef GD5F1GQ4UEYIG_H
#define GD5F1GQ4UEYIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "string.h"
#define EEPROM_HOST HSPI_HOST
#define DMA_CHAN 2
#define PIN_NUM_MISO 19 // OK
#define PIN_NUM_MOSI 23 // OK
#define PIN_NUM_CLK 18 // OK
#define PIN_NUM_CS 5 // OK
#define PARALLEL_LINES 16
extern spi_device_handle_t external_flash;
void SPI_init();
uint32_t GD5F1_get_id(spi_device_handle_t spi);
void GD5F1_init(spi_device_handle_t spi);
#ifdef __cplusplus
}
#endif
#endif
Code: Select all
SPI_init(); // initialise SPI bus
printf("getting spi id \n");
GD5F1_init(external_flash); // initialise SPI device GD5F1 ( external flash)
I am trying to understand a little bit more about how SPI works and how can I read from registers.
https://ibb.co/3Skn8nL
For example, when I send the command 9F ( Read ID), do I also need to send something else? For example, do I need to send the addresses as shown in Read ID command description?
The result I get from my read_id command is:
Code: Select all
getting spi id
GD5F1_id: 00FFFFFF