Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spi_nand_flash): expose lower-level API and make it usable without Dhara #447

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions spi_nand_flash/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
set(srcs "src/nand.c"
"src/nand_winbond.c"
"src/nand_gigadevice.c"
"src/nand_alliance.c"
"src/nand_micron.c"
"src/nand_impl.c"
"src/nand_impl_wrap.c"
"src/spi_nand_oper.c"
"src/dhara_glue.c"
"vfs/vfs_fat_spinandflash.c"
Expand All @@ -16,5 +22,6 @@ set(priv_reqs vfs)

idf_component_register(SRCS ${srcs}
INCLUDE_DIRS include vfs diskio
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES ${reqs}
PRIV_REQUIRES ${priv_reqs})
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.6.0"
version: "0.7.0"
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
31 changes: 31 additions & 0 deletions spi_nand_flash/include/nand_private/nand_impl_wrap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <stdint.h>
#include "esp_err.h"
#include "spi_nand_flash.h"

#ifdef __cplusplus
extern "C" {
#endif

// These APIs provide direct access to lower-level NAND functions, bypassing the Dhara library.
RathiSonika marked this conversation as resolved.
Show resolved Hide resolved
// These functions differ from the similarly named `nand_*` functions in that they also take the mutex for the duration of the call.

esp_err_t nand_wrap_is_bad(spi_nand_flash_device_t *handle, uint32_t b, bool *is_bad_status);
esp_err_t nand_wrap_mark_bad(spi_nand_flash_device_t *handle, uint32_t b);
esp_err_t nand_wrap_erase_chip(spi_nand_flash_device_t *handle);
esp_err_t nand_wrap_erase_block(spi_nand_flash_device_t *handle, uint32_t b);
esp_err_t nand_wrap_prog(spi_nand_flash_device_t *handle, uint32_t p, const uint8_t *data);
esp_err_t nand_wrap_is_free(spi_nand_flash_device_t *handle, uint32_t p, bool *is_free_status);
esp_err_t nand_wrap_read(spi_nand_flash_device_t *handle, uint32_t p, size_t offset, size_t length, uint8_t *data);
esp_err_t nand_wrap_copy(spi_nand_flash_device_t *handle, uint32_t src, uint32_t dst);

#ifdef __cplusplus
}
#endif
31 changes: 23 additions & 8 deletions spi_nand_flash/include/spi_nand_flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2015-2024 Espressif Systems (Shanghai) CO LTD
*/

#pragma once
Expand All @@ -12,7 +12,6 @@
#include "esp_err.h"
#include "driver/spi_common.h"
#include "driver/spi_master.h"
#include "dhara/map.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -47,7 +46,7 @@ esp_err_t spi_nand_flash_init_device(spi_nand_flash_config_t *config, spi_nand_f
* @param sector_id The id of the sector to read.
* @return ESP_OK on success, or a flash error code if the read failed.
*/
esp_err_t spi_nand_flash_read_sector(spi_nand_flash_device_t *handle, uint8_t *buffer, dhara_sector_t sector_id);
esp_err_t spi_nand_flash_read_sector(spi_nand_flash_device_t *handle, uint8_t *buffer, uint32_t sector_id);

/** @brief Copy a sector to another sector from the nand flash.
*
Expand All @@ -56,7 +55,7 @@ esp_err_t spi_nand_flash_read_sector(spi_nand_flash_device_t *handle, uint8_t *b
* @param dst_sec The destination sector id to which data should be copied.
* @return ESP_OK on success, or a flash error code if the copy failed.
*/
esp_err_t spi_nand_flash_copy_sector(spi_nand_flash_device_t *handle, dhara_sector_t src_sec, dhara_sector_t dst_sec);
esp_err_t spi_nand_flash_copy_sector(spi_nand_flash_device_t *handle, uint32_t src_sec, uint32_t dst_sec);

/** @brief Write a sector to the nand flash.
*
Expand All @@ -65,7 +64,7 @@ esp_err_t spi_nand_flash_copy_sector(spi_nand_flash_device_t *handle, dhara_sect
* @param sector_id The id of the sector to write.
* @return ESP_OK on success, or a flash error code if the write failed.
*/
esp_err_t spi_nand_flash_write_sector(spi_nand_flash_device_t *handle, const uint8_t *buffer, dhara_sector_t sector_id);
esp_err_t spi_nand_flash_write_sector(spi_nand_flash_device_t *handle, const uint8_t *buffer, uint32_t sector_id);

/** @brief Trim sector from the nand flash.
*
Expand All @@ -77,7 +76,7 @@ esp_err_t spi_nand_flash_write_sector(spi_nand_flash_device_t *handle, const uin
* @param sector_id The id of the sector to be trimmed.
* @return ESP_OK on success, or a flash error code if the trim failed.
*/
esp_err_t spi_nand_flash_trim(spi_nand_flash_device_t *handle, dhara_sector_t sector_id);
esp_err_t spi_nand_flash_trim(spi_nand_flash_device_t *handle, uint32_t sector_id);

/** @brief Synchronizes any cache to the device.
*
Expand All @@ -94,23 +93,39 @@ esp_err_t spi_nand_flash_sync(spi_nand_flash_device_t *handle);
* @param[out] number_of_sectors A pointer of where to put the return value
* @return ESP_OK on success, or a flash error code if the operation failed.
*/
esp_err_t spi_nand_flash_get_capacity(spi_nand_flash_device_t *handle, dhara_sector_t *number_of_sectors);
esp_err_t spi_nand_flash_get_capacity(spi_nand_flash_device_t *handle, uint32_t *number_of_sectors);

/** @brief Retrieve the size of each sector.
*
* @param handle The handle to the SPI nand flash chip.
* @param[out] number_of_sectors A pointer of where to put the return value
* @param[out] sectors_size A pointer of where to put the return value
* @return ESP_OK on success, or a flash error code if the operation failed.
*/
esp_err_t spi_nand_flash_get_sector_size(spi_nand_flash_device_t *handle, uint32_t *sector_size);

/** @brief Retrieve the size of each block.
*
* @param handle The handle to the SPI nand flash chip.
* @param[out] block_size A pointer of where to put the return value
* @return ESP_OK on success, or a flash error code if the operation failed.
*/
esp_err_t spi_nand_flash_get_block_size(spi_nand_flash_device_t *handle, uint32_t *block_size);

/** @brief Erases the entire chip, invalidating any data on the chip.
*
* @param handle The handle to the SPI nand flash chip.
* @return ESP_OK on success, or a flash error code if the erase failed.
*/
esp_err_t spi_nand_erase_chip(spi_nand_flash_device_t *handle);

/** @brief Retrieve the number of blocks available.
*
* @param handle The handle to the SPI nand flash chip.
* @param[out] number_of_blocks A pointer of where to put the return value
* @return ESP_OK on success, or a flash error code if the operation failed.
*/
esp_err_t spi_nand_flash_get_block_num(spi_nand_flash_device_t *handle, uint32_t *number_of_blocks);

/** @brief De-initialize the handle, releasing any resources reserved.
*
* @param handle The handle to the SPI nand flash chip.
Expand Down
78 changes: 78 additions & 0 deletions spi_nand_flash/priv_include/nand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2022 mikkeldamsgaard project
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2015-2024 Espressif Systems (Shanghai) CO LTD
*/

#pragma once

#include <stdint.h>
#include "spi_nand_flash.h"
#include "freertos/semphr.h"

#ifdef __cplusplus
extern "C" {
#endif

#define INVALID_PAGE 0xFFFF

typedef enum {
STAT_ECC_OK = 0,
STAT_ECC_1_TO_3_BITS_CORRECTED = 1,
STAT_ECC_BITS_CORRECTED = STAT_ECC_1_TO_3_BITS_CORRECTED,
STAT_ECC_NOT_CORRECTED = 2,
STAT_ECC_4_TO_6_BITS_CORRECTED = 3,
STAT_ECC_MAX_BITS_CORRECTED = STAT_ECC_4_TO_6_BITS_CORRECTED,
STAT_ECC_7_8_BITS_CORRECTED = 5,
STAT_ECC_MAX
} ecc_status_t;

typedef struct {
uint8_t ecc_status_reg_len_in_bits;
uint8_t ecc_data_refresh_threshold;
ecc_status_t ecc_corrected_bits_status;
} ecc_data_t;

typedef struct {
uint8_t log2_page_size; //is power of 2, log2_page_size shift (1<<log2_page_size) is stored to page_size
uint8_t log2_ppb; //is power of 2, log2_ppb shift ((1<<log2_ppb) * page_size) will be stored in block size
uint32_t block_size;
uint32_t page_size;
uint32_t num_blocks;
uint32_t read_page_delay_us;
uint32_t erase_block_delay_us;
uint32_t program_page_delay_us;
ecc_data_t ecc_data;
} spi_nand_chip_t;

typedef struct {
esp_err_t (*init)(spi_nand_flash_device_t *handle);
esp_err_t (*deinit)(spi_nand_flash_device_t *handle);
esp_err_t (*read)(spi_nand_flash_device_t *handle, uint8_t *buffer, uint32_t sector_id);
esp_err_t (*write)(spi_nand_flash_device_t *handle, const uint8_t *buffer, uint32_t sector_id);
esp_err_t (*erase_chip)(spi_nand_flash_device_t *handle);
esp_err_t (*erase_block)(spi_nand_flash_device_t *handle, uint32_t block);
esp_err_t (*trim)(spi_nand_flash_device_t *handle, uint32_t sector_id);
esp_err_t (*sync)(spi_nand_flash_device_t *handle);
esp_err_t (*copy_sector)(spi_nand_flash_device_t *handle, uint32_t src_sec, uint32_t dst_sec);
esp_err_t (*get_capacity)(spi_nand_flash_device_t *handle, uint32_t *number_of_sectors);
} spi_nand_ops;

struct spi_nand_flash_device_t {
spi_nand_flash_config_t config;
spi_nand_chip_t chip;
const spi_nand_ops *ops;
void *ops_priv_data;
uint8_t *work_buffer;
uint8_t *read_buffer;
SemaphoreHandle_t mutex;
};

esp_err_t nand_register_dev(spi_nand_flash_device_t *handle);
esp_err_t nand_unregister_dev(spi_nand_flash_device_t *handle);

#ifdef __cplusplus
}
#endif
24 changes: 24 additions & 0 deletions spi_nand_flash/priv_include/nand_flash_chip.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <stdint.h>
#include "esp_err.h"
#include "spi_nand_flash.h"

#ifdef __cplusplus
extern "C" {
#endif

esp_err_t spi_nand_winbond_init(spi_nand_flash_device_t *dev);
esp_err_t spi_nand_alliance_init(spi_nand_flash_device_t *dev);
esp_err_t spi_nand_gigadevice_init(spi_nand_flash_device_t *dev);
esp_err_t spi_nand_micron_init(spi_nand_flash_device_t *dev);

#ifdef __cplusplus
}
#endif
30 changes: 30 additions & 0 deletions spi_nand_flash/priv_include/nand_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2022 mikkeldamsgaard project
*
* SPDX-License-Identifier: Apache-2.0
*
* SPDX-FileContributor: 2015-2023 Espressif Systems (Shanghai) CO LTD
*/

#pragma once

#include <stdint.h>
#include "esp_err.h"
#include "nand.h"

#ifdef __cplusplus
extern "C" {
#endif

esp_err_t nand_is_bad(spi_nand_flash_device_t *handle, uint32_t b, bool *is_bad_status);
esp_err_t nand_mark_bad(spi_nand_flash_device_t *handle, uint32_t b);
esp_err_t nand_erase_chip(spi_nand_flash_device_t *handle);
esp_err_t nand_erase_block(spi_nand_flash_device_t *handle, uint32_t b);
esp_err_t nand_prog(spi_nand_flash_device_t *handle, uint32_t p, const uint8_t *data);
esp_err_t nand_is_free(spi_nand_flash_device_t *handle, uint32_t p, bool *is_free_status);
esp_err_t nand_read(spi_nand_flash_device_t *handle, uint32_t p, size_t offset, size_t length, uint8_t *data);
esp_err_t nand_copy(spi_nand_flash_device_t *handle, uint32_t src, uint32_t dst);

#ifdef __cplusplus
}
#endif
Loading