External Flash Interface on HSPI, Garbage data read issue

rahul.b.patel
Posts: 62
Joined: Wed Apr 19, 2017 6:35 am

External Flash Interface on HSPI, Garbage data read issue

Postby rahul.b.patel » Tue Sep 12, 2017 12:16 pm

Hello,
I have interfaced flash chip (Windbond's W25Q128FV) on HSPI interface with wrover kit. I am facing one issue with IDFv2.1 while reading the data from external flash, while this issue is not produced in IDFv2.0.

[*]The issue is that on each read command I get extra 3 bytes with 0 value before actual data.

[*]For example on reading data from address 0x000000 of the flash having first 5 bytes of data as {0x01,0x02,0x03,0x04,0x05}.
so, while reading 5 bytes from 0x000000 with flash read command(0x03), I get data in spi_transaction_t rx_buffer as { 0x00,0x00,0x00,0x01,0x02}.
[*]If I read 7 bytes then I get data as {0x00,0x00,0x00,0x01,0x02,0x03,0x04}.

[*]In short I get data {0x00,0x00,0x00}, first 3 bytes as extra dummy bytes with IDFv2.1 only. This is not with the case for IDFv2.0, in v2.0 this works perfectly. I get first 5 bytes read as {0x01,0x02,0x03,0x04,0x05} in IDFv2.0.

My configurations are as below,
esp_err_t ret;
spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num=12,
.mosi_io_num=13,
.sclk_io_num=14,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
.max_transfer_sz=0, //comment out this line for IDFv2.0
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=800000,
.mode=0,
.spics_io_num=5,
.queue_size=7,
.flags=SPI_DEVICE_HALFDUPLEX,

};
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
assert(ret==ESP_OK);
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
assert(ret==ESP_OK);


Is there required to change any configurations for IDFv2.1..? Hope I have given understandable explanation of the issue.

Thanks.

rahul.b.patel
Posts: 62
Joined: Wed Apr 19, 2017 6:35 am

Re: External Flash Interface on HSPI, Garbage data read issue

Postby rahul.b.patel » Tue Sep 12, 2017 12:56 pm

Okay. It works without DMA channel with spi_bus_initialize(HSPI_HOST, &buscfg, 0).

zcg127
Posts: 5
Joined: Tue Jan 16, 2018 6:51 am

Re: External Flash Interface on HSPI, Garbage data read issue

Postby zcg127 » Tue Feb 06, 2018 6:52 am

Hi,
I'm using the HSPI to drive a W25Q128 under IDF v3.0 and it just doesn't work , would you like to share your program about this chip likes read and write operation,etc. , thanks a lot .

Best regards,
Zhang anderson

rahul.b.patel
Posts: 62
Joined: Wed Apr 19, 2017 6:35 am

Re: External Flash Interface on HSPI, Garbage data read issue

Postby rahul.b.patel » Fri Feb 09, 2018 1:04 pm

zcg127 wrote:Hi,
I'm using the HSPI to drive a W25Q128 under IDF v3.0 and it just doesn't work , would you like to share your program about this chip likes read and write operation,etc. , thanks a lot .

Best regards,
Zhang anderson
Hi Zhang,
I have attached some test code that I had been testing with HSPI flash. I hope it will be helpful.



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=0, //comment out this line for IDFv2.0
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=800000,
.mode=0,
.spics_io_num=PIN_NUM_CS,
.queue_size=7,
.flags=SPI_DEVICE_HALFDUPLEX,

};
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 0);
assert(ret==ESP_OK);

ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
assert(ret==ESP_OK);
uint8_t data[MAX];
static spi_transaction_t t;
uint8_t sr=0x05;
uint8_t sd=0;
memset(&t, 0, sizeof(t));

/* read register 1 */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);
// vTaskDelay(500/portTICK_RATE_MS);
uint8_t cmd=0x06;

/* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
// vTaskDelay(500/portTICK_RATE_MS);

/* register */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);

/* manufacture ID */
uint8_t Did[3]={0};
uint8_t id[]={0x90,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
// t.command=0x90;
// t.flags = SPI_TRANS_MODE_DIO,
t.length=8*4; //Command is 8 bits
t.tx_buffer=&id; //The data is the cmd itself
t.rxlength=8*3;
t.rx_buffer=&Did;
ret=spi_device_transmit(spi, &t);
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
ESP_LOGI(TAG,"Manufacture ID :");
for(int i=0;i<3;i++)
{
printf("%x ",Did);
}


/* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
// vTaskDelay(500/portTICK_RATE_MS);

/* register */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);


#if 1
/* read data */
memset(data,0,MAX);
uint8_t cmd12[]={0x03,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
t.length=8*4; //Command is 8 bits
t.tx_buffer=&cmd12;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");



/* erase sector */
uint8_t edata[]={0x20,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
t.length=8*4;
t.tx_buffer=&edata;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x20 Transmit fails");
}
vTaskDelay(3000/portTICK_RATE_MS);

/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after erase: %x",sd);
vTaskDelay(500/portTICK_RATE_MS);

// /* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
vTaskDelay(500/portTICK_RATE_MS);


/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after erase write enable. : %x",sd);


/* read data */
memset(data,0,MAX);
memset(&t, 0, sizeof(t));
t.length=8*4;
t.tx_buffer=&cmd12;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");


#if 1
/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register before write : %x",sd);


/* write data */
uint8_t wdata[]={0x02,0x00,0x00,0x00,0x11,0x12,0x13,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04};
memset(&t, 0, sizeof(t));
t.length=8*MAX; //Command is 8 bits
t.tx_buffer=wdata;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x02 Transmit fails");
}

