Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions spi_nand_flash/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [0.15.0]
- fix: fix nand flash issue caused by data length unalignment on esp32p4

## [0.14.0]
- feat: added support for XTX (XT26G08D) and Gigadevice (GD5F4GM8) NAND flash

Expand Down
2 changes: 1 addition & 1 deletion spi_nand_flash/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ else()
"src/spi_nand_oper.c"
"vfs/vfs_fat_spinandflash.c")

set(priv_reqs vfs)
set(priv_reqs vfs esp_mm)
list(APPEND inc vfs)

if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "5.3")
Expand Down
2 changes: 1 addition & 1 deletion spi_nand_flash/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "0.14.0"
version: "0.15.0"
description: Driver for accessing SPI NAND Flash
url: https://github.com/espressif/idf-extra-components/tree/master/spi_nand_flash
issues: https://github.com/espressif/idf-extra-components/issues
Expand Down
71 changes: 61 additions & 10 deletions spi_nand_flash/src/spi_nand_oper.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <string.h>
#include "spi_nand_oper.h"
#include "driver/spi_master.h"
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
#include "esp_private/esp_cache_private.h"
#endif

esp_err_t spi_nand_execute_transaction(spi_nand_flash_device_t *handle, spi_nand_transaction_t *transaction)
{
Expand Down Expand Up @@ -99,12 +102,40 @@
return spi_nand_execute_transaction(handle, &t);
}

#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
static uint16_t check_length_alignment(spi_nand_flash_device_t *handle, uint16_t length)
{
size_t alignment;
uint16_t data_len = length;
esp_cache_get_alignment(MALLOC_CAP_DMA, &alignment);
bool is_length_unaligned = ((length + alignment - 1) & (~(alignment - 1))) ? true : false;
if (is_length_unaligned) {
if (length < alignment) {
data_len = ((length + alignment) & ~(alignment - 1));
} else {
data_len = ((length + (alignment - 1)) & ~(alignment - 1));
}
}
if (!(handle->config.flags & SPI_DEVICE_HALFDUPLEX)) {
data_len = data_len + alignment;
}
return data_len;
}
#endif

static esp_err_t spi_nand_quad_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
{
uint32_t spi_flags = SPI_TRANS_MODE_QIO;
uint8_t cmd = CMD_READ_X4;
uint8_t dummy_bits = 8;

uint8_t *data_read = data;
uint16_t data_read_len = length;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
data_read = handle->temp_buffer;
data_read_len = check_length_alignment(handle, length);
#endif

if (handle->config.io_mode == SPI_NAND_IO_MODE_QIO) {
spi_flags |= SPI_TRANS_MULTILINE_ADDR;
cmd = CMD_READ_QIO;
Expand All @@ -115,8 +146,8 @@
.command = cmd,
.address_bytes = 2,
.address = column,
.miso_len = length,
.miso_data = data,
.miso_len = data_read_len,
.miso_data = data_read,
.dummy_bits = dummy_bits,
.flags = spi_flags,
};
Expand All @@ -133,6 +164,13 @@
uint8_t cmd = CMD_READ_X2;
uint8_t dummy_bits = 8;

uint8_t *data_read = data;
uint16_t data_read_len = length;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
data_read = handle->temp_buffer;
data_read_len = check_length_alignment(handle, length);
#endif

if (handle->config.io_mode == SPI_NAND_IO_MODE_DIO) {
spi_flags |= SPI_TRANS_MULTILINE_ADDR;
cmd = CMD_READ_DIO;
Expand All @@ -143,8 +181,8 @@
.command = cmd,
.address_bytes = 2,
.address = column,
.miso_len = length,
.miso_data = data,
.miso_len = data_read_len,
.miso_data = data_read,
.dummy_bits = dummy_bits,
.flags = spi_flags,
};
Expand All @@ -157,16 +195,19 @@

static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
{
uint8_t *data_read = NULL;
uint16_t data_read_len;
uint8_t *data_read = data;
uint16_t data_read_len = length;
uint8_t half_duplex = handle->config.flags & SPI_DEVICE_HALFDUPLEX;
if (half_duplex) {
data_read_len = length;
data_read = data;
} else {
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
data_read = handle->temp_buffer;
data_read_len = check_length_alignment(handle, length);
#else
if (!half_duplex) {
data_read_len = length + 1;
data_read = handle->temp_buffer;
}
#endif

spi_nand_transaction_t t = {
.command = CMD_READ_FAST,
.address_bytes = 2,
Expand All @@ -185,9 +226,19 @@
if (ret != ESP_OK) {
goto fail;
}

#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
if (!half_duplex) {
memcpy(data, data_read + 1, length);
} else {
memcpy(data, data_read, length);
}
#else
if (!half_duplex) {
memcpy(data, data_read + 1, length);
}
#endif

fail:
return ret;
}
Expand Down
Loading