-
Notifications
You must be signed in to change notification settings - Fork 124
Open
Labels
Description
Answers checklist.
- I have read the component documentation ESP-IDF Components and the issue is not addressed there.
- I am using target and esp-idf version as defined in component's idf_component.yml
- I have searched the issue tracker for a similar issue and not found any related issue.
Which component are you using? If you choose Other, provide details in More Information.
spi_nand_flash
ESP-IDF version.
v5.5.1
Development Kit.
ESP32P4
Used Component version.
v0.17.0
More Information.
Run the nand_flash + FatFs example. spi_nand_program_load() may fail because the provided data buffer can reside in non-DMA-capable memory (and/or be not 64-byte aligned). The current implementation conditionally sets SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL based only on length alignment, without validating whether the buffer address and memory capabilities satisfy SPI DMA requirements.
When the data buffer is not DMA-capable or properly aligned, the SPI driver rejects the transaction, causing the NAND program operation to fail.
esp_err_t spi_nand_program_load(spi_nand_flash_device_t *handle, const uint8_t *data, uint16_t column, uint16_t length)
{
ESP_LOGI("nand", "spi_nand_program_load: column=%"PRIu16", length=%"PRIu16, column, length);
ESP_LOGI("nand", "data: %p, align 64 ? %d, dma capable ? %d", data, (uintptr_t)data % 64 == 0, esp_ptr_dma_capable(data));
uint8_t cmd = CMD_PROGRAM_LOAD;
uint32_t spi_flags = 0;
if (handle->config.io_mode == SPI_NAND_IO_MODE_QOUT || handle->config.io_mode == SPI_NAND_IO_MODE_QIO) {
cmd = CMD_PROGRAM_LOAD_X4;
spi_flags = SPI_TRANS_MODE_QIO;
}
const uint8_t *data_write = data;
uint16_t data_write_len = length;
// memcpy(handle->temp_buffer, data_write, length);
spi_nand_transaction_t t = {
.command = cmd,
.address_bytes = 2,
.address = column,
.mosi_len = data_write_len,
.mosi_data = data_write,
.flags = spi_flags,
};
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
// Check if length needs alignment for DMA
uint16_t aligned_len = check_length_alignment(handle, length);
if (aligned_len == length) {
t.flags |= SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL;
}
#endif
esp_err_t ret = spi_nand_execute_transaction(handle, &t);
return ret;
}
log:
I (1335) nand: spi_nand_program_load: column=0, length=2048
I (1335) nand: data: 0x480c1494, align 64? 0, dma capable? 0
E (1339) spi_master: setup_priv_desc(1193): Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but TX buffer addr&len not align to 64 byte, or not dma_capable
E (1352) spi_nand: nand_prog(223):
E (1356) spi_nand: Error in nand_prog 258
E (1359) diskio_nand: ff_nand_write(65): spi_nand_flash_write failed
E (1365) diskio_nand: ff_nand_write failed with error 0x4FF151F4
Reactions are currently unavailable