Skip to content
Merged
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.16.0]
- fix: fix nand flash issue caused by data length unalignment on esp32p4

## [0.15.0]
- feat: added support for Gigadevice (GD5F2GM7xExxG) 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.15.0"
version: "0.16.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
121 changes: 98 additions & 23 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 All @@ -34,11 +37,11 @@ esp_err_t spi_nand_execute_transaction(spi_nand_flash_device_t *handle, spi_nand
.dummy_bits = transaction->dummy_bits
};

if (transaction->flags == SPI_TRANS_USE_TXDATA) {
if (transaction->flags & SPI_TRANS_USE_TXDATA) {
assert(transaction->mosi_len <= 4 && "SPI_TRANS_USE_TXDATA used for a long transaction");
memcpy(e.base.tx_data, transaction->mosi_data, transaction->mosi_len);
}
if (transaction->flags == SPI_TRANS_USE_RXDATA) {
if (transaction->flags & SPI_TRANS_USE_RXDATA) {
assert(transaction->miso_len <= 4 && "SPI_TRANS_USE_RXDATA used for a long transaction");
}

Expand Down Expand Up @@ -67,7 +70,7 @@ esp_err_t spi_nand_read_register(spi_nand_flash_device_t *handle, uint8_t reg, u

esp_err_t spi_nand_write_register(spi_nand_flash_device_t *handle, uint8_t reg, uint8_t val)
{
spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.command = CMD_SET_REGISTER,
.address_bytes = 1,
.address = reg,
Expand All @@ -81,7 +84,7 @@ esp_err_t spi_nand_write_register(spi_nand_flash_device_t *handle, uint8_t reg,

esp_err_t spi_nand_write_enable(spi_nand_flash_device_t *handle)
{
spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.command = CMD_WRITE_ENABLE
};

Expand All @@ -90,7 +93,7 @@ esp_err_t spi_nand_write_enable(spi_nand_flash_device_t *handle)

esp_err_t spi_nand_read_page(spi_nand_flash_device_t *handle, uint32_t page)
{
spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.command = CMD_PAGE_READ,
.address_bytes = 3,
.address = page
Expand All @@ -99,32 +102,65 @@ esp_err_t spi_nand_read_page(spi_nand_flash_device_t *handle, uint32_t page)
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)) ? 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;
dummy_bits = 4;
}

spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.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,
};

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
#endif
return spi_nand_execute_transaction(handle, &t);
esp_err_t ret = spi_nand_execute_transaction(handle, &t);

#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
memcpy(data, data_read, length);
#endif
return ret;
}

static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
Expand All @@ -133,41 +169,56 @@ static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *da
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;
dummy_bits = 4;
}

spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.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,
};

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
#endif
return spi_nand_execute_transaction(handle, &t);
esp_err_t ret = spi_nand_execute_transaction(handle, &t);

#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
memcpy(data, data_read, length);
#endif
return ret;
}

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;
}
spi_nand_transaction_t t = {
#endif

spi_nand_transaction_t t = {
.command = CMD_READ_FAST,
.address_bytes = 2,
.address = column,
Expand All @@ -185,9 +236,19 @@ static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *da
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 All @@ -204,7 +265,7 @@ esp_err_t spi_nand_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t

esp_err_t spi_nand_program_execute(spi_nand_flash_device_t *handle, uint32_t page)
{
spi_nand_transaction_t t = {
spi_nand_transaction_t t = {
.command = CMD_PROGRAM_EXECUTE,
.address_bytes = 3,
.address = page
Expand All @@ -222,14 +283,28 @@ esp_err_t spi_nand_program_load(spi_nand_flash_device_t *handle, const uint8_t *
spi_flags = SPI_TRANS_MODE_QIO;
}

spi_nand_transaction_t t = {
uint16_t data_write_len = length;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
memcpy(handle->temp_buffer, data, length);
const uint8_t *data_write = handle->temp_buffer;
data_write_len = check_length_alignment(handle, length);
#endif

spi_nand_transaction_t t = {
.command = cmd,
.address_bytes = 2,
.address = column,
.mosi_len = length,
.mosi_len = data_write_len,
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
.mosi_data = data_write,
#else
.mosi_data = data,
#endif
.flags = spi_flags,
};
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
#endif

return spi_nand_execute_transaction(handle, &t);
}
Expand Down
2 changes: 1 addition & 1 deletion spi_nand_flash/test_app/main/test_app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void setUp(void)
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
unity_utils_evaluate_leaks_direct(20);
unity_utils_evaluate_leaks_direct(32);
}

void app_main(void)
Expand Down
Loading