Skip to content

Commit c6fe5f6

Browse files
committed
fix(spi_nand_flash): fix nand flash issue caused by length unalignment on esp32p4
1 parent f467d5d commit c6fe5f6

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

spi_nand_flash/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ else()
2424
"src/spi_nand_oper.c"
2525
"vfs/vfs_fat_spinandflash.c")
2626

27-
set(priv_reqs vfs)
27+
set(priv_reqs vfs esp_mm)
2828
list(APPEND inc vfs)
2929

3030
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "5.3")

spi_nand_flash/src/spi_nand_oper.c

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include <string.h>
1010
#include "spi_nand_oper.h"
1111
#include "driver/spi_master.h"
12+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
13+
#include "esp_private/esp_cache_private.h"
14+
#endif
1215

1316
esp_err_t spi_nand_execute_transaction(spi_nand_flash_device_t *handle, spi_nand_transaction_t *transaction)
1417
{
@@ -99,12 +102,40 @@ esp_err_t spi_nand_read_page(spi_nand_flash_device_t *handle, uint32_t page)
99102
return spi_nand_execute_transaction(handle, &t);
100103
}
101104

105+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
106+
static uint16_t check_length_alignment(spi_nand_flash_device_t *handle, uint16_t length)
107+
{
108+
size_t alignment;
109+
uint16_t data_len = length;
110+
esp_cache_get_alignment(MALLOC_CAP_DMA, &alignment);
111+
bool is_length_unaligned = ((length + alignment - 1) & (~(alignment - 1))) ? true : false;
112+
if (is_length_unaligned) {
113+
if (length < alignment) {
114+
data_len = ((length + alignment) & ~(alignment - 1));
115+
} else {
116+
data_len = ((length + (alignment - 1)) & ~(alignment - 1));
117+
}
118+
}
119+
if (!(handle->config.flags & SPI_DEVICE_HALFDUPLEX)) {
120+
data_len = data_len + alignment;
121+
}
122+
return data_len;
123+
}
124+
#endif
125+
102126
static esp_err_t spi_nand_quad_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
103127
{
104128
uint32_t spi_flags = SPI_TRANS_MODE_QIO;
105129
uint8_t cmd = CMD_READ_X4;
106130
uint8_t dummy_bits = 8;
107131

132+
uint8_t *data_read = data;
133+
uint16_t data_read_len = length;
134+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
135+
data_read = handle->temp_buffer;
136+
data_read_len = check_length_alignment(handle, length);
137+
#endif
138+
108139
if (handle->config.io_mode == SPI_NAND_IO_MODE_QIO) {
109140
spi_flags |= SPI_TRANS_MULTILINE_ADDR;
110141
cmd = CMD_READ_QIO;
@@ -115,8 +146,8 @@ static esp_err_t spi_nand_quad_read(spi_nand_flash_device_t *handle, uint8_t *da
115146
.command = cmd,
116147
.address_bytes = 2,
117148
.address = column,
118-
.miso_len = length,
119-
.miso_data = data,
149+
.miso_len = data_read_len,
150+
.miso_data = data_read,
120151
.dummy_bits = dummy_bits,
121152
.flags = spi_flags,
122153
};
@@ -133,6 +164,13 @@ static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *da
133164
uint8_t cmd = CMD_READ_X2;
134165
uint8_t dummy_bits = 8;
135166

167+
uint8_t *data_read = data;
168+
uint16_t data_read_len = length;
169+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
170+
data_read = handle->temp_buffer;
171+
data_read_len = check_length_alignment(handle, length);
172+
#endif
173+
136174
if (handle->config.io_mode == SPI_NAND_IO_MODE_DIO) {
137175
spi_flags |= SPI_TRANS_MULTILINE_ADDR;
138176
cmd = CMD_READ_DIO;
@@ -143,8 +181,8 @@ static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *da
143181
.command = cmd,
144182
.address_bytes = 2,
145183
.address = column,
146-
.miso_len = length,
147-
.miso_data = data,
184+
.miso_len = data_read_len,
185+
.miso_data = data_read,
148186
.dummy_bits = dummy_bits,
149187
.flags = spi_flags,
150188
};
@@ -157,16 +195,19 @@ static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *da
157195

158196
static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
159197
{
160-
uint8_t *data_read = NULL;
161-
uint16_t data_read_len;
198+
uint8_t *data_read = data;
199+
uint16_t data_read_len = length;
162200
uint8_t half_duplex = handle->config.flags & SPI_DEVICE_HALFDUPLEX;
163-
if (half_duplex) {
164-
data_read_len = length;
165-
data_read = data;
166-
} else {
201+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
202+
data_read = handle->temp_buffer;
203+
data_read_len = check_length_alignment(handle, length);
204+
#else
205+
if (!half_duplex) {
167206
data_read_len = length + 1;
168207
data_read = handle->temp_buffer;
169208
}
209+
#endif
210+
170211
spi_nand_transaction_t t = {
171212
.command = CMD_READ_FAST,
172213
.address_bytes = 2,
@@ -185,9 +226,19 @@ static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *da
185226
if (ret != ESP_OK) {
186227
goto fail;
187228
}
229+
230+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
188231
if (!half_duplex) {
189232
memcpy(data, data_read + 1, length);
233+
} else {
234+
memcpy(data, data_read, length);
190235
}
236+
#else
237+
if (!half_duplex) {
238+
memcpy(data, data_read + 1, length);
239+
}
240+
#endif
241+
191242
fail:
192243
return ret;
193244
}

0 commit comments

Comments
 (0)