/* register */
memset(data,0,100);
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after write : %x",sd);

uint8_t cmd13[]={0x03,0x00,0x00,0x00};

memset(&t, 0, sizeof(t));
t.length=8*4; //Command is 8 bits
t.tx_buffer=&cmd13;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");

zcg127
Posts: 5
Joined: Tue Jan 16, 2018 6:51 am

Re: External Flash Interface on HSPI, Garbage data read issue

Postby zcg127 » Sat Feb 10, 2018 5:18 am

rahul.b.patel wrote:
zcg127 wrote:Hi,
I'm using the HSPI to drive a W25Q128 under IDF v3.0 and it just doesn't work , would you like to share your program about this chip likes read and write operation,etc. , thanks a lot .

Best regards,
Zhang anderson
Hi Zhang,
I have attached some test code that I had been testing with HSPI flash. I hope it will be helpful.



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=0, //comment out this line for IDFv2.0
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=800000,
.mode=0,
.spics_io_num=PIN_NUM_CS,
.queue_size=7,
.flags=SPI_DEVICE_HALFDUPLEX,

};
ret=spi_bus_initialize(HSPI_HOST, &buscfg, 0);
assert(ret==ESP_OK);

ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
assert(ret==ESP_OK);
uint8_t data[MAX];
static spi_transaction_t t;
uint8_t sr=0x05;
uint8_t sd=0;
memset(&t, 0, sizeof(t));

/* read register 1 */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);
// vTaskDelay(500/portTICK_RATE_MS);
uint8_t cmd=0x06;

/* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
// vTaskDelay(500/portTICK_RATE_MS);

/* register */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);

/* manufacture ID */
uint8_t Did[3]={0};
uint8_t id[]={0x90,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
// t.command=0x90;
// t.flags = SPI_TRANS_MODE_DIO,
t.length=8*4; //Command is 8 bits
t.tx_buffer=&id; //The data is the cmd itself
t.rxlength=8*3;
t.rx_buffer=&Did;
ret=spi_device_transmit(spi, &t);
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
ESP_LOGI(TAG,"Manufacture ID :");
for(int i=0;i<3;i++)
{
printf("%x ",Did);
}


/* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
// vTaskDelay(500/portTICK_RATE_MS);

/* register */
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register : %x",sd);


#if 1
/* read data */
memset(data,0,MAX);
uint8_t cmd12[]={0x03,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
t.length=8*4; //Command is 8 bits
t.tx_buffer=&cmd12;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");



/* erase sector */
uint8_t edata[]={0x20,0x00,0x00,0x00};
memset(&t, 0, sizeof(t));
t.length=8*4;
t.tx_buffer=&edata;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x20 Transmit fails");
}
vTaskDelay(3000/portTICK_RATE_MS);

/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after erase: %x",sd);
vTaskDelay(500/portTICK_RATE_MS);

// /* write enable */
memset(&t, 0, sizeof(t));
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x06 Transmit fails");
}
vTaskDelay(500/portTICK_RATE_MS);


/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after erase write enable. : %x",sd);


/* read data */
memset(data,0,MAX);
memset(&t, 0, sizeof(t));
t.length=8*4;
t.tx_buffer=&cmd12;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");


#if 1
/* register */
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register before write : %x",sd);


/* write data */
uint8_t wdata[]={0x02,0x00,0x00,0x00,0x11,0x12,0x13,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04,0x01,0x02,0x03,0x04};
memset(&t, 0, sizeof(t));
t.length=8*MAX; //Command is 8 bits
t.tx_buffer=wdata;
t.rx_buffer=NULL;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x02 Transmit fails");
}

/* register */
memset(data,0,100);
memset(&t, 0, sizeof(t));
t.rxlength=8;
t.rx_buffer=&sd;
t.length=8;
t.tx_buffer=&sr;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x05 Transmit fails");
}
ESP_LOGI(TAG,"Register after write : %x",sd);

uint8_t cmd13[]={0x03,0x00,0x00,0x00};

memset(&t, 0, sizeof(t));
t.length=8*4; //Command is 8 bits
t.tx_buffer=&cmd13;
t.rxlength=8*MAX;
t.rx_buffer=data;
ret=spi_device_transmit(spi, &t); //Transmit!
if(ret != ESP_OK)
{
ESP_LOGE(TAG,"command 0x03 Transmit fails");
}
for(int i=0;i<MAX;i++)
printf("%x ",data);
printf("\r\n");

Hi rahul.b.patel ,it works ,now i'm tring to using it under idf v3.0 & full-duplex ,thanks a lot :D

lllucius
Posts: 13
Joined: Sun Feb 11, 2018 9:02 am

Re: External Flash Interface on HSPI, Garbage data read issue

Postby lllucius » Sun Feb 11, 2018 6:16 pm

Here's another example:

External flash component: https://github.com/lllucius/esp32_extflash

And a couple of example filesystems that utilize it:

FatFS: https://github.com/lllucius/esp32_fatflash
LittleFS: https://github.com/lllucius/esp32_littleflash

Who is online

Users browsing this forum: zamek42@gmail.com and 116 guests