Skip to content

Commit ac7a4e5

Browse files
authored
Merge pull request #583 from RathiSonika/fix/nand_flash_not_working_with_esp32p4
fix(spi_nand_flash): fix nand flash issue caused by data length unalignment on esp32p4
2 parents 698758e + 77c36a3 commit ac7a4e5

File tree

5 files changed

+104
-26
lines changed

5 files changed

+104
-26
lines changed

spi_nand_flash/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## [0.16.0]
2+
- fix: fix nand flash issue caused by data length unalignment on esp32p4
3+
14
## [0.15.0]
25
- feat: added support for Gigadevice (GD5F2GM7xExxG) NAND flash
36

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/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: "0.15.0"
1+
version: "0.16.0"
22
description: Driver for accessing SPI NAND Flash
33
url: https://github.com/espressif/idf-extra-components/tree/master/spi_nand_flash
44
issues: https://github.com/espressif/idf-extra-components/issues

spi_nand_flash/src/spi_nand_oper.c

Lines changed: 98 additions & 23 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
{
@@ -34,11 +37,11 @@ esp_err_t spi_nand_execute_transaction(spi_nand_flash_device_t *handle, spi_nand
3437
.dummy_bits = transaction->dummy_bits
3538
};
3639

37-
if (transaction->flags == SPI_TRANS_USE_TXDATA) {
40+
if (transaction->flags & SPI_TRANS_USE_TXDATA) {
3841
assert(transaction->mosi_len <= 4 && "SPI_TRANS_USE_TXDATA used for a long transaction");
3942
memcpy(e.base.tx_data, transaction->mosi_data, transaction->mosi_len);
4043
}
41-
if (transaction->flags == SPI_TRANS_USE_RXDATA) {
44+
if (transaction->flags & SPI_TRANS_USE_RXDATA) {
4245
assert(transaction->miso_len <= 4 && "SPI_TRANS_USE_RXDATA used for a long transaction");
4346
}
4447

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

6871
esp_err_t spi_nand_write_register(spi_nand_flash_device_t *handle, uint8_t reg, uint8_t val)
6972
{
70-
spi_nand_transaction_t t = {
73+
spi_nand_transaction_t t = {
7174
.command = CMD_SET_REGISTER,
7275
.address_bytes = 1,
7376
.address = reg,
@@ -81,7 +84,7 @@ esp_err_t spi_nand_write_register(spi_nand_flash_device_t *handle, uint8_t reg,
8184

8285
esp_err_t spi_nand_write_enable(spi_nand_flash_device_t *handle)
8386
{
84-
spi_nand_transaction_t t = {
87+
spi_nand_transaction_t t = {
8588
.command = CMD_WRITE_ENABLE
8689
};
8790

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

9194
esp_err_t spi_nand_read_page(spi_nand_flash_device_t *handle, uint32_t page)
9295
{
93-
spi_nand_transaction_t t = {
96+
spi_nand_transaction_t t = {
9497
.command = CMD_PAGE_READ,
9598
.address_bytes = 3,
9699
.address = page
@@ -99,32 +102,65 @@ 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)) ? 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;
111142
dummy_bits = 4;
112143
}
113144

114-
spi_nand_transaction_t t = {
145+
spi_nand_transaction_t t = {
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
};
123154

124155
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
125156
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
126157
#endif
127-
return spi_nand_execute_transaction(handle, &t);
158+
esp_err_t ret = spi_nand_execute_transaction(handle, &t);
159+
160+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
161+
memcpy(data, data_read, length);
162+
#endif
163+
return ret;
128164
}
129165

130166
static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
@@ -133,41 +169,56 @@ static esp_err_t spi_nand_dual_read(spi_nand_flash_device_t *handle, uint8_t *da
133169
uint8_t cmd = CMD_READ_X2;
134170
uint8_t dummy_bits = 8;
135171

172+
uint8_t *data_read = data;
173+
uint16_t data_read_len = length;
174+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
175+
data_read = handle->temp_buffer;
176+
data_read_len = check_length_alignment(handle, length);
177+
#endif
178+
136179
if (handle->config.io_mode == SPI_NAND_IO_MODE_DIO) {
137180
spi_flags |= SPI_TRANS_MULTILINE_ADDR;
138181
cmd = CMD_READ_DIO;
139182
dummy_bits = 4;
140183
}
141184

142-
spi_nand_transaction_t t = {
185+
spi_nand_transaction_t t = {
143186
.command = cmd,
144187
.address_bytes = 2,
145188
.address = column,
146-
.miso_len = length,
147-
.miso_data = data,
189+
.miso_len = data_read_len,
190+
.miso_data = data_read,
148191
.dummy_bits = dummy_bits,
149192
.flags = spi_flags,
150193
};
151194

152195
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
153196
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
154197
#endif
155-
return spi_nand_execute_transaction(handle, &t);
198+
esp_err_t ret = spi_nand_execute_transaction(handle, &t);
199+
200+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
201+
memcpy(data, data_read, length);
202+
#endif
203+
return ret;
156204
}
157205

158206
static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t column, uint16_t length)
159207
{
160-
uint8_t *data_read = NULL;
161-
uint16_t data_read_len;
208+
uint8_t *data_read = data;
209+
uint16_t data_read_len = length;
162210
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 {
211+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
212+
data_read = handle->temp_buffer;
213+
data_read_len = check_length_alignment(handle, length);
214+
#else
215+
if (!half_duplex) {
167216
data_read_len = length + 1;
168217
data_read = handle->temp_buffer;
169218
}
170-
spi_nand_transaction_t t = {
219+
#endif
220+
221+
spi_nand_transaction_t t = {
171222
.command = CMD_READ_FAST,
172223
.address_bytes = 2,
173224
.address = column,
@@ -185,9 +236,19 @@ static esp_err_t spi_nand_fast_read(spi_nand_flash_device_t *handle, uint8_t *da
185236
if (ret != ESP_OK) {
186237
goto fail;
187238
}
239+
240+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
188241
if (!half_duplex) {
189242
memcpy(data, data_read + 1, length);
243+
} else {
244+
memcpy(data, data_read, length);
190245
}
246+
#else
247+
if (!half_duplex) {
248+
memcpy(data, data_read + 1, length);
249+
}
250+
#endif
251+
191252
fail:
192253
return ret;
193254
}
@@ -204,7 +265,7 @@ esp_err_t spi_nand_read(spi_nand_flash_device_t *handle, uint8_t *data, uint16_t
204265

205266
esp_err_t spi_nand_program_execute(spi_nand_flash_device_t *handle, uint32_t page)
206267
{
207-
spi_nand_transaction_t t = {
268+
spi_nand_transaction_t t = {
208269
.command = CMD_PROGRAM_EXECUTE,
209270
.address_bytes = 3,
210271
.address = page
@@ -222,14 +283,28 @@ esp_err_t spi_nand_program_load(spi_nand_flash_device_t *handle, const uint8_t *
222283
spi_flags = SPI_TRANS_MODE_QIO;
223284
}
224285

225-
spi_nand_transaction_t t = {
286+
uint16_t data_write_len = length;
287+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
288+
memcpy(handle->temp_buffer, data, length);
289+
const uint8_t *data_write = handle->temp_buffer;
290+
data_write_len = check_length_alignment(handle, length);
291+
#endif
292+
293+
spi_nand_transaction_t t = {
226294
.command = cmd,
227295
.address_bytes = 2,
228296
.address = column,
229-
.mosi_len = length,
297+
.mosi_len = data_write_len,
298+
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE == 1
299+
.mosi_data = data_write,
300+
#else
230301
.mosi_data = data,
302+
#endif
231303
.flags = spi_flags,
232304
};
305+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
306+
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
307+
#endif
233308

234309
return spi_nand_execute_transaction(handle, &t);
235310
}

spi_nand_flash/test_app/main/test_app_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void setUp(void)
1818
void tearDown(void)
1919
{
2020
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
21-
unity_utils_evaluate_leaks_direct(20);
21+
unity_utils_evaluate_leaks_direct(32);
2222
}
2323

2424
void app_main(void)

0 commit comments

Comments
 (0)