Skip to content

Commit

Permalink
Merge pull request #426 from RathiSonika/update/nand_flash_work_buf_a…
Browse files Browse the repository at this point in the history
…lignment

update(spi_nand_flash): handle alignment and DMA requirements for work buffers
  • Loading branch information
RathiSonika authored Oct 22, 2024
2 parents 1639c16 + 3a550d8 commit 6c23b9c
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 16 deletions.
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.4.0"
version: "0.4.1"
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
37 changes: 27 additions & 10 deletions spi_nand_flash/src/nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "nand_flash_devices.h"
#include "esp_vfs_fat_nand.h"

static const char *TAG = "nand";
static const char *TAG = "nand_flash";

static esp_err_t spi_nand_winbond_init(spi_nand_flash_device_t *dev)
{
Expand All @@ -26,13 +26,15 @@ static esp_err_t spi_nand_winbond_init(spi_nand_flash_device_t *dev)
.command = CMD_READ_ID,
.dummy_bits = 16,
.miso_len = 2,
.miso_data = device_id_buf
.miso_data = device_id_buf,
.flags = SPI_TRANS_USE_RXDATA,
};
spi_nand_execute_transaction(dev->config.device_handle, &t);
uint16_t device_id = (device_id_buf[0] << 8) + device_id_buf[1];
dev->read_page_delay_us = 10;
dev->erase_block_delay_us = 2500;
dev->program_page_delay_us = 320;
ESP_LOGD(TAG, "%s: device_id: %x\n", __func__, device_id);
switch (device_id) {
case WINBOND_DI_AA20:
case WINBOND_DI_BA20:
Expand All @@ -58,11 +60,13 @@ static esp_err_t spi_nand_alliance_init(spi_nand_flash_device_t *dev)
.address_bytes = 1,
.dummy_bits = 8,
.miso_len = 1,
.miso_data = &device_id
.miso_data = &device_id,
.flags = SPI_TRANS_USE_RXDATA,
};
spi_nand_execute_transaction(dev->config.device_handle, &t);
dev->erase_block_delay_us = 3000;
dev->program_page_delay_us = 630;
ESP_LOGD(TAG, "%s: device_id: %x\n", __func__, device_id);
switch (device_id) {
case ALLIANCE_DI_25: //AS5F31G04SND-08LIN
dev->dhara_nand.num_blocks = 1024;
Expand Down Expand Up @@ -97,13 +101,14 @@ static esp_err_t spi_nand_gigadevice_init(spi_nand_flash_device_t *dev)
.command = CMD_READ_ID,
.dummy_bits = 16,
.miso_len = 1,
.miso_data = &device_id
.miso_data = &device_id,
.flags = SPI_TRANS_USE_RXDATA,
};
spi_nand_execute_transaction(dev->config.device_handle, &t);
dev->read_page_delay_us = 25;
dev->erase_block_delay_us = 3200;
dev->program_page_delay_us = 380;
printf("device_id: %x\n", device_id);
ESP_LOGD(TAG, "%s: device_id: %x\n", __func__, device_id);
switch (device_id) {
case GIGADEVICE_DI_51:
case GIGADEVICE_DI_41:
Expand Down Expand Up @@ -136,12 +141,14 @@ static esp_err_t spi_nand_micron_init(spi_nand_flash_device_t *dev)
.command = CMD_READ_ID,
.dummy_bits = 16,
.miso_len = 1,
.miso_data = &device_id
.miso_data = &device_id,
.flags = SPI_TRANS_USE_RXDATA,
};
spi_nand_execute_transaction(dev->config.device_handle, &t);
dev->read_page_delay_us = 115;
dev->erase_block_delay_us = 2000;
dev->program_page_delay_us = 240;
ESP_LOGD(TAG, "%s: device_id: %x\n", __func__, device_id);
switch (device_id) {
case MICRON_DI_34:
dev->dhara_nand.num_blocks = 2048;
Expand All @@ -162,9 +169,11 @@ static esp_err_t detect_chip(spi_nand_flash_device_t *dev)
.address = 0, // This normally selects the manufacturer id. Some chips ignores it, but still expects 8 dummy bits here
.address_bytes = 1,
.miso_len = 1,
.miso_data = &manufacturer_id
.miso_data = &manufacturer_id,
.flags = SPI_TRANS_USE_RXDATA,
};
spi_nand_execute_transaction(dev->config.device_handle, &t);
ESP_LOGD(TAG, "%s: manufacturer_id: %x\n", __func__, manufacturer_id);

