From 2fedcb61b55bfac4d2822d5b1594c8fab787f73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sun, 19 Jun 2022 16:33:15 +0200 Subject: [PATCH] [core] Migrate Flash library to common code based on FAL --- arduino/libretuya/api/Flash.h | 27 -------- arduino/libretuya/core/LibreTuyaAPI.h | 2 +- arduino/libretuya/core/LibreTuyaClass.cpp | 17 +++++ arduino/libretuya/core/LibreTuyaClass.h | 29 ++++---- arduino/libretuya/libraries/Flash/Flash.cpp | 30 +++++++++ .../libraries/Flash/Flash.h | 14 +--- arduino/libretuya/port/flashdb/fal_cfg.h | 5 +- .../cores/arduino/LibreTuyaAPI.cpp | 12 ++++ .../realtek-ambz/libraries/Flash/Flash.cpp | 66 ------------------- .../port/flashdb/fal_flash_ambz_port.c | 7 +- 10 files changed, 87 insertions(+), 122 deletions(-) delete mode 100644 arduino/libretuya/api/Flash.h create mode 100644 arduino/libretuya/libraries/Flash/Flash.cpp rename arduino/{realtek-ambz => libretuya}/libraries/Flash/Flash.h (61%) delete mode 100644 arduino/realtek-ambz/libraries/Flash/Flash.cpp diff --git a/arduino/libretuya/api/Flash.h b/arduino/libretuya/api/Flash.h deleted file mode 100644 index 7aaecbb..0000000 --- a/arduino/libretuya/api/Flash.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ - -#pragma once - -#include -#include -#include - -typedef struct { - uint8_t manufacturerId; - uint8_t chipId; - uint8_t chipSizeId; -} FlashId; - -class IFlashClass { - public: - IFlashClass() {} - - ~IFlashClass() {} - - virtual FlashId getChipId() = 0; - virtual uint32_t getSize() = 0; - - virtual bool eraseSector(uint32_t sector) = 0; - virtual bool readBlock(uint32_t offset, uint8_t *data, size_t size) = 0; - virtual bool writeBlock(uint32_t offset, uint8_t *data, size_t size) = 0; -}; diff --git a/arduino/libretuya/core/LibreTuyaAPI.h b/arduino/libretuya/core/LibreTuyaAPI.h index 18d91f9..32bb7f2 100644 --- a/arduino/libretuya/core/LibreTuyaAPI.h +++ b/arduino/libretuya/core/LibreTuyaAPI.h @@ -23,7 +23,7 @@ #include "LibreTuyaClass.h" // global LT class #include "LibreTuyaCompat.h" // compatibility methods #include "LibreTuyaConfig.h" // configuration macros -#include "LibreTuyaCustom.h" // family-defined methods +#include "LibreTuyaCustom.h" // family-defined methods (Wiring custom) #include // C includes diff --git a/arduino/libretuya/core/LibreTuyaClass.cpp b/arduino/libretuya/core/LibreTuyaClass.cpp index 70df6e9..b8c446f 100644 --- a/arduino/libretuya/core/LibreTuyaClass.cpp +++ b/arduino/libretuya/core/LibreTuyaClass.cpp @@ -57,6 +57,23 @@ uint32_t LibreTuya::getCpuFreqMHz() { return getCpuFreq() / 1000000; } +/** + * @brief Get flash chip total size. + * The default implementation uses the least significant + * byte of the chip ID to determine the size. + */ +__attribute__((weak)) uint32_t LibreTuya::getFlashChipSize() { + FlashId id = getFlashChipId(); + if (id.chipSizeId >= 0x14 && id.chipSizeId <= 0x19) { + return (1 << id.chipSizeId); + } +#ifdef FLASH_LENGTH + return FLASH_LENGTH; +#else + return 0; +#endif +} + static uint8_t otaRunningIndex = 0; /** diff --git a/arduino/libretuya/core/LibreTuyaClass.h b/arduino/libretuya/core/LibreTuyaClass.h index d3c7c1b..944e9ab 100644 --- a/arduino/libretuya/core/LibreTuyaClass.h +++ b/arduino/libretuya/core/LibreTuyaClass.h @@ -7,7 +7,14 @@ #include "LibreTuyaAPI.h" #include -#include // for flash inline methods +/** + * @brief Flash chip ID structure. + */ +typedef struct { + uint8_t manufacturerId; + uint8_t chipId; + uint8_t chipSizeId; +} FlashId; /** * @brief Main LibreTuya API class. @@ -25,23 +32,12 @@ class LibreTuya { const char *getChipFamilyName(); const char *getDeviceName(); uint32_t getCpuFreqMHz(); + uint32_t getFlashChipSize(); uint8_t otaGetRunning(); uint8_t otaGetTarget(); bool otaRollback(); bool otaCanRollback(); - public: /* Inline methods */ - inline uint32_t getFlashChipSize() { - return Flash.getSize(); - } - - // inline bool flashEraseSector(uint32_t sector) {} - // inline bool flashWrite(uint32_t offset, uint32_t *data, size_t size) {} - // inline bool flashRead(uint32_t offset, uint32_t *data, size_t size) {} - // inline bool partitionEraseRange(const esp_partition_t *partition, uint32_t offset, size_t size) {} - // inline bool partitionWrite(const esp_partition_t *partition, uint32_t offset, uint32_t *data, size_t size) {} - // inline bool partitionRead(const esp_partition_t *partition, uint32_t offset, uint32_t *data, size_t size) {} - public: /* Family-defined methods */ /** * @brief Reboot the CPU. @@ -64,6 +60,7 @@ class LibreTuya { const char *getChipModel(); /** * @brief Get CPU unique ID. This may be based on MAC, eFuse, etc. + * Note: the number should be 24-bit (with most significant byte being zero). */ uint32_t getChipId(); /** @@ -83,6 +80,12 @@ class LibreTuya { */ uint32_t getCycleCount(); + public: /* Flash memory utilities */ + /** + * @brief Read flash chip ID and return a FlashId struct. + */ + FlashId getFlashChipId(); + public: /* Memory management */ /** * @brief Get total RAM size. diff --git a/arduino/libretuya/libraries/Flash/Flash.cpp b/arduino/libretuya/libraries/Flash/Flash.cpp new file mode 100644 index 0000000..f3dc2f9 --- /dev/null +++ b/arduino/libretuya/libraries/Flash/Flash.cpp @@ -0,0 +1,30 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ + +#include "Flash.h" + +extern "C" { +#include +} + +// Global Flash object. +FlashClass Flash; + +FlashId FlashClass::getChipId() { + return LT.getFlashChipId(); +} + +uint32_t FlashClass::getSize() { + return LT.getFlashChipSize(); +} + +bool FlashClass::eraseSector(uint32_t offset) { + return fal_partition_erase(fal_root_part, offset, 1) >= 0; +} + +bool FlashClass::readBlock(uint32_t offset, uint8_t *data, size_t size) { + return fal_partition_read(fal_root_part, offset, data, size) >= 0; +} + +bool FlashClass::writeBlock(uint32_t offset, uint8_t *data, size_t size) { + return fal_partition_write(fal_root_part, offset, data, size) >= 0; +} diff --git a/arduino/realtek-ambz/libraries/Flash/Flash.h b/arduino/libretuya/libraries/Flash/Flash.h similarity index 61% rename from arduino/realtek-ambz/libraries/Flash/Flash.h rename to arduino/libretuya/libraries/Flash/Flash.h index cf00727..7e23a02 100644 --- a/arduino/realtek-ambz/libraries/Flash/Flash.h +++ b/arduino/libretuya/libraries/Flash/Flash.h @@ -2,20 +2,10 @@ #pragma once -#include "api/Flash.h" - -struct flash_s; -typedef struct flash_s flash_t; - -class FlashClass : public IFlashClass { - private: - flash_t *flash; - void initialize(); +#include +class FlashClass { public: - FlashClass(); - ~FlashClass(); - FlashId getChipId(); uint32_t getSize(); diff --git a/arduino/libretuya/port/flashdb/fal_cfg.h b/arduino/libretuya/port/flashdb/fal_cfg.h index 61836ce..cf0f478 100644 --- a/arduino/libretuya/port/flashdb/fal_cfg.h +++ b/arduino/libretuya/port/flashdb/fal_cfg.h @@ -2,8 +2,6 @@ #pragma once -#include - // Flash device configuration extern const struct fal_flash_dev flash0; @@ -26,6 +24,9 @@ extern const struct fal_flash_dev flash0; .len = FLASH_##part_upper##_LENGTH, /* partition length macro as uppercase string */ \ }, +// for fal_partition_t +#include + /** * @brief Root partition table, representing the entire flash. */ diff --git a/arduino/realtek-ambz/cores/arduino/LibreTuyaAPI.cpp b/arduino/realtek-ambz/cores/arduino/LibreTuyaAPI.cpp index acf964c..517bbe1 100644 --- a/arduino/realtek-ambz/cores/arduino/LibreTuyaAPI.cpp +++ b/arduino/realtek-ambz/cores/arduino/LibreTuyaAPI.cpp @@ -57,6 +57,18 @@ uint32_t LibreTuya::getCycleCount() { return microsecondsToClockCycles(micros()); } +/* Flash memory utilities */ + +FlashId LibreTuya::getFlashChipId() { + FlashId id; + uint8_t idBytes[3]; + flash_read_id(NULL, idBytes, 3); + id.manufacturerId = idBytes[0]; + id.chipId = idBytes[1]; + id.chipSizeId = idBytes[2]; + return id; +} + /* Memory management */ uint32_t LibreTuya::getRamSize() { diff --git a/arduino/realtek-ambz/libraries/Flash/Flash.cpp b/arduino/realtek-ambz/libraries/Flash/Flash.cpp deleted file mode 100644 index 44520a4..0000000 --- a/arduino/realtek-ambz/libraries/Flash/Flash.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ - -#include "Flash.h" - -#include - -extern "C" { -#include -} - -// Global Flash object. -FlashClass Flash; - -FlashClass::FlashClass() { - flash = NULL; -} - -FlashClass::~FlashClass() { - if (!flash) - return; - free(flash); - flash = NULL; -} - -void FlashClass::initialize() { - if (flash) - return; - flash = (flash_t *)malloc(sizeof(flash_t)); - flash_get_status(flash); -} - -FlashId FlashClass::getChipId() { - initialize(); - FlashId id; - uint8_t idBytes[3]; - flash_read_id(flash, idBytes, 3); - id.manufacturerId = idBytes[0]; - id.chipId = idBytes[1]; - id.chipSizeId = idBytes[2]; - return id; -} - -uint32_t FlashClass::getSize() { - initialize(); - FlashId id = getChipId(); - if (id.chipSizeId >= 0x14 && id.chipSizeId <= 0x19) { - return (1 << id.chipSizeId); - } - return 1024 * 1024; -} - -bool FlashClass::eraseSector(uint32_t offset) { - initialize(); - flash_erase_sector(flash, offset); - return true; -} - -bool FlashClass::readBlock(uint32_t offset, uint8_t *data, size_t size) { - initialize(); - return flash_stream_read(flash, offset, size, data); -} - -bool FlashClass::writeBlock(uint32_t offset, uint8_t *data, size_t size) { - initialize(); - return flash_stream_write(flash, offset, size, data); -} diff --git a/arduino/realtek-ambz/port/flashdb/fal_flash_ambz_port.c b/arduino/realtek-ambz/port/flashdb/fal_flash_ambz_port.c index 1e8f98b..79b25c3 100644 --- a/arduino/realtek-ambz/port/flashdb/fal_flash_ambz_port.c +++ b/arduino/realtek-ambz/port/flashdb/fal_flash_ambz_port.c @@ -5,6 +5,11 @@ #define FLASH_ERASE_MIN_SIZE (4 * 1024) +static int init() { + flash_get_status(NULL); + return 0; +} + static int read(long offset, uint8_t *buf, size_t size) { return size * flash_stream_read(NULL, offset, size, buf); } @@ -26,6 +31,6 @@ const struct fal_flash_dev flash0 = { .addr = 0x0, .len = FLASH_LENGTH, .blk_size = FLASH_ERASE_MIN_SIZE, - .ops = {NULL, read, write, erase}, + .ops = {init, read, write, erase}, .write_gran = 1, };