From 644431cbc465f94a0cfc70b370b8c0f4c16d12e1 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 15 May 2022 22:15:19 +0200 Subject: [PATCH] Add support for SpiNorFlash and FS (#30) The external SPI flash is implemented as a 4MB on the local filesystem. This allows the FS (littleFS) and settings to work properly. Remove the simulated `FS.h` and `FS.cpp`, because we can now use the files from InfiniTime directly as the heavy lifting is done in the simulated `SpiNorFlash.h` and cpp files. `SpiNorFlash.h` provides read and write functions with `uint8_t` buffer, but `fs::fstream` expects `char` buffer. Use `reinterpret_cast` and check if by any chance the `char` type on a platform is implemented with more than one byte. Then the `reinterpret_cast(buffer)` would change the meaning of the `size` parameter, which could lead to garbage data. Co-authored-by: Reinhold Gschweicher --- CMakeLists.txt | 12 +- main.cpp | 6 +- sim/components/fs/FS.cpp | 261 ------------------------------------ sim/components/fs/FS.h | 157 ---------------------- sim/drivers/SpiNorFlash.cpp | 106 ++++----------- sim/drivers/SpiNorFlash.h | 10 +- 6 files changed, 50 insertions(+), 502 deletions(-) delete mode 100644 sim/components/fs/FS.cpp delete mode 100644 sim/components/fs/FS.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e2b555..d8fa68c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,8 +88,6 @@ target_sources(infinisim PUBLIC sim/components/brightness/BrightnessController.cpp sim/components/firmwarevalidator/FirmwareValidator.h sim/components/firmwarevalidator/FirmwareValidator.cpp - sim/components/fs/FS.h - sim/components/fs/FS.cpp sim/components/heartrate/HeartRateController.h sim/components/heartrate/HeartRateController.cpp sim/components/motion/MotionController.h @@ -173,13 +171,21 @@ file(GLOB InfiniTime_WIDGETS "${InfiniTime_DIR}/src/displayapp/widgets/*.cpp" "${InfiniTime_DIR}/src/displayapp/widgets/*.h" ) +set(LITTLEFS_SRC + ${InfiniTime_DIR}/src/libs/littlefs/lfs_util.h + ${InfiniTime_DIR}/src/libs/littlefs/lfs.h + ${InfiniTime_DIR}/src/libs/littlefs/lfs_util.c + ${InfiniTime_DIR}/src/libs/littlefs/lfs.c +) target_sources(infinisim PUBLIC ${InfiniTime_SCREENS}) target_sources(infinisim PUBLIC ${InfiniTime_FONTS}) target_sources(infinisim PUBLIC ${InfiniTime_ICONS}) target_sources(infinisim PUBLIC ${InfiniTime_WIDGETS}) +target_sources(infinisim PUBLIC ${LITTLEFS_SRC}) # add files directly from InfiniTime sources target_include_directories(infinisim PRIVATE "${InfiniTime_DIR}/src") +target_include_directories(infinisim PRIVATE "${InfiniTime_DIR}/src/libs/littlefs") target_sources(infinisim PUBLIC ${InfiniTime_DIR}/src/BootloaderVersion.h ${InfiniTime_DIR}/src/BootloaderVersion.cpp @@ -202,6 +208,8 @@ target_sources(infinisim PUBLIC ${InfiniTime_DIR}/src/components/settings/Settings.cpp ${InfiniTime_DIR}/src/components/ble/NotificationManager.h ${InfiniTime_DIR}/src/components/ble/NotificationManager.cpp + ${InfiniTime_DIR}/src/components/fs/FS.h + ${InfiniTime_DIR}/src/components/fs/FS.cpp ${InfiniTime_DIR}/src/components/timer/TimerController.h ${InfiniTime_DIR}/src/components/timer/TimerController.cpp ${InfiniTime_DIR}/src/drivers/PinMap.h diff --git a/main.cpp b/main.cpp index a0a823a..2a0fd71 100644 --- a/main.cpp +++ b/main.cpp @@ -224,7 +224,7 @@ Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; -Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; +Pinetime::Drivers::SpiNorFlash spiNorFlash {"spiNorFlash.raw"}; // The TWI device should work @ up to 400Khz but there is a HW bug which prevent it from // respecting correct timings. According to erratas heet, this magic value makes it run @@ -252,7 +252,7 @@ Pinetime::Controllers::Ble bleController; Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); -Pinetime::Controllers::FS fs; // {spiNorFlash}; +Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::Settings settingsController {fs}; Pinetime::Controllers::MotorController motorController {}; @@ -837,6 +837,8 @@ int main(int argc, char **argv) /*Initialize the HAL (display, input devices, tick) for LVGL*/ hal_init(); + fs.Init(); + // initialize the core of our Simulator Framework fw(fw_status_window_visible, 240,240); diff --git a/sim/components/fs/FS.cpp b/sim/components/fs/FS.cpp deleted file mode 100644 index 0e61695..0000000 --- a/sim/components/fs/FS.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "FS.h" -#include -#include -#include -//#include -#include - -using namespace Pinetime::Controllers; - -//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 = blockSize, -// .block_count = size / blockSize, -// .block_cycles = 1000u, -// -// .cache_size = 16, -// .lookahead_size = 16, -// -// .name_max = 50, -// .attr_max = 50, -// } { -//} - - -void FS::Init() { - -// // try mount -// 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(&lfs, &lfsConfig); -// err = lfs_mount(&lfs, &lfsConfig); -// if (err != LFS_ERR_OK) { -// return; -// } -// } -// -//#ifndef PINETIME_IS_RECOVERY -// VerifyResource(); -// LVGLFileSystemInit(); -//#endif - -} - -void FS::VerifyResource() { - // validate the resource metadata - resourcesValid = true; -} - -int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { - // create the file in the current directory - const char *local_filename = fileName[0]=='/' ? &fileName[1] : fileName; - const char *mode; - bool flag_read = flags & LFS_O_RDONLY; - bool flag_write = flags & LFS_O_WRONLY; - bool flag_create = flags & LFS_O_CREAT; - if (flag_create) { - if (std::filesystem::exists(local_filename)) { - if (flag_read && flag_write) { - mode = "rb+"; - } else if (flag_read) { - mode = "rb"; - } else if (flag_write) { - mode = "wb"; - } else { - assert(false); // not implemented - } - } else { - if (flag_read && flag_write) { - mode = "wb+"; - } else if (flag_read) { - assert(false); // read only file not existing - mode = "rb"; - } else if (flag_write) { - mode = "wb"; - } else { - assert(false); // not implemented - } - } - } else { - if (std::filesystem::exists(local_filename)) { - if (flag_read && flag_write) { - mode = "rb+"; - } else if (flag_read) { - mode = "rb"; - } else if (flag_write) { - mode = "wb"; - } else { - assert(false); // not implemented - } - } else { - return LFS_ERR_IO; - } - } - FILE *fptr = fopen(local_filename, mode); - if (fptr == nullptr) { - return LFS_ERR_BADF; - } else { - *file_p = fptr; - return LFS_ERR_OK; - } - //return lfs_file_open(&lfs, file_p, fileName, flags); -} - -int FS::FileClose(lfs_file_t* file_p) { - return fclose(*file_p); - //return lfs_file_close(&lfs, file_p); -} - -int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { - return fread(buff, sizeof(uint8_t), size, *file_p); - //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 fwrite((void*)buff, sizeof(uint8_t), size, *file_p); - //return lfs_file_write(&lfs, file_p, buff, size); -} - -int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { - return fseek(*file_p, pos, SEEK_SET); - //return lfs_file_seek(&lfs, file_p, pos, whence); -} - -int FS::FileDelete(const char* fileName) { - return std::filesystem::remove(fileName); - //return lfs_remove(&lfs, fileName); -} - - -int FS::DirCreate(const char* path) { - return std::filesystem::create_directory(path); - //return lfs_mkdir(&lfs, path); -} - -// Delete directory and all files inside -int FS::DirDelete(const char* path) { - return std::filesystem::remove_all(path); - - //lfs_dir_t lfs_dir; - //lfs_info entryInfo; - - //int err; - //err = lfs_dir_open(&lfs, &lfs_dir, path); - //if (err) { - // return err; - //} - //while (lfs_dir_read(&lfs, &lfs_dir, &entryInfo)) { - // lfs_remove(&lfs, entryInfo.name); - //} - //lfs_dir_close(&lfs, &lfs_dir); - //return LFS_ERR_OK; -} - -// check if file exists, if so write file-size into info object -int FS::Stat(const char* path, lfs_info* info) { - const char *local_filename = path[0]=='/' ? &path[1] : path; - if (!std::filesystem::exists(local_filename)) - { - return LFS_ERR_NOENT; // No directory entry - } - info->size = std::filesystem::file_size(local_filename); - 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; -//} - -/* - - ----------- LVGL filesystem integration ----------- - -*/ - -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); - int ret = filesys->FileOpen(file, path, LFS_O_RDONLY); - if (ret != LFS_ERR_OK) { - return LV_FS_RES_FS_ERR; - } - 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, static_cast(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_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); -} diff --git a/sim/components/fs/FS.h b/sim/components/fs/FS.h deleted file mode 100644 index ab151e2..0000000 --- a/sim/components/fs/FS.h +++ /dev/null @@ -1,157 +0,0 @@ -#pragma once - -#include -#include -//#include "drivers/SpiNorFlash.h" -//#include -#include - -using lfs_file_t = FILE*; - -// copied from src/libs/littlefs/lfs.h -// Possible error codes, these are negative to allow -// valid positive return values -enum lfs_error { - LFS_ERR_OK = 0, // No error - LFS_ERR_IO = -5, // Error during device operation - LFS_ERR_CORRUPT = -84, // Corrupted - LFS_ERR_NOENT = -2, // No directory entry - LFS_ERR_EXIST = -17, // Entry already exists - LFS_ERR_NOTDIR = -20, // Entry is not a dir - LFS_ERR_ISDIR = -21, // Entry is a dir - LFS_ERR_NOTEMPTY = -39, // Dir is not empty - LFS_ERR_BADF = -9, // Bad file number - LFS_ERR_FBIG = -27, // File too large - LFS_ERR_INVAL = -22, // Invalid parameter - LFS_ERR_NOSPC = -28, // No space left on device - LFS_ERR_NOMEM = -12, // No more memory available - LFS_ERR_NOATTR = -61, // No data/attr available - LFS_ERR_NAMETOOLONG = -36, // File name too long -}; - -enum lfs_open_flags { - // open flags - LFS_O_RDONLY = 1, // Open a file as read only -#ifndef LFS_READONLY - LFS_O_WRONLY = 2, // Open a file as write only - LFS_O_RDWR = 3, // Open a file as read and write - LFS_O_CREAT = 0x0100, // Create a file if it does not exist - LFS_O_EXCL = 0x0200, // Fail if a file already exists - LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size - LFS_O_APPEND = 0x0800, // Move to end of file on every write -#endif -}; - -// File seek flags -enum lfs_whence_flags { - LFS_SEEK_SET = 0, // Seek relative to an absolute position - LFS_SEEK_CUR = 1, // Seek relative to the current file position - LFS_SEEK_END = 2, // Seek relative to the end of the file -}; - -typedef uint32_t lfs_size_t; -typedef int32_t lfs_ssize_t; - -// Maximum name size in bytes, may be redefined to reduce the size of the -// info struct. Limited to <= 1022. Stored in superblock and must be -// respected by other littlefs drivers. -//#ifndef LFS_NAME_MAX -//#define LFS_NAME_MAX 255 -//#endif - -// File info structure -struct lfs_info { -// // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR -// uint8_t type; - - // Size of the file, only valid for REG files. Limited to 32-bits. - lfs_size_t size; - -// // Name of the file stored as a null-terminated string. Limited to -// // LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to -// // reduce RAM. LFS_NAME_MAX is stored in superblock and must be -// // respected by other littlefs drivers. -// char name[LFS_NAME_MAX+1]; -}; - -namespace Pinetime { - namespace Controllers { - class FS { - public: - //FS(Pinetime::Drivers::SpiNorFlash&); - - 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 FileDelete(const char* fileName); - - //int DirOpen(const char* path, lfs_dir_t* lfs_dir); - //int DirClose(lfs_dir_t* lfs_dir); - //int DirRead(lfs_dir_t* dir, lfs_info* info); - //int DirRewind(lfs_dir_t* dir); - int DirCreate(const char* path); - int DirDelete(const char* path); - - lfs_ssize_t GetFSSize(); - int Rename(const char* oldPath, const char* newPath); - int Stat(const char* path, lfs_info* info); - void VerifyResource(); - - static size_t getSize() { - return size; - } - static size_t getBlockSize() { - return blockSize; - } - - private: - - //Pinetime::Drivers::SpiNorFlash& flashDriver; - - /* - * 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 = 0x34C000; - static constexpr size_t blockSize = 4096; - - lv_fs_drv_t fs_drv; - - 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); - - }; - } -} diff --git a/sim/drivers/SpiNorFlash.cpp b/sim/drivers/SpiNorFlash.cpp index 4a0680e..bca056f 100644 --- a/sim/drivers/SpiNorFlash.cpp +++ b/sim/drivers/SpiNorFlash.cpp @@ -1,12 +1,27 @@ #include "drivers/SpiNorFlash.h" #include -#include #include #include "drivers/Spi.h" +#include +#include using namespace Pinetime::Drivers; -SpiNorFlash::SpiNorFlash(Spi& spi) : spi {spi} { +SpiNorFlash::SpiNorFlash(const std::string& memoryFilePath) : memoryFilePath{memoryFilePath} { + namespace fs = std::filesystem; + fs::path f{ memoryFilePath }; + if (fs::exists(f)) { + memoryFile = std::fstream(memoryFilePath, std::ios::binary | std::fstream::in | std::fstream::out); + } else { + memoryFile = std::fstream(memoryFilePath, std::ios::trunc | std::ios::binary | std::fstream::in | std::fstream::out); + memoryFile.seekp(memorySize - 1); + memoryFile.write("", 1); + } +} +SpiNorFlash::~SpiNorFlash() { + if (memoryFile.is_open()) { + memoryFile.close(); + } } void SpiNorFlash::Init() { @@ -19,126 +34,61 @@ void SpiNorFlash::Uninit() { } void SpiNorFlash::Sleep() { - auto cmd = static_cast(Commands::DeepPowerDown); - spi.Write(&cmd, sizeof(uint8_t)); NRF_LOG_INFO("[SpiNorFlash] Sleep") } void SpiNorFlash::Wakeup() { - // send Commands::ReleaseFromDeepPowerDown then 3 dummy bytes before reading Device ID -// static constexpr uint8_t cmdSize = 4; -// uint8_t cmd[cmdSize] = {static_cast(Commands::ReleaseFromDeepPowerDown), 0x01, 0x02, 0x03}; -// uint8_t id = 0; -// spi.Read(reinterpret_cast(&cmd), cmdSize, &id, 1); -// auto devId = device_id = ReadIdentificaion(); -// if (devId.type != device_id.type) { -// NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: Failed"); -// } else { -// NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: %d", id); -// } NRF_LOG_INFO("[SpiNorFlash] Wakeup") } SpiNorFlash::Identification SpiNorFlash::ReadIdentificaion() { -// auto cmd = static_cast(Commands::ReadIdentification); -// Identification identification; -// spi.Read(&cmd, 1, reinterpret_cast(&identification), sizeof(Identification)); -// return identification; return {}; } uint8_t SpiNorFlash::ReadStatusRegister() { - auto cmd = static_cast(Commands::ReadStatusRegister); - uint8_t status; - spi.Read(&cmd, sizeof(cmd), &status, sizeof(uint8_t)); - return status; + return 0; } bool SpiNorFlash::WriteInProgress() { -// return (ReadStatusRegister() & 0x01u) == 0x01u; return false; } bool SpiNorFlash::WriteEnabled() { -// return (ReadStatusRegister() & 0x02u) == 0x02u; return false; } uint8_t SpiNorFlash::ReadConfigurationRegister() { - auto cmd = static_cast(Commands::ReadConfigurationRegister); - uint8_t status; - spi.Read(&cmd, sizeof(cmd), &status, sizeof(uint8_t)); - return status; + return 0; } void SpiNorFlash::Read(uint32_t address, uint8_t* buffer, size_t size) { - static constexpr uint8_t cmdSize = 4; - uint8_t cmd[cmdSize] = {static_cast(Commands::Read), (uint8_t) (address >> 16U), (uint8_t) (address >> 8U), (uint8_t) address}; - spi.Read(reinterpret_cast(&cmd), cmdSize, buffer, size); + static_assert(sizeof(uint8_t) == sizeof(char)); + memoryFile.seekp(address); + memoryFile.read(reinterpret_cast(buffer), size); } void SpiNorFlash::WriteEnable() { - auto cmd = static_cast(Commands::WriteEnable); - spi.Read(&cmd, sizeof(cmd), nullptr, 0); + } void SpiNorFlash::SectorErase(uint32_t sectorAddress) { -// static constexpr uint8_t cmdSize = 4; -// uint8_t cmd[cmdSize] = {static_cast(Commands::SectorErase), -// (uint8_t) (sectorAddress >> 16U), -// (uint8_t) (sectorAddress >> 8U), -// (uint8_t) sectorAddress}; -// -// WriteEnable(); -// while (!WriteEnabled()) -// vTaskDelay(1); -// -// spi.Read(reinterpret_cast(&cmd), cmdSize, nullptr, 0); -// -// while (WriteInProgress()) -// vTaskDelay(1); + } uint8_t SpiNorFlash::ReadSecurityRegister() { - auto cmd = static_cast(Commands::ReadSecurityRegister); - uint8_t status; - spi.Read(&cmd, sizeof(cmd), &status, sizeof(uint8_t)); - return status; + return 0; } bool SpiNorFlash::ProgramFailed() { -// return (ReadSecurityRegister() & 0x20u) == 0x20u; return false; } bool SpiNorFlash::EraseFailed() { -// return (ReadSecurityRegister() & 0x40u) == 0x40u; return false; } void SpiNorFlash::Write(uint32_t address, const uint8_t* buffer, size_t size) { -// static constexpr uint8_t cmdSize = 4; -// -// size_t len = size; -// uint32_t addr = address; -// const uint8_t* b = buffer; -// while (len > 0) { -// uint32_t pageLimit = (addr & ~(pageSize - 1u)) + pageSize; -// uint32_t toWrite = pageLimit - addr > len ? len : pageLimit - addr; -// -// uint8_t cmd[cmdSize] = {static_cast(Commands::PageProgram), (uint8_t) (addr >> 16U), (uint8_t) (addr >> 8U), (uint8_t) addr}; -// -// WriteEnable(); -// while (!WriteEnabled()) -// vTaskDelay(1); -// -// spi.WriteCmdAndBuffer(cmd, cmdSize, b, toWrite); -// -// while (WriteInProgress()) -// vTaskDelay(1); -// -// addr += toWrite; -// b += toWrite; -// len -= toWrite; -// } + memoryFile.seekp(address); + memoryFile.write(reinterpret_cast(buffer), size); + memoryFile.flush(); } diff --git a/sim/drivers/SpiNorFlash.h b/sim/drivers/SpiNorFlash.h index ad4d090..83bdf7d 100644 --- a/sim/drivers/SpiNorFlash.h +++ b/sim/drivers/SpiNorFlash.h @@ -1,13 +1,15 @@ #pragma once #include #include +#include namespace Pinetime { namespace Drivers { class Spi; class SpiNorFlash { public: - explicit SpiNorFlash(Spi& spi); + explicit SpiNorFlash(const std::string& memoryFilePath); + ~SpiNorFlash(); SpiNorFlash(const SpiNorFlash&) = delete; SpiNorFlash& operator=(const SpiNorFlash&) = delete; SpiNorFlash(SpiNorFlash&&) = delete; @@ -53,8 +55,12 @@ namespace Pinetime { }; static constexpr uint16_t pageSize = 256; - Spi& spi; + static constexpr size_t memorySize {0x400000}; + const std::string& memoryFilePath; + + Identification device_id; + std::fstream memoryFile; }; } }