switch (manufacturer_id) {
case SPI_NAND_FLASH_ALLIANCE_MI: // Alliance
Expand Down Expand Up @@ -221,10 +230,13 @@ esp_err_t spi_nand_flash_init_device(spi_nand_flash_config_t *config, spi_nand_f
(*handle)->page_size = 1 << (*handle)->dhara_nand.log2_page_size;
(*handle)->block_size = (1 << (*handle)->dhara_nand.log2_ppb) * (*handle)->page_size;
(*handle)->num_blocks = (*handle)->dhara_nand.num_blocks;
(*handle)->work_buffer = malloc((*handle)->page_size);

(*handle)->work_buffer = heap_caps_malloc((*handle)->page_size, MALLOC_CAP_DMA | MALLOC_CAP_8BIT);
ESP_GOTO_ON_FALSE((*handle)->work_buffer != NULL, ESP_ERR_NO_MEM, fail, TAG, "nomem");

(*handle)->read_buffer = heap_caps_malloc((*handle)->page_size, MALLOC_CAP_DMA | MALLOC_CAP_8BIT);
ESP_GOTO_ON_FALSE((*handle)->read_buffer != NULL, ESP_ERR_NO_MEM, fail, TAG, "nomem");

(*handle)->mutex = xSemaphoreCreateMutex();
if (!(*handle)->mutex) {
ret = ESP_ERR_NO_MEM;
Expand All @@ -242,6 +254,9 @@ esp_err_t spi_nand_flash_init_device(spi_nand_flash_config_t *config, spi_nand_f
if ((*handle)->work_buffer != NULL) {
free((*handle)->work_buffer);
}
if ((*handle)->read_buffer != NULL) {
free((*handle)->read_buffer);
}
if ((*handle)->mutex != NULL) {
vSemaphoreDelete((*handle)->mutex);
}
Expand Down Expand Up @@ -281,16 +296,17 @@ esp_err_t spi_nand_flash_read_sector(spi_nand_flash_device_t *handle, uint8_t *b

xSemaphoreTake(handle->mutex, portMAX_DELAY);

if (dhara_map_read(&handle->dhara_map, sector_id, buffer, &err)) {
if (dhara_map_read(&handle->dhara_map, sector_id, handle->read_buffer, &err)) {
ret = ESP_ERR_FLASH_BASE + err;
} else if (err) {
// This indicates a soft ECC error, we rewrite the sector to recover
if (dhara_map_write(&handle->dhara_map, sector_id, buffer, &err)) {
if (dhara_map_write(&handle->dhara_map, sector_id, handle->read_buffer, &err)) {
ret = ESP_ERR_FLASH_BASE + err;
}
}

xSemaphoreGive(handle->mutex);
memcpy(buffer, handle->read_buffer, handle->page_size);
return ret;
}

Expand Down Expand Up @@ -339,6 +355,7 @@ esp_err_t spi_nand_flash_get_sector_size(spi_nand_flash_device_t *handle, uint32
esp_err_t spi_nand_flash_deinit_device(spi_nand_flash_device_t *handle)
{
free(handle->work_buffer);
free(handle->read_buffer);
vSemaphoreDelete(handle->mutex);
free(handle);
return ESP_OK;
Expand Down
1 change: 1 addition & 0 deletions spi_nand_flash/src/nand.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct spi_nand_flash_device_t {
struct dhara_map dhara_map;
struct dhara_nand dhara_nand;
uint8_t *work_buffer;
uint8_t *read_buffer;
uint32_t read_page_delay_us;
uint32_t erase_block_delay_us;
uint32_t program_page_delay_us;
Expand Down
30 changes: 25 additions & 5 deletions spi_nand_flash/src/spi_nand_oper.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
* SPDX-FileContributor: 2015-2023 Espressif Systems (Shanghai) CO LTD
*/

#include <string.h>
#include "spi_nand_oper.h"
#include "driver/spi_master.h"

esp_err_t spi_nand_execute_transaction(spi_device_handle_t device, spi_nand_transaction_t *transaction)
{
spi_transaction_ext_t e = {
.base = {
.flags = SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_DUMMY,
.flags = SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_DUMMY | transaction->flags,
.rxlength = transaction->miso_len * 8,
.rx_buffer = transaction->miso_data,
.length = transaction->mosi_len * 8,
Expand All @@ -26,7 +27,21 @@ esp_err_t spi_nand_execute_transaction(spi_device_handle_t device, spi_nand_tran
.dummy_bits = transaction->dummy_bits
};

return spi_device_transmit(device, (spi_transaction_t *) &e);
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) {
assert(transaction->miso_len <= 4 && "SPI_TRANS_USE_RXDATA used for a long transaction");
}

esp_err_t ret = spi_device_transmit(device, (spi_transaction_t *) &e);
if (ret == ESP_OK) {
if (transaction->flags == SPI_TRANS_USE_RXDATA) {
memcpy(transaction->miso_data, e.base.rx_data, transaction->miso_len);
}
}
return ret;
}

esp_err_t spi_nand_read_register(spi_device_handle_t device, uint8_t reg, uint8_t *val)
Expand All @@ -36,7 +51,8 @@ esp_err_t spi_nand_read_register(spi_device_handle_t device, uint8_t reg, uint8_
.address_bytes = 1,
.address = reg,
.miso_len = 1,
.miso_data = val
.miso_data = val,
.flags = SPI_TRANS_USE_RXDATA,
};

return spi_nand_execute_transaction(device, &t);
Expand All @@ -49,7 +65,8 @@ esp_err_t spi_nand_write_register(spi_device_handle_t device, uint8_t reg, uint8
.address_bytes = 1,
.address = reg,
.mosi_len = 1,
.mosi_data = &val
.mosi_data = &val,
.flags = SPI_TRANS_USE_TXDATA,
};

return spi_nand_execute_transaction(device, &t);
Expand Down Expand Up @@ -83,7 +100,10 @@ esp_err_t spi_nand_read(spi_device_handle_t device, uint8_t *data, uint16_t colu
.address = column,
.miso_len = length,
.miso_data = data,
.dummy_bits = 8
.dummy_bits = 8,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
.flags = SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL,
#endif
};

return spi_nand_execute_transaction(device, &t);
Expand Down
1 change: 1 addition & 0 deletions spi_nand_flash/src/spi_nand_oper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct spi_nand_transaction_t {
uint32_t miso_len;
uint8_t *miso_data;
uint32_t dummy_bits;
uint32_t flags;
};

typedef struct spi_nand_transaction_t spi_nand_transaction_t;
Expand Down

0 comments on commit 6c23b9c

Please sign in to comment.