[core] Migrate Flash library to common code based on FAL

This commit is contained in:
Kuba Szczodrzyński
2022-06-19 16:33:15 +02:00
parent 272b033253
commit 2fedcb61b5
10 changed files with 87 additions and 122 deletions

View File

@@ -1,27 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
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;
};

View File

@@ -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 <Arduino.h>
// C includes

View File

@@ -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;
/**

View File

@@ -7,7 +7,14 @@
#include "LibreTuyaAPI.h"
#include <core/ChipType.h>
#include <Flash.h> // 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.

View File

@@ -0,0 +1,30 @@
/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */
#include "Flash.h"
extern "C" {
#include <fal.h>
}
// 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;
}

View File

@@ -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 <Arduino.h>
class FlashClass {
public:
FlashClass();
~FlashClass();
FlashId getChipId();
uint32_t getSize();

View File

@@ -2,8 +2,6 @@
#pragma once
#include <fal_def.h>
// 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 <fal_def.h>
/**
* @brief Root partition table, representing the entire flash.
*/

View File

@@ -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() {

View File

@@ -1,66 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */
#include "Flash.h"
#include <Arduino.h>
extern "C" {
#include <flash_api.h>
}
// 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);
}

View File

@@ -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,
};