-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spi_nand_flash): Add linux target support
- Loading branch information
1 parent
52be198
commit 05e804f
Showing
17 changed files
with
508 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,44 @@ | ||
idf_build_get_property(target IDF_TARGET) | ||
|
||
set(reqs fatfs) | ||
set(inc diskio include) | ||
set(priv_inc priv_include) | ||
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/nand_diag_api.c" | ||
"src/spi_nand_oper.c" | ||
"src/dhara_glue.c" | ||
"vfs/vfs_fat_spinandflash.c" | ||
"src/nand_impl_wrap.c" | ||
"diskio/diskio_nand.c") | ||
|
||
set(reqs fatfs) | ||
if(${target} STREQUAL "linux") | ||
|
||
list(APPEND reqs esp_partition) | ||
list(APPEND srcs "src/nand_impl_linux.c") | ||
|
||
else() | ||
|
||
list(APPEND srcs "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/nand_diag_api.c" | ||
"src/spi_nand_oper.c" | ||
"vfs/vfs_fat_spinandflash.c") | ||
|
||
set(priv_reqs vfs) | ||
list(APPEND inc vfs) | ||
|
||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "5.3") | ||
list(APPEND reqs esp_driver_spi) | ||
else() | ||
list(APPEND reqs driver) | ||
endif() | ||
|
||
set(priv_reqs vfs) | ||
endif() | ||
|
||
|
||
idf_component_register(SRCS ${srcs} | ||
INCLUDE_DIRS include vfs diskio | ||
PRIV_INCLUDE_DIRS "priv_include" | ||
INCLUDE_DIRS ${inc} | ||
PRIV_INCLUDE_DIRS ${priv_inc} | ||
REQUIRES ${reqs} | ||
PRIV_REQUIRES ${priv_reqs}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
set(COMPONENTS main) | ||
|
||
project(nand_flash_host_test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
| Supported Targets | Linux | | ||
| ----------------- | ----- | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
idf_component_register(SRCS "test_nand_flash.cpp" "test_app_main.cpp" | ||
REQUIRES fatfs | ||
WHOLE_ARCHIVE | ||
) | ||
|
||
# Currently 'main' for IDF_TARGET=linux is defined in freertos component. | ||
# Since we are using a freertos mock here, need to let Catch2 provide 'main'. | ||
target_link_libraries(${COMPONENT_LIB} PRIVATE Catch2WithMain) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dependencies: | ||
espressif/catch2: "^3.4.0" | ||
espressif/spi_nand_flash: | ||
version: '*' | ||
override_path: '../../' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_session.hpp> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
|
||
extern "C" void app_main(void) | ||
{ | ||
int argc = 1; | ||
const char *argv[2] = { | ||
"target_test_main", | ||
NULL | ||
}; | ||
|
||
auto result = Catch::Session().run(argc, argv); | ||
if (result != 0) { | ||
printf("Test failed with result %d\n", result); | ||
} else { | ||
printf("Test passed.\n"); | ||
} | ||
fflush(stdout); | ||
exit(result); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "ff.h" | ||
#include "esp_partition.h" | ||
#include "diskio_impl.h" | ||
#include "diskio_nand.h" | ||
#include "spi_nand_flash.h" | ||
#include "nand_private/nand_impl_wrap.h" | ||
|
||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#define PATTERN_SEED 0x12345678 | ||
|
||
TEST_CASE("Create volume, open file, write and read back data", "[fatfs, spi_nand_flash]") | ||
{ | ||
FRESULT fr_result; | ||
BYTE pdrv; | ||
FATFS fs; | ||
FIL file; | ||
UINT bw; | ||
|
||
esp_err_t esp_result; | ||
spi_nand_flash_config_t nand_flash_config; | ||
spi_nand_flash_device_t *device_handle; | ||
REQUIRE(spi_nand_flash_init_device(&nand_flash_config, &device_handle) == ESP_OK); | ||
|
||
// Get a physical drive | ||
esp_result = ff_diskio_get_drive(&pdrv); | ||
REQUIRE(esp_result == ESP_OK); | ||
|
||
// Register physical drive as wear-levelled partition | ||
esp_result = ff_diskio_register_nand(pdrv, device_handle); | ||
|
||
// Create FAT volume on the entire disk | ||
LBA_t part_list[] = {100, 0, 0, 0}; | ||
BYTE work_area[FF_MAX_SS]; | ||
|
||
fr_result = f_fdisk(pdrv, part_list, work_area); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
char drv[3] = {(char)('0' + pdrv), ':', 0}; | ||
const MKFS_PARM opt = {(BYTE)(FM_ANY), 0, 0, 0, 0}; | ||
fr_result = f_mkfs(drv, &opt, work_area, sizeof(work_area)); // Use default volume | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Mount the volume | ||
fr_result = f_mount(&fs, drv, 0); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Open, write and read data | ||
fr_result = f_open(&file, "0:/test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Generate data | ||
uint32_t data_size = 1000; | ||
|
||
char *data = (char *) malloc(data_size); | ||
char *read = (char *) malloc(data_size); | ||
|
||
for (uint32_t i = 0; i < data_size; i += sizeof(i)) { | ||
*((uint32_t *)(data + i)) = i; | ||
} | ||
|
||
// Write generated data | ||
fr_result = f_write(&file, data, data_size, &bw); | ||
REQUIRE(fr_result == FR_OK); | ||
REQUIRE(bw == data_size); | ||
|
||
// Move to beginning of file | ||
fr_result = f_lseek(&file, 0); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Read written data | ||
fr_result = f_read(&file, read, data_size, &bw); | ||
REQUIRE(fr_result == FR_OK); | ||
REQUIRE(bw == data_size); | ||
|
||
REQUIRE(memcmp(data, read, data_size) == 0); | ||
|
||
// Close file | ||
fr_result = f_close(&file); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Unmount default volume | ||
fr_result = f_mount(0, drv, 0); | ||
REQUIRE(fr_result == FR_OK); | ||
|
||
// Clear | ||
free(read); | ||
free(data); | ||
ff_diskio_unregister(pdrv); | ||
ff_diskio_clear_pdrv_nand(device_handle); | ||
spi_nand_flash_deinit_device(device_handle); | ||
esp_partition_unload_all(); | ||
} | ||
|
||
TEST_CASE("verify mark_bad_block works", "[spi_nand_flash]") | ||
{ | ||
spi_nand_flash_config_t nand_flash_config; | ||
spi_nand_flash_device_t *device_handle; | ||
REQUIRE(spi_nand_flash_init_device(&nand_flash_config, &device_handle) == ESP_OK); | ||
|
||
uint32_t sector_num, sector_size; | ||
REQUIRE(spi_nand_flash_get_capacity(device_handle, §or_num) == 0); | ||
REQUIRE(spi_nand_flash_get_sector_size(device_handle, §or_size) == 0); | ||
|
||
uint32_t test_block = 15; | ||
if (test_block < sector_num) { | ||
bool is_bad_status = false; | ||
// Verify if test_block is not bad block | ||
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0); | ||
REQUIRE(is_bad_status == false); | ||
// mark test_block as a bad block | ||
REQUIRE(nand_wrap_mark_bad(device_handle, test_block) == 0); | ||
// Verify if test_block is marked as bad block | ||
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0); | ||
REQUIRE(is_bad_status == true); | ||
} | ||
|
||
spi_nand_flash_deinit_device(device_handle); | ||
esp_partition_unload_all(); | ||
} | ||
|
||
static void fill_buffer(uint32_t seed, uint8_t *dst, size_t count) | ||
{ | ||
srand(seed); | ||
for (size_t i = 0; i < count; ++i) { | ||
uint32_t val = rand(); | ||
memcpy(dst + i * sizeof(uint32_t), &val, sizeof(val)); | ||
} | ||
} | ||
|
||
TEST_CASE("verify nand_prog, nand_read, nand_copy, nand_is_free works", "[spi_nand_flash]") | ||
{ | ||
spi_nand_flash_config_t nand_flash_config; | ||
spi_nand_flash_device_t *device_handle; | ||
REQUIRE(spi_nand_flash_init_device(&nand_flash_config, &device_handle) == ESP_OK); | ||
|
||
uint32_t sector_num, sector_size, block_size; | ||
REQUIRE(spi_nand_flash_get_capacity(device_handle, §or_num) == 0); | ||
REQUIRE(spi_nand_flash_get_sector_size(device_handle, §or_size) == 0); | ||
REQUIRE(spi_nand_flash_get_block_size(device_handle, &block_size) == 0); | ||
|
||
uint8_t *pattern_buf = (uint8_t *)heap_caps_malloc(sector_size, MALLOC_CAP_DEFAULT); | ||
REQUIRE(pattern_buf != NULL); | ||
uint8_t *temp_buf = (uint8_t *)heap_caps_malloc(sector_size, MALLOC_CAP_DEFAULT); | ||
REQUIRE(temp_buf != NULL); | ||
|
||
fill_buffer(PATTERN_SEED, pattern_buf, sector_size / sizeof(uint32_t)); | ||
|
||
bool is_page_free = true; | ||
uint32_t test_block = 20; | ||
uint32_t test_page = test_block * (block_size / sector_size); //(block_num * pages_per_block) | ||
uint32_t dst_page = test_page + 1; | ||
if (test_page < sector_num) { | ||
// Verify if test_page is free | ||
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0); | ||
REQUIRE(is_page_free == true); | ||
// Write/program test_page | ||
REQUIRE(nand_wrap_prog(device_handle, test_page, pattern_buf) == 0); | ||
// Verify if test_page is used/programmed | ||
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0); | ||
REQUIRE(is_page_free == false); | ||
|
||
REQUIRE(nand_wrap_read(device_handle, test_page, 0, sector_size, temp_buf) == 0); | ||
REQUIRE(nand_wrap_copy(device_handle, test_page, dst_page) == 0); | ||
REQUIRE(nand_wrap_read(device_handle, dst_page, 0, sector_size, temp_buf) == 0); | ||
} | ||
free(pattern_buf); | ||
free(temp_buf); | ||
spi_nand_flash_deinit_device(device_handle); | ||
esp_partition_unload_all(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Name, Type, SubType, Offset, Size, Flags | ||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap | ||
nvs, data, nvs, 0x9000, 0x6000, | ||
phy_init, data, phy, 0xf000, 0x1000, | ||
factory, app, factory, 0x10000, 1M, | ||
storage, data, fat, , 8M, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||
# SPDX-License-Identifier: Unlicense OR CC0-1.0 | ||
import pytest | ||
from pytest_embedded import Dut | ||
|
||
|
||
@pytest.mark.linux | ||
@pytest.mark.host_test | ||
def test_nand_flash_linux(dut: Dut) -> None: | ||
dut.expect_exact('All tests passed', timeout=120) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CONFIG_IDF_TARGET="linux" | ||
CONFIG_COMPILER_CXX_EXCEPTIONS=y | ||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n | ||
CONFIG_PARTITION_TABLE_OFFSET=0x8000 | ||
CONFIG_PARTITION_TABLE_CUSTOM=y | ||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partition_table.csv" | ||
CONFIG_MMU_PAGE_SIZE=0X10000 | ||
CONFIG_ESP_PARTITION_ENABLE_STATS=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.