diff --git a/CMakeLists.txt b/CMakeLists.txt index 584ed379..0237e76d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright (c) 2023 Space Cubics, LLC. # SPDX-License-Identifier: Apache-2.0 +add_subdirectory(lib) add_subdirectory(drivers/can) add_subdirectory(drivers/i2c) add_subdirectory(drivers/spi) diff --git a/Kconfig b/Kconfig index 39c3088f..523ef250 100644 --- a/Kconfig +++ b/Kconfig @@ -1,6 +1,7 @@ # Copyright (c) 2023 Space Cubics, LLC. # SPDX-License-Identifier: Apache-2.0 +rsource "lib/Kconfig" rsource "drivers/can/Kconfig" rsource "drivers/i2c/Kconfig" rsource "drivers/spi/Kconfig" diff --git a/boards/sc/scsat1_adcs/scsat1_adcs.dts b/boards/sc/scsat1_adcs/scsat1_adcs.dts index 67b49605..8b86b2fc 100644 --- a/boards/sc/scsat1_adcs/scsat1_adcs.dts +++ b/boards/sc/scsat1_adcs/scsat1_adcs.dts @@ -118,7 +118,7 @@ spiclk_div = <0>; data-capture-mode; - s25fl256l: s25fl256l@0 { + s25fl256l0: s25fl256l0@0 { compatible = "jedec,spi-nor"; reg = <0>; size = ; @@ -157,6 +157,28 @@ cpol = <0>; cpha = <0>; spiclk_div = <0>; + data-capture-mode; + + s25fl256l1: s25fl256l1@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + size = ; + spi-max-frequency = <12000000>; + status = "okay"; + enter-4byte-addr = <1>; + jedec-id = [01 60 19]; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage_partition"; + reg = <0x00000000 DT_SIZE_M(32)>; + }; + }; + }; }; spi2: spi@40200000 { diff --git a/boards/sc/scsat1_main/scsat1_main.dts b/boards/sc/scsat1_main/scsat1_main.dts index 37e1bc12..bde153fb 100644 --- a/boards/sc/scsat1_main/scsat1_main.dts +++ b/boards/sc/scsat1_main/scsat1_main.dts @@ -124,7 +124,7 @@ spiclk_div = <0>; data-capture-mode; - s25fl256l: s25fl256l@0 { + s25fl256l0: s25fl256l0@0 { compatible = "jedec,spi-nor"; reg = <0>; size = ; @@ -163,6 +163,28 @@ cpol = <0>; cpha = <0>; spiclk_div = <0>; + data-capture-mode; + + s25fl256l1: s25fl256l1@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + size = ; + spi-max-frequency = <12000000>; + status = "okay"; + enter-4byte-addr = <1>; + jedec-id = [01 60 19]; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage_partition"; + reg = <0x00000000 DT_SIZE_M(32)>; + }; + }; + }; }; spi2: spi@40200000 { diff --git a/drivers/spi/spi_sc.c b/drivers/spi/spi_sc.c index df0bd0fe..425c4c86 100644 --- a/drivers/spi/spi_sc.c +++ b/drivers/spi/spi_sc.c @@ -65,6 +65,10 @@ LOG_MODULE_REGISTER(spi_sc, CONFIG_SPI_LOG_LEVEL); /* QSPI Data Capture Mode Setting Register */ #define SC_QSPI_DCMSR_DTCAPT BIT(0) +/* TX/RX Buffer size */ +#define SC_QSPI_TX_BUFFER_SIZE (16U) +#define SC_QSPI_RX_BUFFER_SIZE (16U) + typedef void (*irq_init_func_t)(const struct device *dev); struct spi_sc_data { @@ -93,7 +97,7 @@ static int spi_sc_wait_for_idle(const struct device *dev) LOG_ERR("Waiting for the 'SPICTRLDN' interrupt, but it timed out. (%d)", ret); } - return 0; + return ret; } static void spi_sc_isr(const struct device *dev) @@ -112,12 +116,19 @@ static void spi_sc_isr(const struct device *dev) } } -static int spi_sc_send_tx_data(struct spi_context *ctx, const struct device *dev, uint8_t dfs) +static int spi_sc_send_tx_data(struct spi_context *ctx, const struct device *dev, uint8_t dfs, + uint32_t *tx_size) { const struct spi_sc_cfg *cfg = dev->config; int ret; - for (int i = 0; i < ctx->current_tx->len; i++) { + *tx_size = ctx->current_tx->len; + + if (ctx->current_tx->len > SC_QSPI_TX_BUFFER_SIZE) { + *tx_size = SC_QSPI_TX_BUFFER_SIZE; + } + + for (int i = 0; i < *tx_size; i++) { sys_write32(ctx->tx_buf[i], cfg->base + SC_QSPI_TDR_OFFSET); LOG_DBG("0x%02x sent", ctx->tx_buf[i]); @@ -127,7 +138,7 @@ static int spi_sc_send_tx_data(struct spi_context *ctx, const struct device *dev } } - spi_context_update_tx(ctx, dfs, ctx->current_tx->len); + spi_context_update_tx(ctx, dfs, *tx_size); end: return ret; } @@ -150,8 +161,12 @@ static int spi_sc_read_rx_data(struct spi_context *ctx, const struct device *dev int ret = 0; uint8_t byte; + if (size > SC_QSPI_RX_BUFFER_SIZE) { + size = SC_QSPI_RX_BUFFER_SIZE; + } + if (!cfg->data_capture_mode) { - ret = spi_sc_request_rx_data(dev, ctx->current_rx->len); + ret = spi_sc_request_rx_data(dev, size); if (ret < 0) { LOG_ERR("Failed to request the RX data. (%d)", ret); goto end; @@ -220,8 +235,7 @@ static int spi_sc_xfer(struct spi_context *ctx, const struct device *dev, uint8_ LOG_DBG("rx buf count %d len %d", ctx->rx_count, ctx->rx_len); if (spi_context_tx_buf_on(ctx)) { - last_tx_size = ctx->current_tx->len; - ret = spi_sc_send_tx_data(ctx, dev, dfs); + ret = spi_sc_send_tx_data(ctx, dev, dfs, &last_tx_size); if (ret < 0) { LOG_ERR("Failed to send the TX data. (%d)", ret); goto end; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 00000000..fc0eb344 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Space Cubics, LLC. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_SC_LIB_FLASH flash) diff --git a/lib/Kconfig b/lib/Kconfig new file mode 100644 index 00000000..a3bfd57c --- /dev/null +++ b/lib/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Space Cubics, LLC. +# SPDX-License-Identifier: Apache-2.0 + +menu "Space Cubics Libraries" + +rsource "flash/Kconfig" + +endmenu diff --git a/lib/flash/CMakeLists.txt b/lib/flash/CMakeLists.txt new file mode 100644 index 00000000..0e28ed9c --- /dev/null +++ b/lib/flash/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Space Cubics, LLC. +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SC_LIB_FLASH_DATA) + zephyr_library() + zephyr_library_sources_ifdef(CONFIG_SC_LIB_FLASH_DATA data_nor.c) + zephyr_include_directories(.) + zephyr_link_libraries(FS) +endif() diff --git a/lib/flash/Kconfig b/lib/flash/Kconfig new file mode 100644 index 00000000..9941e407 --- /dev/null +++ b/lib/flash/Kconfig @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Space Cubics, LLC. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig SC_LIB_FLASH + bool "Space Cubics Flash Memory libraries" + default y + help + Enable Space Cubics Flash Memory libraries. + +if SC_LIB_FLASH + +config SC_LIB_FLASH_DATA + bool "Enable Data Store Flash Memory" + default y + depends on FILE_SYSTEM_LITTLEFS + help + Enable Data Store Flash Memory + +if SC_LIB_FLASH_DATA + +config SC_LIB_FLASH_DATA_STORE_MNT_POINT + string "Mount point name for Data Store Flash memory" + default "/storage" + help + Mount point name for Data Store Flash memory + +endif #SC_LIB_FLASH_DATA + +module = SC_LIB_FLASH +module-str = Space Cubics Flash Memory libraries +source "subsys/logging/Kconfig.template.log_config" + +endif #SC_LIB_FLASH diff --git a/lib/flash/data_nor.c b/lib/flash/data_nor.c new file mode 100644 index 00000000..47710a1e --- /dev/null +++ b/lib/flash/data_nor.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024 Space Cubics, LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(lfs); + +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage); +static struct fs_mount_t lfs_storage_mnt = { + .type = FS_LITTLEFS, + .fs_data = &storage, + .storage_dev = (void *)FIXED_PARTITION_ID(storage_partition), + .mnt_point = CONFIG_SC_LIB_FLASH_DATA_STORE_MNT_POINT, +}; + +struct fs_mount_t *mountpoint = &lfs_storage_mnt; + +int datafs_init(void) +{ + struct fs_statvfs sbuf; + int ret; + + ret = fs_mount(mountpoint); + if (ret < 0) { + LOG_ERR("Faild to mount %s (%d)", mountpoint->mnt_point, ret); + goto end; + } + + ret = fs_statvfs(mountpoint->mnt_point, &sbuf); + if (ret < 0) { + LOG_ERR("Faild to get the fs status %s (%d)", mountpoint->mnt_point, ret); + goto end; + } + + LOG_INF("%s: bsize = %lu ; frsize = %lu ;" + " blocks = %lu ; bfree = %lu", + mountpoint->mnt_point, sbuf.f_bsize, sbuf.f_frsize, sbuf.f_blocks, sbuf.f_bfree); + +end: + return ret; +} + +int update_boot_count(const char *fname) +{ + uint32_t boot_count = 0; + struct fs_file_t file; + int ret; + + fs_file_t_init(&file); + + ret = fs_open(&file, fname, FS_O_CREATE | FS_O_RDWR); + if (ret < 0) { + LOG_ERR("Faild to open the boot count file %s (%d)", fname, ret); + goto end; + } + + ret = fs_read(&file, &boot_count, sizeof(boot_count)); + if (ret < 0) { + LOG_ERR("Faild to read the boot count file %s (%d)", fname, ret); + goto close; + } + LOG_INF("%s read count:%u (bytes: %d)", fname, boot_count, ret); + + ret = fs_seek(&file, 0, FS_SEEK_SET); + if (ret < 0) { + LOG_ERR("Faild to seek the boot count file %s (%d)", fname, ret); + goto close; + } + + boot_count++; + ret = fs_write(&file, &boot_count, sizeof(boot_count)); + if (ret < 0) { + LOG_ERR("Faild to write the boot count file %s (%d)", fname, ret); + goto close; + } + + LOG_INF("%s write new boot count %u: (bytes: %d]", fname, boot_count, ret); + +close: + ret = fs_close(&file); + if (ret < 0) { + LOG_ERR("Faild to close the boot count file %s (%d)", fname, ret); + goto close; + } + +end: + return ret; +} diff --git a/lib/flash/data_nor.h b/lib/flash/data_nor.h new file mode 100644 index 00000000..13dcd1f5 --- /dev/null +++ b/lib/flash/data_nor.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Space Cubics, LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +int datafs_init(void); +int update_boot_count(const char *fname); diff --git a/tests/hwtest/adcs/prj.conf b/tests/hwtest/adcs/prj.conf index 6f1463c5..f6edefb9 100644 --- a/tests/hwtest/adcs/prj.conf +++ b/tests/hwtest/adcs/prj.conf @@ -10,7 +10,7 @@ CONFIG_EVENTS=y CONFIG_SHELL=y CONFIG_SHELL_PROMPT_UART="adcs:~$ " CONFIG_LOG_BUFFER_SIZE=5120 -CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=4096 CONFIG_PICOLIBC_IO_FLOAT=y # For CSP CONFIG_LIBCSP=y @@ -22,3 +22,6 @@ CONFIG_FLASH=y CONFIG_SPI_NOR=y CONFIG_FLASH_MAP=y CONFIG_FLASH_MAP_LABELS=y +# For LittleFS +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y diff --git a/tests/hwtest/adcs/src/main.c b/tests/hwtest/adcs/src/main.c index 5fc457f6..96323738 100644 --- a/tests/hwtest/adcs/src/main.c +++ b/tests/hwtest/adcs/src/main.c @@ -19,12 +19,14 @@ #include "adcs_init.h" #include "loop_test.h" #include "syshk_test.h" +#include "data_nor.h" #include LOG_MODULE_REGISTER(adcs_main, CONFIG_SCSAT1_ADCS_LOG_LEVEL); #define CMD_HANDLER_PRIO (0U) #define CMD_EXEC_EVENT (1U) +#define BOOT_COUNT_FILE CONFIG_SC_LIB_FLASH_DATA_STORE_MNT_POINT "/boot.count" char last_cmd[32]; @@ -133,12 +135,16 @@ int main(void) printk("This is for HW test program for %s\n", CONFIG_BOARD); + datafs_init(); + start_kick_wdt_thread(); sc_adcs_print_fpga_ids(); k_event_init(&exec_event); + update_boot_count(BOOT_COUNT_FILE); + ret = csp_enable(); if (ret < 0) { LOG_ERR("Failed to enable the CSP. (%d)", ret); diff --git a/tests/hwtest/main/prj.conf b/tests/hwtest/main/prj.conf index 38b776e7..cf41daf3 100644 --- a/tests/hwtest/main/prj.conf +++ b/tests/hwtest/main/prj.conf @@ -10,7 +10,7 @@ CONFIG_EVENTS=y CONFIG_SHELL=y CONFIG_SHELL_PROMPT_UART="main:~$ " CONFIG_LOG_BUFFER_SIZE=4096 -CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=4096 CONFIG_PICOLIBC_IO_FLOAT=y # For CSP CONFIG_LIBCSP=y @@ -23,3 +23,6 @@ CONFIG_FLASH=y CONFIG_SPI_NOR=y CONFIG_FLASH_MAP=y CONFIG_FLASH_MAP_LABELS=y +# For LittleFS +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y diff --git a/tests/hwtest/main/src/main.c b/tests/hwtest/main/src/main.c index 5d58ef9d..2b76dc4e 100644 --- a/tests/hwtest/main/src/main.c +++ b/tests/hwtest/main/src/main.c @@ -22,12 +22,14 @@ #include "main_init.h" #include "loop_test.h" #include "syshk_test.h" +#include "data_nor.h" #include LOG_MODULE_REGISTER(main, CONFIG_SCSAT1_MAIN_LOG_LEVEL); #define CMD_HANDLER_PRIO (0U) #define CMD_EXEC_EVENT (1U) +#define BOOT_COUNT_FILE CONFIG_SC_LIB_FLASH_DATA_STORE_MNT_POINT "/boot.count" char last_cmd[32]; @@ -139,12 +141,16 @@ int main(void) printk("This is for HW test program for %s\n", CONFIG_BOARD); + datafs_init(); + start_kick_wdt_thread(); sc_main_print_fpga_ids(); k_event_init(&exec_event); + update_boot_count(BOOT_COUNT_FILE); + ret = csp_enable(); if (ret < 0) { LOG_ERR("Failed to enable the CSP. (%d)", ret); diff --git a/west.yml b/west.yml index 305bb83c..60500333 100644 --- a/west.yml +++ b/west.yml @@ -15,3 +15,10 @@ manifest: url: https://github.com/libcsp/libcsp.git revision: develop path: modules/lib/libcsp + + - name: littlefs + url: https://github.com/zephyrproject-rtos/littlefs.git + revision: zephyr + path: modules/fs/littlefs + groups: + - fs