Skip to content

Commit

Permalink
update(spi_nand_flash): handle alignment and DMA requirements for wor…
Browse files Browse the repository at this point in the history
…k buffers
  • Loading branch information
RathiSonika committed Oct 16, 2024
1 parent 333e1ef commit 548138d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
30 changes: 22 additions & 8 deletions spi_nand_flash/src/nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ 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];
Expand Down Expand Up @@ -58,7 +59,8 @@ 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;
Expand Down Expand Up @@ -97,7 +99,8 @@ 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;
Expand Down Expand Up @@ -136,7 +139,8 @@ 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;
Expand All @@ -162,9 +166,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);
printf("manufacturer_id: %x\n", manufacturer_id);

switch (manufacturer_id) {
case SPI_NAND_FLASH_ALLIANCE_MI: // Alliance
Expand Down Expand Up @@ -221,10 +227,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 +251,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 +293,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);

Check warning

Code scanning / clang-tidy

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] Warning

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
return ret;
}

Expand Down Expand Up @@ -339,6 +352,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
26 changes: 21 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,17 @@ 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 && transaction->mosi_len <= 4) {
memcpy(e.base.tx_data, transaction->mosi_data, transaction->mosi_len);

Check warning

Code scanning / clang-tidy

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] Warning

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
}

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

Check warning

Code scanning / clang-tidy

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] Warning

Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
}
}
return ret;
}

esp_err_t spi_nand_read_register(spi_device_handle_t device, uint8_t reg, uint8_t *val)
Expand All @@ -36,7 +47,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 +61,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 +96,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, 1, 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 548138d

Please sign in to comment.