From 659f84c339d7fbc7bb7bc4d5bf50405a767c507c Mon Sep 17 00:00:00 2001 From: Joaquim Date: Fri, 4 Jun 2021 14:41:06 +0100 Subject: [PATCH 1/7] add submodule littlefs --- .gitmodules | 3 +++ src/libs/littlefs | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/libs/littlefs diff --git a/.gitmodules b/.gitmodules index 6f6d0e10e8..815fc022be 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "src/libs/lvgl"] path = src/libs/lvgl url = https://github.com/joaquimorg/lvgl.git +[submodule "src/libs/littlefs"] + path = src/libs/littlefs + url = https://github.com/littlefs-project/littlefs.git diff --git a/src/libs/littlefs b/src/libs/littlefs new file mode 160000 index 0000000000..1863dc7883 --- /dev/null +++ b/src/libs/littlefs @@ -0,0 +1 @@ +Subproject commit 1863dc7883d82bd6ca79faa164b65341064d1c16 From e7e783f1ee4ab3dfc4d0a7bb9bb3929a207b0a78 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Wed, 16 Jun 2021 21:20:33 +0100 Subject: [PATCH 2/7] base fs --- src/CMakeLists.txt | 24 ++++- src/components/fs/FS.cpp | 194 ++++++++++++++++++++++++++++++++++ src/components/fs/FS.h | 63 +++++++++++ src/libs/lv_conf.h | 4 +- src/systemtask/SystemTask.cpp | 9 +- src/systemtask/SystemTask.h | 6 +- 6 files changed, 294 insertions(+), 6 deletions(-) create mode 100644 src/components/fs/FS.cpp create mode 100644 src/components/fs/FS.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd72992168..38ceefc801 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -166,6 +166,13 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/util/src/addr.c ) +set(LITTLEFS_SRC + libs/littlefs/lfs_util.h + libs/littlefs/lfs.h + libs/littlefs/lfs_util.c + libs/littlefs/lfs.c + ) + set(LVGL_SRC libs/lv_conf.h libs/lvgl/lvgl.h @@ -461,6 +468,7 @@ list(APPEND SOURCE_FILES components/motor/MotorController.cpp components/settings/Settings.cpp components/timer/TimerController.cpp + components/fs/FS.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -797,13 +805,25 @@ target_compile_options(lvgl PRIVATE $<$: -MP -MD -x assembler-with-cpp> ) +# LITTLEFS_SRC +add_library(littlefs STATIC ${LITTLEFS_SRC}) +target_include_directories(littlefs SYSTEM PUBLIC . ../) +target_include_directories(littlefs SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) +target_compile_options(littlefs PRIVATE + $<$,$>: ${COMMON_FLAGS} -Og -g3> + $<$,$>: ${COMMON_FLAGS} -Os> + $<$,$>: ${COMMON_FLAGS} -Og -g3 -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Os -fno-rtti> + $<$: -MP -MD -x assembler-with-cpp> + ) + # Build autonomous binary (without support for bootloader) set(EXECUTABLE_NAME "pinetime-app") set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}) set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld") add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES}) set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME}) -target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl) +target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs) target_compile_options(${EXECUTABLE_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -Og -g3> $<$,$>: ${COMMON_FLAGS} -Os> @@ -832,7 +852,7 @@ set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_ set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip) set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld") add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl) +target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs) set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME}) target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -Og -g3> diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp new file mode 100644 index 0000000000..80b292b3ae --- /dev/null +++ b/src/components/fs/FS.cpp @@ -0,0 +1,194 @@ +#include "FS.h" +#include +#include +#include "drivers/SpiNorFlash.h" +#include +#include + +using namespace Pinetime::Controllers; + + +static constexpr size_t BLOCK_SIZE_BYTES = 4096; + +/* +* Interface between littlefs and SpiNorFlash +*/ + +namespace { + static int read(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Read(address, (uint8_t*)buffer, size); + + return 0u; + } + + static int prog(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Write(address, (uint8_t*)buffer, size); + return lfs.mDriver.ProgramFailed() ? -1u : 0u; + } + + static int erase(const struct lfs_config *c, lfs_block_t block) { + Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES); + lfs.mDriver.SectorErase(address); + return lfs.mDriver.EraseFailed() ? -1u : 0u; + } + + static int sync(const struct lfs_config *c) { + // no hardware caching used + return 0u; + } +} + +const static struct lfs_config baseLfsConfig = { + .read = read, + .prog = prog, + .erase = erase, + .sync = sync, + + .read_size = 16, + .prog_size = 8, + .block_size = BLOCK_SIZE_BYTES, + .block_cycles = 1000u, + + .cache_size = 16, + .lookahead_size = 16, + + .name_max = 50, + .attr_max = 50 + +}; + +constexpr struct lfs_config createLfsConfig(Pinetime::Controllers::FS& fs, const size_t totalSizeBytes) { + struct lfs_config config = baseLfsConfig; + config.context = &fs; + config.block_count = totalSizeBytes / BLOCK_SIZE_BYTES; + return config; +} + +FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : + mDriver{driver}, + mLfsConfig{createLfsConfig(*this, mSize)} { } + + +void FS::Init() { + + // try mount + int err = lfs_mount(&mLfs, &mLfsConfig); + + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err != 0) { + lfs_format(&mLfs, &mLfsConfig); + err = lfs_mount(&mLfs, &mLfsConfig); + if (err != 0) { + return; + } + } + VerifyResource(); + + LVGLFileSystemInit(); + +} + +void FS::VerifyResource() { + // validate the resource metadata + fsValid = true; +} + +void FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { + lfs_file_open(&mLfs, file_p, fileName, flags); +} + +void FS::FileClose(lfs_file_t* file_p) { + lfs_file_close(&mLfs, file_p); +} + +void FS::Delete(const char* fileName) { + lfs_remove(&mLfs, fileName); +} + +void FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { + lfs_file_read(&mLfs, file_p, buff, size); +} + +void FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { + lfs_file_write(&mLfs, file_p, buff, size); +} + +void FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { + lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); +} + +void FS::MkDir(const char* path) { + lfs_mkdir(&mLfs, path); +} + + +/* + + ----------- LVGL filesystem integration ----------- + +*/ + +lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { + + lfs_file_t* file = static_cast(file_p); + FS* filesys = static_cast(drv->user_data); + filesys->FileOpen(file, path, LFS_O_RDONLY); + + if (file->type == 0) { + return LV_FS_RES_FS_ERR; + } else { + return LV_FS_RES_OK; + } +} + +lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileClose( file ); + + return LV_FS_RES_OK; +} + +lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileRead(file, (uint8_t *)buf, btr); + *br = btr; + return LV_FS_RES_OK; +} + +lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileSeek(file, pos); + return LV_FS_RES_OK; +} + + +void FS::LVGLFileSystemInit() { + + if ( !fsValid ) return; + + lv_fs_drv_t fs_drv; + lv_fs_drv_init(&fs_drv); + + fs_drv.file_size = sizeof(lfs_file_t); + fs_drv.letter = 'F'; + fs_drv.open_cb = lvglOpen; + fs_drv.close_cb = lvglClose; + fs_drv.read_cb = lvglRead; + fs_drv.seek_cb = lvglSeek; + + fs_drv.user_data = this; + + lv_fs_drv_register(&fs_drv); + +} \ No newline at end of file diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h new file mode 100644 index 0000000000..a7ca45cad1 --- /dev/null +++ b/src/components/fs/FS.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include "drivers/SpiNorFlash.h" +#include + + +namespace Pinetime { + namespace Controllers { + class FS { + public: + FS(Pinetime::Drivers::SpiNorFlash&); + + Pinetime::Drivers::SpiNorFlash& mDriver; + + void Init(); + void LVGLFileSystemInit(); + + void FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); + void FileClose(lfs_file_t* file_p); + void Delete(const char* fileName); + void FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); + void FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); + void FileSeek(lfs_file_t* file_p, uint32_t pos); + + void MkDir(const char* path); + + void VerifyResource(); + + /* + * External Flash MAP (4 MBytes) + * + * 0x000000 +---------------------------------------+ + * | Bootloader Assets | + * | 256 KBytes | + * | | + * 0x040000 +---------------------------------------+ + * | OTA | + * | 464 KBytes | + * | | + * | | + * | | + * 0x0B4000 +---------------------------------------+ + * | File System | + * | | + * | | + * | | + * | | + * 0x400000 +---------------------------------------+ + * + */ + static constexpr size_t mStartAddress = 0x0B4000; + static constexpr size_t mSize = 0x3C0000; + + private: + bool fsValid = false; + const struct lfs_config mLfsConfig; + + lfs_t mLfs; + + }; + } +} diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 761baba249..bb1980fcc5 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -204,7 +204,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ /* 1: Enable file system (might be required for images */ // TODO: Enable FS -#define LV_USE_FILESYSTEM 0 +#define LV_USE_FILESYSTEM 1 #if LV_USE_FILESYSTEM /*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ typedef void * lv_fs_drv_user_data_t; @@ -236,7 +236,7 @@ typedef void * lv_fs_drv_user_data_t; * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. * However the opened images might consume additional RAM. * LV_IMG_CACHE_DEF_SIZE must be >= 1 */ -#define LV_IMG_CACHE_DEF_SIZE 1 +#define LV_IMG_CACHE_DEF_SIZE 6 /*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ typedef void* lv_img_decoder_user_data_t; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 5837776403..b8d7a462d9 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -63,7 +63,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, heartRateSensor {heartRateSensor}, motionSensor {motionSensor}, settingsController {settingsController}, - nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { + nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) + #ifndef PINETIME_IS_RECOVERY + ,fs(spiNorFlash) + #endif + { systemTasksMsgQueue = xQueueCreate(10, 1); } @@ -89,6 +93,9 @@ void SystemTask::Work() { spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); + #ifndef PINETIME_IS_RECOVERY + fs.Init(); + #endif nimbleController.Init(); nimbleController.StartAdvertising(); brightnessController.Init(); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ea41a69d67..8ae19d949b 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -17,6 +17,7 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" + #ifdef PINETIME_IS_RECOVERY #include "displayapp/DisplayAppRecovery.h" #include "displayapp/DummyLittleVgl.h" @@ -24,6 +25,7 @@ #include "components/settings/Settings.h" #include "displayapp/DisplayApp.h" #include "displayapp/LittleVgl.h" + #include "components/fs/FS.h" #endif #include "drivers/Watchdog.h" @@ -117,7 +119,9 @@ namespace Pinetime { Pinetime::Controllers::NimbleController nimbleController; Controllers::BrightnessController brightnessController; Pinetime::Controllers::MotionController motionController; - +#ifndef PINETIME_IS_RECOVERY + Pinetime::Controllers::FS fs; +#endif static constexpr uint8_t pinSpiSck = 2; static constexpr uint8_t pinSpiMosi = 3; static constexpr uint8_t pinSpiMiso = 4; From d81fd2cfac37697dd9f9795bd90cb7363623c1e9 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Thu, 17 Jun 2021 10:27:49 +0100 Subject: [PATCH 3/7] Save settings using littlefs --- src/CMakeLists.txt | 5 +- src/components/fs/FS.cpp | 10 +-- src/components/fs/FS.h | 2 +- src/components/settings/Settings.cpp | 99 ++++------------------------ src/components/settings/Settings.h | 26 +++----- src/main.cpp | 13 ++-- src/systemtask/SystemTask.cpp | 15 ++--- src/systemtask/SystemTask.h | 15 ++--- 8 files changed, 55 insertions(+), 130 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98060e8e5f..66e83ae8ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -547,6 +547,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/heartrate/Biquad.cpp components/heartrate/Ptagc.cpp components/motor/MotorController.cpp + components/fs/FS.cpp ) list(APPEND RECOVERYLOADER_SOURCE_FILES @@ -888,7 +889,7 @@ endif() set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery") set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}) add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk) +target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk littlefs) set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME}) target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY") target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC @@ -918,7 +919,7 @@ set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${ set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin) set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip) add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk) +target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk littlefs) set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}) target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY") target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 80b292b3ae..fbfb2df219 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -90,15 +90,17 @@ void FS::Init() { return; } } - VerifyResource(); - + +#ifndef PINETIME_IS_RECOVERY + VerifyResource(); LVGLFileSystemInit(); +#endif } void FS::VerifyResource() { // validate the resource metadata - fsValid = true; + resourcesValid = true; } void FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { @@ -175,8 +177,6 @@ lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { void FS::LVGLFileSystemInit() { - if ( !fsValid ) return; - lv_fs_drv_t fs_drv; lv_fs_drv_init(&fs_drv); diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index a7ca45cad1..bc1349e54d 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -53,7 +53,7 @@ namespace Pinetime { static constexpr size_t mSize = 0x3C0000; private: - bool fsValid = false; + bool resourcesValid = false; const struct lfs_config mLfsConfig; lfs_t mLfs; diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 071940b85a..c3b4b2e0c6 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -4,108 +4,37 @@ using namespace Pinetime::Controllers; -struct SettingsHeader { - uint8_t isActive; // 0xF1 = Block is active, 0xF0 = Block is inactive - uint16_t version; // Current version, to verify if the saved data is for the current Version -}; - -#define HEADER_SIZE sizeof(SettingsHeader) - -Settings::Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} { +Settings::Settings(Pinetime::Controllers::FS& fs) : fs {fs} { } void Settings::Init() { // Load default settings from Flash - LoadSettingsFromFlash(); + LoadSettingsFromFile(); } void Settings::SaveSettings() { // verify if is necessary to save if (settingsChanged) { - SaveSettingsToFlash(); + SaveSettingsToFile(); } settingsChanged = false; } -bool Settings::FindHeader() { - SettingsHeader settingsHeader; - uint8_t bufferHead[sizeof(settingsHeader)]; - - for (uint8_t block = 0; block < 10; block++) { +void Settings::LoadSettingsFromFile() { + SettingsData bufferSettings; - spiNorFlash.Read(settingsBaseAddr + (block * 0x1000), bufferHead, sizeof(settingsHeader)); - std::memcpy(&settingsHeader, bufferHead, sizeof(settingsHeader)); - if (settingsHeader.isActive == 0xF1 && settingsHeader.version == settingsVersion) { - settingsFlashBlock = block; - return true; - } + fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT); + fs.FileRead(&settingsFile, (uint8_t *)&bufferSettings, sizeof(settings)); + fs.FileClose(&settingsFile); + if ( bufferSettings.version == settingsVersion ) { + std::memcpy((void *)&settings, (void *)&bufferSettings, sizeof(settings)); } - return false; -} - -void Settings::ReadSettingsData() { - uint8_t bufferSettings[sizeof(settings)]; - spiNorFlash.Read(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings)); - std::memcpy(&settings, bufferSettings, sizeof(settings)); -} - -void Settings::EraseBlock() { - - spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000)); -} - -void Settings::SetHeader(bool state) { - SettingsHeader settingsHeader; - uint8_t bufferHead[sizeof(settingsHeader)]; - settingsHeader.isActive = state ? 0xF1 : 0xF0; - settingsHeader.version = settingsVersion; - - std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader)); - spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader)); } -void Settings::SaveSettingsData() { - uint8_t bufferSettings[sizeof(settings)]; - std::memcpy(bufferSettings, &settings, sizeof(settings)); - spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings)); -} - -void Settings::LoadSettingsFromFlash() { - - if (settingsFlashBlock == 99) { - // Find current Block, if can't find use default settings and set block to 0 ans save ! - if (FindHeader()) { - ReadSettingsData(); - } else { - SaveSettingsToFlash(); - } - } else { - // Read Settings from flash... - // never used :) - ReadSettingsData(); - } -} - -void Settings::SaveSettingsToFlash() { - - // calculate where to save... - // mark current to inactive - // erase the new location and save - // set settingsFlashBlock - - // if first time hever, only saves to block 0 and set settingsFlashBlock - - if (settingsFlashBlock != 99) { - SetHeader(false); - } - - settingsFlashBlock++; - if (settingsFlashBlock > 9) - settingsFlashBlock = 0; - - EraseBlock(); - SetHeader(true); - SaveSettingsData(); +void Settings::SaveSettingsToFile() { + fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT); + fs.FileWrite(&settingsFile, (uint8_t *)&settings, sizeof(settings)); + fs.FileClose(&settingsFile); } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 4409425be4..58aaeda462 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -2,7 +2,7 @@ #include #include "components/datetime/DateTimeController.h" #include "components/brightness/BrightnessController.h" -#include "drivers/SpiNorFlash.h" +#include "components/fs/FS.h" #include "drivers/Cst816s.h" namespace Pinetime { @@ -13,7 +13,7 @@ namespace Pinetime { enum class Vibration { ON, OFF }; enum class WakeUpMode { None, SingleTap, DoubleTap, RaiseWrist }; - Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash); + Settings(Pinetime::Controllers::FS& fs); void Init(); void SaveSettings(); @@ -95,9 +95,13 @@ namespace Pinetime { uint32_t GetStepsGoal() const { return settings.stepsGoal; }; private: - Pinetime::Drivers::SpiNorFlash& spiNorFlash; + Pinetime::Controllers::FS& fs; + + static constexpr uint32_t settingsVersion = 0x0001; struct SettingsData { + uint32_t version = settingsVersion; + ClockType clockType = ClockType::H24; Vibration vibrationStatus = Vibration::ON; @@ -117,20 +121,10 @@ namespace Pinetime { uint8_t appMenu = 0; uint8_t settingsMenu = 0; - // There are 10 blocks of reserved flash to save settings - // to minimize wear, the recording is done in a rotating way by the 10 blocks - uint8_t settingsFlashBlock = 99; // default to indicate it needs to find the active block - - static constexpr uint32_t settingsBaseAddr = 0x3F6000; // Flash Settings Location - static constexpr uint16_t settingsVersion = 0x0100; // Flash Settings Version + lfs_file_t settingsFile; - bool FindHeader(); - void ReadSettingsData(); - void EraseBlock(); - void SetHeader(bool state); - void SaveSettingsData(); - void LoadSettingsFromFlash(); - void SaveSettingsToFlash(); + void LoadSettingsFromFile(); + void SaveSettingsToFile(); }; } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4c2c5de897..e7aa10f2cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ #include "components/motor/MotorController.h" #include "components/datetime/DateTimeController.h" #include "components/heartrate/HeartRateController.h" +#include "components/fs/FS.h" #include "drivers/Spi.h" #include "drivers/SpiMaster.h" #include "drivers/SpiNorFlash.h" @@ -107,10 +108,6 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; static constexpr uint8_t pinPowerPresentIrq = 19; -Pinetime::Controllers::Settings settingsController {spiNorFlash}; - -Pinetime::Controllers::MotorController motorController {settingsController}; - Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); @@ -121,6 +118,11 @@ Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; +Pinetime::Controllers::FS fs {spiNorFlash}; +Pinetime::Controllers::Settings settingsController {fs}; +Pinetime::Controllers::MotorController motorController {settingsController}; + + Pinetime::Applications::DisplayApp displayApp(lcd, lvgl, touchPanel, @@ -154,7 +156,8 @@ Pinetime::System::SystemTask systemTask(spi, settingsController, heartRateController, displayApp, - heartRateApp); + heartRateApp, + fs); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index f7a2366664..ef6c19afd4 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -59,7 +59,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, - Pinetime::Applications::HeartRateTask& heartRateApp) + Pinetime::Applications::HeartRateTask& heartRateApp, + Pinetime::Controllers::FS& fs) : spi {spi}, lcd {lcd}, spiNorFlash {spiNorFlash}, @@ -77,13 +78,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, motionSensor {motionSensor}, settingsController {settingsController}, heartRateController{heartRateController}, - #ifndef PINETIME_IS_RECOVERY - ,fs(spiNorFlash) - #endif - nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController), motionController{motionController}, displayApp{displayApp}, - heartRateApp(heartRateApp) { + heartRateApp(heartRateApp), + fs{fs}, + nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { } @@ -110,9 +109,9 @@ void SystemTask::Work() { spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); - #ifndef PINETIME_IS_RECOVERY + fs.Init(); - #endif + nimbleController.Init(); nimbleController.StartAdvertising(); brightnessController.Init(); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index d0cf5ea451..855ff0cf19 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -16,6 +16,7 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" +#include "components/fs/FS.h" #ifdef PINETIME_IS_RECOVERY #include "displayapp/DisplayAppRecovery.h" @@ -23,8 +24,7 @@ #else #include "components/settings/Settings.h" #include "displayapp/DisplayApp.h" - #include "displayapp/LittleVgl.h" - #include "components/fs/FS.h" + #include "displayapp/LittleVgl.h" #endif #include "drivers/Watchdog.h" @@ -61,7 +61,8 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, - Pinetime::Applications::HeartRateTask& heartRateApp); + Pinetime::Applications::HeartRateTask& heartRateApp, + Pinetime::Controllers::FS& fs); void Start(); void PushMessage(Messages msg); @@ -101,16 +102,14 @@ namespace Pinetime { Pinetime::Drivers::Bma421& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; - Pinetime::Controllers::NimbleController nimbleController; + Controllers::BrightnessController brightnessController; Pinetime::Controllers::MotionController& motionController; Pinetime::Applications::DisplayApp& displayApp; Pinetime::Applications::HeartRateTask& heartRateApp; - -#ifndef PINETIME_IS_RECOVERY - Pinetime::Controllers::FS fs; -#endif + Pinetime::Controllers::FS& fs; + Pinetime::Controllers::NimbleController nimbleController; static constexpr uint8_t pinSpiSck = 2; static constexpr uint8_t pinSpiMosi = 3; From 982f2b99266029e9293d4160a770da1ff0f5e6c2 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sat, 26 Jun 2021 20:15:27 +0100 Subject: [PATCH 4/7] Small fixes and suggestions from PR --- src/components/fs/FS.cpp | 134 +++++++++++++++------------ src/components/fs/FS.h | 17 ++-- src/components/settings/Settings.cpp | 9 +- 3 files changed, 93 insertions(+), 67 deletions(-) diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index fbfb2df219..a689ec35f5 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -15,33 +15,33 @@ static constexpr size_t BLOCK_SIZE_BYTES = 4096; */ namespace { - static int read(const struct lfs_config *c, lfs_block_t block, + int read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; lfs.mDriver.Read(address, (uint8_t*)buffer, size); - return 0u; + return 0; } - static int prog(const struct lfs_config *c, lfs_block_t block, + int prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; lfs.mDriver.Write(address, (uint8_t*)buffer, size); - return lfs.mDriver.ProgramFailed() ? -1u : 0u; + return lfs.mDriver.ProgramFailed() ? -1 : 0; } - static int erase(const struct lfs_config *c, lfs_block_t block) { - Pinetime::Controllers::FS& lfs = *(reinterpret_cast(c->context)); + int erase(const struct lfs_config *c, lfs_block_t block) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES); lfs.mDriver.SectorErase(address); - return lfs.mDriver.EraseFailed() ? -1u : 0u; + return lfs.mDriver.EraseFailed() ? -1 : 0; } - static int sync(const struct lfs_config *c) { + int sync(const struct lfs_config *c) { // no hardware caching used - return 0u; + return 0; } } @@ -83,16 +83,16 @@ void FS::Init() { // reformat if we can't mount the filesystem // this should only happen on the first boot - if (err != 0) { + if (err != LFS_ERR_OK) { lfs_format(&mLfs, &mLfsConfig); err = lfs_mount(&mLfs, &mLfsConfig); - if (err != 0) { + if (err != LFS_ERR_OK) { return; } } -#ifndef PINETIME_IS_RECOVERY - VerifyResource(); +#ifndef PINETIME_IS_RECOVERY + VerifyResource(); LVGLFileSystemInit(); #endif @@ -103,32 +103,51 @@ void FS::VerifyResource() { resourcesValid = true; } -void FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { - lfs_file_open(&mLfs, file_p, fileName, flags); +int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { + return lfs_file_open(&mLfs, file_p, fileName, flags); } -void FS::FileClose(lfs_file_t* file_p) { - lfs_file_close(&mLfs, file_p); +int FS::FileClose(lfs_file_t* file_p) { + return lfs_file_close(&mLfs, file_p); } -void FS::Delete(const char* fileName) { - lfs_remove(&mLfs, fileName); +int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { + return lfs_file_read(&mLfs, file_p, buff, size); } -void FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { - lfs_file_read(&mLfs, file_p, buff, size); +int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { + return lfs_file_write(&mLfs, file_p, buff, size); } -void FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { - lfs_file_write(&mLfs, file_p, buff, size); +int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { + return lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); } -void FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { - lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); +int FS::FileDelete(const char* fileName) { + return lfs_remove(&mLfs, fileName); } -void FS::MkDir(const char* path) { - lfs_mkdir(&mLfs, path); + +int FS::DirCreate(const char* path) { + return lfs_mkdir(&mLfs, path); +} + +// Delete directory and all files inside +int FS::DirDelete(const char* path) { + + lfs_dir_t mLfs_dir; + lfs_info entryInfo; + + int err; + err = lfs_dir_open(&mLfs, &mLfs_dir, path); + if (err) { + return err; + } + while (lfs_dir_read(&mLfs, &mLfs_dir, &entryInfo)) { + lfs_remove(&mLfs, entryInfo.name); + } + lfs_dir_close(&mLfs, &mLfs_dir); + return LFS_ERR_OK; } @@ -138,43 +157,44 @@ void FS::MkDir(const char* path) { */ -lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { +namespace { + lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { - lfs_file_t* file = static_cast(file_p); - FS* filesys = static_cast(drv->user_data); - filesys->FileOpen(file, path, LFS_O_RDONLY); + lfs_file_t* file = static_cast(file_p); + FS* filesys = static_cast(drv->user_data); + filesys->FileOpen(file, path, LFS_O_RDONLY); - if (file->type == 0) { - return LV_FS_RES_FS_ERR; - } else { - return LV_FS_RES_OK; + if (file->type == 0) { + return LV_FS_RES_FS_ERR; + } else { + return LV_FS_RES_OK; + } } -} -lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileClose( file ); + lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileClose( file ); - return LV_FS_RES_OK; -} + return LV_FS_RES_OK; + } -lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileRead(file, (uint8_t *)buf, btr); - *br = btr; - return LV_FS_RES_OK; -} + lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileRead(file, (uint8_t *)buf, btr); + *br = btr; + return LV_FS_RES_OK; + } -lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileSeek(file, pos); - return LV_FS_RES_OK; + lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileSeek(file, pos); + return LV_FS_RES_OK; + } } - void FS::LVGLFileSystemInit() { lv_fs_drv_t fs_drv; diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index bc1349e54d..d01f8fadf7 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -4,7 +4,6 @@ #include "drivers/SpiNorFlash.h" #include - namespace Pinetime { namespace Controllers { class FS { @@ -16,14 +15,16 @@ namespace Pinetime { void Init(); void LVGLFileSystemInit(); - void FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); - void FileClose(lfs_file_t* file_p); - void Delete(const char* fileName); - void FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); - void FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); - void FileSeek(lfs_file_t* file_p, uint32_t pos); + int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); + int FileClose(lfs_file_t* file_p); + int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); + int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); + int FileSeek(lfs_file_t* file_p, uint32_t pos); + + int FileDelete(const char* fileName); - void MkDir(const char* path); + int DirCreate(const char* path); + int DirDelete(const char* path); void VerifyResource(); diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index c3b4b2e0c6..1383135507 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -25,7 +25,9 @@ void Settings::SaveSettings() { void Settings::LoadSettingsFromFile() { SettingsData bufferSettings; - fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT); + if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + return; + } fs.FileRead(&settingsFile, (uint8_t *)&bufferSettings, sizeof(settings)); fs.FileClose(&settingsFile); if ( bufferSettings.version == settingsVersion ) { @@ -34,7 +36,10 @@ void Settings::LoadSettingsFromFile() { } void Settings::SaveSettingsToFile() { - fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT); + + if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + return; + } fs.FileWrite(&settingsFile, (uint8_t *)&settings, sizeof(settings)); fs.FileClose(&settingsFile); } From 3b4de93caec0030e840c01d78161c8e65bead61e Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Jul 2021 23:05:07 +0100 Subject: [PATCH 5/7] More small fixes from PR suggestions --- src/CMakeLists.txt | 8 +- src/components/fs/FS.cpp | 217 ++++++++++++++------------- src/components/settings/Settings.cpp | 10 +- src/components/settings/Settings.h | 13 +- src/libs/littlefs | 2 +- 5 files changed, 125 insertions(+), 125 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6a0fbacc8..40e1f2a554 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -815,10 +815,10 @@ add_library(littlefs STATIC ${LITTLEFS_SRC}) target_include_directories(littlefs SYSTEM PUBLIC . ../) target_include_directories(littlefs SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) target_compile_options(littlefs PRIVATE - $<$,$>: ${COMMON_FLAGS} -Og -g3> - $<$,$>: ${COMMON_FLAGS} -Os> - $<$,$>: ${COMMON_FLAGS} -Og -g3 -fno-rtti> - $<$,$>: ${COMMON_FLAGS} -Os -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Os> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3 -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Os -fno-rtti> $<$: -MP -MD -x assembler-with-cpp> ) diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index a689ec35f5..b929126f62 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -15,34 +15,34 @@ static constexpr size_t BLOCK_SIZE_BYTES = 4096; */ namespace { - int read(const struct lfs_config *c, lfs_block_t block, - lfs_off_t off, void *buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Read(address, (uint8_t*)buffer, size); - - return 0; - } - - int prog(const struct lfs_config *c, lfs_block_t block, - lfs_off_t off, const void *buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Write(address, (uint8_t*)buffer, size); - return lfs.mDriver.ProgramFailed() ? -1 : 0; - } - - int erase(const struct lfs_config *c, lfs_block_t block) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES); - lfs.mDriver.SectorErase(address); - return lfs.mDriver.EraseFailed() ? -1 : 0; - } - - int sync(const struct lfs_config *c) { - // no hardware caching used - return 0; - } + int read(const struct lfs_config* c, lfs_block_t block, + lfs_off_t off, void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Read(address, (uint8_t*)buffer, size); + + return 0; + } + + int prog(const struct lfs_config* c, lfs_block_t block, + lfs_off_t off, const void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Write(address, (uint8_t*)buffer, size); + return lfs.mDriver.ProgramFailed() ? -1 : 0; + } + + int erase(const struct lfs_config* c, lfs_block_t block) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES); + lfs.mDriver.SectorErase(address); + return lfs.mDriver.EraseFailed() ? -1 : 0; + } + + int sync(const struct lfs_config* c) { + // no hardware caching used + return 0; + } } const static struct lfs_config baseLfsConfig = { @@ -65,89 +65,89 @@ const static struct lfs_config baseLfsConfig = { }; constexpr struct lfs_config createLfsConfig(Pinetime::Controllers::FS& fs, const size_t totalSizeBytes) { - struct lfs_config config = baseLfsConfig; - config.context = &fs; - config.block_count = totalSizeBytes / BLOCK_SIZE_BYTES; - return config; + struct lfs_config config = baseLfsConfig; + config.context = &fs; + config.block_count = totalSizeBytes / BLOCK_SIZE_BYTES; + return config; } FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : - mDriver{driver}, - mLfsConfig{createLfsConfig(*this, mSize)} { } + mDriver{ driver }, + mLfsConfig{ createLfsConfig(*this, mSize) } { } void FS::Init() { - // try mount - int err = lfs_mount(&mLfs, &mLfsConfig); + // try mount + int err = lfs_mount(&mLfs, &mLfsConfig); - // reformat if we can't mount the filesystem - // this should only happen on the first boot + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err != LFS_ERR_OK) { + lfs_format(&mLfs, &mLfsConfig); + err = lfs_mount(&mLfs, &mLfsConfig); if (err != LFS_ERR_OK) { - lfs_format(&mLfs, &mLfsConfig); - err = lfs_mount(&mLfs, &mLfsConfig); - if (err != LFS_ERR_OK) { - return; - } + return; } + } #ifndef PINETIME_IS_RECOVERY - VerifyResource(); - LVGLFileSystemInit(); + VerifyResource(); + LVGLFileSystemInit(); #endif } void FS::VerifyResource() { - // validate the resource metadata - resourcesValid = true; + // validate the resource metadata + resourcesValid = true; } int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { - return lfs_file_open(&mLfs, file_p, fileName, flags); + return lfs_file_open(&mLfs, file_p, fileName, flags); } int FS::FileClose(lfs_file_t* file_p) { - return lfs_file_close(&mLfs, file_p); + return lfs_file_close(&mLfs, file_p); } int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { - return lfs_file_read(&mLfs, file_p, buff, size); + return lfs_file_read(&mLfs, file_p, buff, size); } int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { - return lfs_file_write(&mLfs, file_p, buff, size); + return lfs_file_write(&mLfs, file_p, buff, size); } int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { - return lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); + return lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); } int FS::FileDelete(const char* fileName) { - return lfs_remove(&mLfs, fileName); + return lfs_remove(&mLfs, fileName); } int FS::DirCreate(const char* path) { - return lfs_mkdir(&mLfs, path); + return lfs_mkdir(&mLfs, path); } // Delete directory and all files inside int FS::DirDelete(const char* path) { - lfs_dir_t mLfs_dir; - lfs_info entryInfo; - - int err; - err = lfs_dir_open(&mLfs, &mLfs_dir, path); - if (err) { - return err; - } - while (lfs_dir_read(&mLfs, &mLfs_dir, &entryInfo)) { - lfs_remove(&mLfs, entryInfo.name); - } - lfs_dir_close(&mLfs, &mLfs_dir); - return LFS_ERR_OK; + lfs_dir_t mLfs_dir; + lfs_info entryInfo; + + int err; + err = lfs_dir_open(&mLfs, &mLfs_dir, path); + if (err) { + return err; + } + while (lfs_dir_read(&mLfs, &mLfs_dir, &entryInfo)) { + lfs_remove(&mLfs, entryInfo.name); + } + lfs_dir_close(&mLfs, &mLfs_dir); + return LFS_ERR_OK; } @@ -158,57 +158,58 @@ int FS::DirDelete(const char* path) { */ namespace { - lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { - - lfs_file_t* file = static_cast(file_p); - FS* filesys = static_cast(drv->user_data); - filesys->FileOpen(file, path, LFS_O_RDONLY); - - if (file->type == 0) { - return LV_FS_RES_FS_ERR; - } else { - return LV_FS_RES_OK; - } - } - - lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileClose( file ); + lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { - return LV_FS_RES_OK; - } + lfs_file_t* file = static_cast(file_p); + FS* filesys = static_cast(drv->user_data); + filesys->FileOpen(file, path, LFS_O_RDONLY); - lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileRead(file, (uint8_t *)buf, btr); - *br = btr; - return LV_FS_RES_OK; + if (file->type == 0) { + return LV_FS_RES_FS_ERR; } - - lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { - FS* filesys = static_cast(drv->user_data); - lfs_file_t* file = static_cast(file_p); - filesys->FileSeek(file, pos); - return LV_FS_RES_OK; + else { + return LV_FS_RES_OK; } + } + + lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileClose(file); + + return LV_FS_RES_OK; + } + + lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileRead(file, (uint8_t*)buf, btr); + *br = btr; + return LV_FS_RES_OK; + } + + lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileSeek(file, pos); + return LV_FS_RES_OK; + } } void FS::LVGLFileSystemInit() { - lv_fs_drv_t fs_drv; - lv_fs_drv_init(&fs_drv); + lv_fs_drv_t fs_drv; + lv_fs_drv_init(&fs_drv); - fs_drv.file_size = sizeof(lfs_file_t); - fs_drv.letter = 'F'; - fs_drv.open_cb = lvglOpen; - fs_drv.close_cb = lvglClose; - fs_drv.read_cb = lvglRead; - fs_drv.seek_cb = lvglSeek; + fs_drv.file_size = sizeof(lfs_file_t); + fs_drv.letter = 'F'; + fs_drv.open_cb = lvglOpen; + fs_drv.close_cb = lvglClose; + fs_drv.read_cb = lvglRead; + fs_drv.seek_cb = lvglSeek; - fs_drv.user_data = this; + fs_drv.user_data = this; - lv_fs_drv_register(&fs_drv); + lv_fs_drv_register(&fs_drv); } \ No newline at end of file diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 1383135507..37c09f9104 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -24,22 +24,24 @@ void Settings::SaveSettings() { void Settings::LoadSettingsFromFile() { SettingsData bufferSettings; + lfs_file_t settingsFile; if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { return; } - fs.FileRead(&settingsFile, (uint8_t *)&bufferSettings, sizeof(settings)); + fs.FileRead(&settingsFile, reinterpret_cast(&bufferSettings), sizeof(settings)); fs.FileClose(&settingsFile); if ( bufferSettings.version == settingsVersion ) { - std::memcpy((void *)&settings, (void *)&bufferSettings, sizeof(settings)); + settings = bufferSettings; } } void Settings::SaveSettingsToFile() { - + lfs_file_t settingsFile; + if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { return; } - fs.FileWrite(&settingsFile, (uint8_t *)&settings, sizeof(settings)); + fs.FileWrite(&settingsFile, reinterpret_cast(&settings), sizeof(settings)); fs.FileClose(&settingsFile); } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 58aaeda462..332351571b 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -9,9 +9,9 @@ namespace Pinetime { namespace Controllers { class Settings { public: - enum class ClockType { H24, H12 }; - enum class Vibration { ON, OFF }; - enum class WakeUpMode { None, SingleTap, DoubleTap, RaiseWrist }; + enum class ClockType : uint8_t { H24, H12 }; + enum class Vibration : uint8_t { ON, OFF }; + enum class WakeUpMode : uint8_t { None, SingleTap, DoubleTap, RaiseWrist }; Settings(Pinetime::Controllers::FS& fs); @@ -101,15 +101,14 @@ namespace Pinetime { struct SettingsData { uint32_t version = settingsVersion; + uint32_t stepsGoal = 10000; + uint32_t screenTimeOut = 15000; ClockType clockType = ClockType::H24; Vibration vibrationStatus = Vibration::ON; uint8_t clockFace = 0; - uint32_t stepsGoal = 10000; - uint32_t screenTimeOut = 15000; - WakeUpMode wakeUpMode = WakeUpMode::None; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; @@ -121,8 +120,6 @@ namespace Pinetime { uint8_t appMenu = 0; uint8_t settingsMenu = 0; - lfs_file_t settingsFile; - void LoadSettingsFromFile(); void SaveSettingsToFile(); }; diff --git a/src/libs/littlefs b/src/libs/littlefs index 1863dc7883..ead50807f1 160000 --- a/src/libs/littlefs +++ b/src/libs/littlefs @@ -1 +1 @@ -Subproject commit 1863dc7883d82bd6ca79faa164b65341064d1c16 +Subproject commit ead50807f1ca3fdf2da00b77a0ce02651ded2d13 From 787ccaea777dadaf235b2acfab875d1857d20cb4 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Mon, 5 Jul 2021 10:11:09 +0100 Subject: [PATCH 6/7] Code clean up --- src/components/fs/FS.cpp | 47 ++++++++--------- src/components/fs/FS.h | 84 +++++++++++++++--------------- src/components/settings/Settings.h | 21 +++++--- 3 files changed, 78 insertions(+), 74 deletions(-) diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index b929126f62..c1cde325fb 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -1,13 +1,10 @@ #include "FS.h" #include -#include -#include "drivers/SpiNorFlash.h" #include #include using namespace Pinetime::Controllers; - static constexpr size_t BLOCK_SIZE_BYTES = 4096; /* @@ -18,8 +15,8 @@ namespace { int read(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) { Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Read(address, (uint8_t*)buffer, size); + const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Read(address, static_cast(buffer), size); return 0; } @@ -27,14 +24,14 @@ namespace { int prog(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) { Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Write(address, (uint8_t*)buffer, size); + const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES) + off; + lfs.mDriver.Write(address, (uint8_t*) buffer, size); return lfs.mDriver.ProgramFailed() ? -1 : 0; } int erase(const struct lfs_config* c, lfs_block_t block) { Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = lfs.mStartAddress + (block * BLOCK_SIZE_BYTES); + const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES); lfs.mDriver.SectorErase(address); return lfs.mDriver.EraseFailed() ? -1 : 0; } @@ -73,19 +70,19 @@ constexpr struct lfs_config createLfsConfig(Pinetime::Controllers::FS& fs, const FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : mDriver{ driver }, - mLfsConfig{ createLfsConfig(*this, mSize) } { } + lfsConfig{ createLfsConfig(*this, size) } { } void FS::Init() { // try mount - int err = lfs_mount(&mLfs, &mLfsConfig); + int err = lfs_mount(&lfs, &lfsConfig); // reformat if we can't mount the filesystem // this should only happen on the first boot if (err != LFS_ERR_OK) { - lfs_format(&mLfs, &mLfsConfig); - err = lfs_mount(&mLfs, &mLfsConfig); + lfs_format(&lfs, &lfsConfig); + err = lfs_mount(&lfs, &lfsConfig); if (err != LFS_ERR_OK) { return; } @@ -104,49 +101,49 @@ void FS::VerifyResource() { } int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { - return lfs_file_open(&mLfs, file_p, fileName, flags); + return lfs_file_open(&lfs, file_p, fileName, flags); } int FS::FileClose(lfs_file_t* file_p) { - return lfs_file_close(&mLfs, file_p); + return lfs_file_close(&lfs, file_p); } int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { - return lfs_file_read(&mLfs, file_p, buff, size); + return lfs_file_read(&lfs, file_p, buff, size); } int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { - return lfs_file_write(&mLfs, file_p, buff, size); + return lfs_file_write(&lfs, file_p, buff, size); } int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { - return lfs_file_seek(&mLfs, file_p, pos, LFS_SEEK_SET); + return lfs_file_seek(&lfs, file_p, pos, LFS_SEEK_SET); } int FS::FileDelete(const char* fileName) { - return lfs_remove(&mLfs, fileName); + return lfs_remove(&lfs, fileName); } int FS::DirCreate(const char* path) { - return lfs_mkdir(&mLfs, path); + return lfs_mkdir(&lfs, path); } // Delete directory and all files inside int FS::DirDelete(const char* path) { - lfs_dir_t mLfs_dir; + lfs_dir_t lfs_dir; lfs_info entryInfo; int err; - err = lfs_dir_open(&mLfs, &mLfs_dir, path); + err = lfs_dir_open(&lfs, &lfs_dir, path); if (err) { return err; } - while (lfs_dir_read(&mLfs, &mLfs_dir, &entryInfo)) { - lfs_remove(&mLfs, entryInfo.name); + while (lfs_dir_read(&lfs, &lfs_dir, &entryInfo)) { + lfs_remove(&lfs, entryInfo.name); } - lfs_dir_close(&mLfs, &mLfs_dir); + lfs_dir_close(&lfs, &lfs_dir); return LFS_ERR_OK; } @@ -183,7 +180,7 @@ namespace { lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { FS* filesys = static_cast(drv->user_data); lfs_file_t* file = static_cast(file_p); - filesys->FileRead(file, (uint8_t*)buf, btr); + filesys->FileRead(file, static_cast(buf), btr); *br = btr; return LV_FS_RES_OK; } diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index d01f8fadf7..c78612eafb 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -7,57 +7,57 @@ namespace Pinetime { namespace Controllers { class FS { - public: - FS(Pinetime::Drivers::SpiNorFlash&); + public: + FS(Pinetime::Drivers::SpiNorFlash&); - Pinetime::Drivers::SpiNorFlash& mDriver; + Pinetime::Drivers::SpiNorFlash& mDriver; - void Init(); - void LVGLFileSystemInit(); + void Init(); + void LVGLFileSystemInit(); - int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); - int FileClose(lfs_file_t* file_p); - int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); - int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); - int FileSeek(lfs_file_t* file_p, uint32_t pos); + int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); + int FileClose(lfs_file_t* file_p); + int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); + int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); + int FileSeek(lfs_file_t* file_p, uint32_t pos); - int FileDelete(const char* fileName); + int FileDelete(const char* fileName); - int DirCreate(const char* path); - int DirDelete(const char* path); + int DirCreate(const char* path); + int DirDelete(const char* path); - void VerifyResource(); + void VerifyResource(); - /* - * External Flash MAP (4 MBytes) - * - * 0x000000 +---------------------------------------+ - * | Bootloader Assets | - * | 256 KBytes | - * | | - * 0x040000 +---------------------------------------+ - * | OTA | - * | 464 KBytes | - * | | - * | | - * | | - * 0x0B4000 +---------------------------------------+ - * | File System | - * | | - * | | - * | | - * | | - * 0x400000 +---------------------------------------+ - * - */ - static constexpr size_t mStartAddress = 0x0B4000; - static constexpr size_t mSize = 0x3C0000; + /* + * External Flash MAP (4 MBytes) + * + * 0x000000 +---------------------------------------+ + * | Bootloader Assets | + * | 256 KBytes | + * | | + * 0x040000 +---------------------------------------+ + * | OTA | + * | 464 KBytes | + * | | + * | | + * | | + * 0x0B4000 +---------------------------------------+ + * | File System | + * | | + * | | + * | | + * | | + * 0x400000 +---------------------------------------+ + * + */ + static constexpr size_t startAddress = 0x0B4000; + static constexpr size_t size = 0x3C0000; - private: - bool resourcesValid = false; - const struct lfs_config mLfsConfig; + private: + bool resourcesValid = false; + const struct lfs_config lfsConfig; - lfs_t mLfs; + lfs_t lfs; }; } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 332351571b..577455ebd3 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -19,8 +19,9 @@ namespace Pinetime { void SaveSettings(); void SetClockFace(uint8_t face) { - if (face != settings.clockFace) + if (face != settings.clockFace) { settingsChanged = true; + } settings.clockFace = face; }; uint8_t GetClockFace() const { @@ -42,8 +43,9 @@ namespace Pinetime { }; void SetClockType(ClockType clocktype) { - if (clocktype != settings.clockType) + if (clocktype != settings.clockType) { settingsChanged = true; + } settings.clockType = clocktype; }; ClockType GetClockType() const { @@ -51,8 +53,9 @@ namespace Pinetime { }; void SetVibrationStatus(Vibration status) { - if (status != settings.vibrationStatus) + if (status != settings.vibrationStatus) { settingsChanged = true; + } settings.vibrationStatus = status; }; Vibration GetVibrationStatus() const { @@ -60,8 +63,9 @@ namespace Pinetime { }; void SetScreenTimeOut(uint32_t timeout) { - if (timeout != settings.screenTimeOut) + if (timeout != settings.screenTimeOut) { settingsChanged = true; + } settings.screenTimeOut = timeout; }; uint32_t GetScreenTimeOut() const { @@ -69,8 +73,9 @@ namespace Pinetime { }; void setWakeUpMode(WakeUpMode wakeUp) { - if (wakeUp != settings.wakeUpMode) + if (wakeUp != settings.wakeUpMode) { settingsChanged = true; + } settings.wakeUpMode = wakeUp; }; WakeUpMode getWakeUpMode() const { @@ -78,8 +83,9 @@ namespace Pinetime { }; void SetBrightness(Controllers::BrightnessController::Levels level) { - if (level != settings.brightLevel) + if (level != settings.brightLevel) { settingsChanged = true; + } settings.brightLevel = level; }; Controllers::BrightnessController::Levels GetBrightness() const { @@ -87,8 +93,9 @@ namespace Pinetime { }; void SetStepsGoal( uint32_t goal ) { - if ( goal != settings.stepsGoal ) + if ( goal != settings.stepsGoal ) { settingsChanged = true; + } settings.stepsGoal = goal; }; From 1e34523686fbb6d9f1595aac5d2c8dde1bec3926 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Wed, 7 Jul 2021 11:55:41 +0100 Subject: [PATCH 7/7] Change SpiNorFlash functions to be private in FS --- src/components/fs/FS.cpp | 99 +++++++++++++++++----------------------- src/components/fs/FS.h | 13 ++++-- 2 files changed, 52 insertions(+), 60 deletions(-) diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index c1cde325fb..857e6bf93d 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -5,72 +5,28 @@ using namespace Pinetime::Controllers; -static constexpr size_t BLOCK_SIZE_BYTES = 4096; - -/* -* Interface between littlefs and SpiNorFlash -*/ - -namespace { - int read(const struct lfs_config* c, lfs_block_t block, - lfs_off_t off, void* buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Read(address, static_cast(buffer), size); - - return 0; - } - - int prog(const struct lfs_config* c, lfs_block_t block, - lfs_off_t off, const void* buffer, lfs_size_t size) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES) + off; - lfs.mDriver.Write(address, (uint8_t*) buffer, size); - return lfs.mDriver.ProgramFailed() ? -1 : 0; - } - - int erase(const struct lfs_config* c, lfs_block_t block) { - Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); - const size_t address = Pinetime::Controllers::FS::startAddress + (block * BLOCK_SIZE_BYTES); - lfs.mDriver.SectorErase(address); - return lfs.mDriver.EraseFailed() ? -1 : 0; - } - - int sync(const struct lfs_config* c) { - // no hardware caching used - return 0; - } -} - -const static struct lfs_config baseLfsConfig = { - .read = read, - .prog = prog, - .erase = erase, - .sync = sync, +FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : + flashDriver{ driver }, + lfsConfig{ + .context = this, + .read = SectorRead, + .prog = SectorProg, + .erase = SectorErase, + .sync = SectorSync, .read_size = 16, .prog_size = 8, - .block_size = BLOCK_SIZE_BYTES, + .block_size = blockSize, + .block_count = size / blockSize, .block_cycles = 1000u, .cache_size = 16, .lookahead_size = 16, .name_max = 50, - .attr_max = 50 - -}; - -constexpr struct lfs_config createLfsConfig(Pinetime::Controllers::FS& fs, const size_t totalSizeBytes) { - struct lfs_config config = baseLfsConfig; - config.context = &fs; - config.block_count = totalSizeBytes / BLOCK_SIZE_BYTES; - return config; -} - -FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : - mDriver{ driver }, - lfsConfig{ createLfsConfig(*this, size) } { } + .attr_max = 50, + } +{ } void FS::Init() { @@ -147,6 +103,35 @@ int FS::DirDelete(const char* path) { return LFS_ERR_OK; } +/* + + ----------- Interface between littlefs and SpiNorFlash ----------- + +*/ +int FS::SectorSync(const struct lfs_config* c) { + return 0; +} + +int FS::SectorErase(const struct lfs_config* c, lfs_block_t block) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize); + lfs.flashDriver.SectorErase(address); + return lfs.flashDriver.EraseFailed() ? -1 : 0; +} + +int FS::SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize) + off; + lfs.flashDriver.Write(address, (uint8_t*) buffer, size); + return lfs.flashDriver.ProgramFailed() ? -1 : 0; +} + +int FS::SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize) + off; + lfs.flashDriver.Read(address, static_cast(buffer), size); + return 0; +} /* diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index c78612eafb..1f2eb7e069 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -10,8 +10,6 @@ namespace Pinetime { public: FS(Pinetime::Drivers::SpiNorFlash&); - Pinetime::Drivers::SpiNorFlash& mDriver; - void Init(); void LVGLFileSystemInit(); @@ -28,6 +26,10 @@ namespace Pinetime { void VerifyResource(); + private: + + Pinetime::Drivers::SpiNorFlash& flashDriver; + /* * External Flash MAP (4 MBytes) * @@ -52,13 +54,18 @@ namespace Pinetime { */ static constexpr size_t startAddress = 0x0B4000; static constexpr size_t size = 0x3C0000; + static constexpr size_t blockSize = 4096; - private: bool resourcesValid = false; const struct lfs_config lfsConfig; lfs_t lfs; + static int SectorSync(const struct lfs_config* c); + static int SectorErase(const struct lfs_config* c, lfs_block_t block); + static int SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size); + static int SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size); + }; } }