more idf5.1 preps: Berry SPI (#19273)

This commit is contained in:
Christian Baars 2023-08-06 21:10:36 +02:00 committed by GitHub
parent 7488ed03f0
commit 76aa6747a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -24,52 +24,60 @@
#include "esp_idf_version.h"
#if ESP_IDF_VERSION_MAJOR >= 5
// esp_spi_flash.h is deprecated, please use spi_flash_mmap.h instead
#include "spi_flash_mmap.h"
#include "esp_flash.h"
#else
#include "esp_spi_flash.h"
#endif
size_t FlashWriteSubSector(uint32_t address_start, const uint8_t *data, size_t size) {
#if ESP_IDF_VERSION_MAJOR < 5
uint32_t addr = address_start;
size_t size_left = size;
size_t current_offset = 0;
esp_err_t ret;
// Memory is unaligned, so we need to copy it to an aligned buffer
uint8_t buffer[SPI_FLASH_SEC_SIZE] __attribute__((aligned(4)));
uint32_t addr = address_start;
size_t size_left = size;
size_t current_offset = 0;
esp_err_t ret;
// Memory is unaligned, so we need to copy it to an aligned buffer
uint8_t buffer[SPI_FLASH_SEC_SIZE] __attribute__((aligned(4)));
while (size_left) {
uint32_t page_addr = addr & ~(SPI_FLASH_SEC_SIZE - 1);
uint32_t addr_in_page = addr & (SPI_FLASH_SEC_SIZE - 1);
uint32_t size_in_page = size_left;
if (addr_in_page + size_in_page > SPI_FLASH_SEC_SIZE) {
size_in_page = SPI_FLASH_SEC_SIZE - addr_in_page;
}
// AddLog(LOG_LEVEL_DEBUG, ">>>: flash_write addr=%p size=%i -- page_addr=%p addr_in_page=%p size_in_page=%i size_left=%i", address_start, size, page_addr, addr_in_page, size_in_page, size_left);
// check if whole page?
if (addr_in_page == 0 && size_in_page == SPI_FLASH_SEC_SIZE) {
memcpy(buffer, data + current_offset, SPI_FLASH_SEC_SIZE);
} else {
ret = spi_flash_read(page_addr, buffer, SPI_FLASH_SEC_SIZE);
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not read flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; }
memcpy(buffer + addr_in_page, data + current_offset, size_in_page);
}
ret = spi_flash_erase_sector(page_addr / SPI_FLASH_SEC_SIZE);
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not erase flash sector 0x%X ret=%i", page_addr / SPI_FLASH_SEC_SIZE, ret); return 0; }
spi_flash_write(page_addr, buffer, SPI_FLASH_SEC_SIZE);
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not write flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; }
addr += size_in_page;
current_offset += size_in_page;
size_left -= size_in_page;
while (size_left) {
uint32_t page_addr = addr & ~(SPI_FLASH_SEC_SIZE - 1);
uint32_t addr_in_page = addr & (SPI_FLASH_SEC_SIZE - 1);
uint32_t size_in_page = size_left;
if (addr_in_page + size_in_page > SPI_FLASH_SEC_SIZE) {
size_in_page = SPI_FLASH_SEC_SIZE - addr_in_page;
}
return current_offset;
// AddLog(LOG_LEVEL_DEBUG, ">>>: flash_write addr=%p size=%i -- page_addr=%p addr_in_page=%p size_in_page=%i size_left=%i", address_start, size, page_addr, addr_in_page, size_in_page, size_left);
// check if whole page?
if (addr_in_page == 0 && size_in_page == SPI_FLASH_SEC_SIZE) {
memcpy(buffer, data + current_offset, SPI_FLASH_SEC_SIZE);
} else {
#if ESP_IDF_VERSION_MAJOR < 5
ret = spi_flash_read(page_addr, buffer, SPI_FLASH_SEC_SIZE);
#else
// TODO ESPIDF 5
ret = esp_flash_read(NULL, buffer, page_addr, SPI_FLASH_SEC_SIZE);
#endif
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not read flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; }
memcpy(buffer + addr_in_page, data + current_offset, size_in_page);
}
#if ESP_IDF_VERSION_MAJOR < 5
ret = spi_flash_erase_sector(page_addr / SPI_FLASH_SEC_SIZE);
#else
ret = esp_flash_erase_region(NULL, page_addr, SPI_FLASH_SEC_SIZE);
#endif
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not erase flash sector 0x%X ret=%i", page_addr / SPI_FLASH_SEC_SIZE, ret); return 0; }
#if ESP_IDF_VERSION_MAJOR < 5
spi_flash_write(page_addr, buffer, SPI_FLASH_SEC_SIZE);
#else
esp_flash_write(NULL, buffer, page_addr, SPI_FLASH_SEC_SIZE);
#endif
if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not write flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; }
addr += size_in_page;
current_offset += size_in_page;
size_left -= size_in_page;
}
return current_offset;
}
/*********************************************************************************************\
@ -84,7 +92,6 @@ extern "C" {
// If length is not specified, it is full block 4KB
int32_t p_flash_read(struct bvm *vm);
int32_t p_flash_read(struct bvm *vm) {
#if ESP_IDF_VERSION_MAJOR < 5
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 1 && be_isint(vm, 1) &&
(argc < 2 || be_isint(vm, 2)) ) { // optional second argument must be int
@ -96,14 +103,17 @@ extern "C" {
}
// allocate a buffer in the heap that will be automatically freed when going out of scope
auto buf = std::unique_ptr<uint8_t[]>(new uint8_t[length]);
#if ESP_IDF_VERSION_MAJOR < 5
esp_err_t ret = spi_flash_read(address, buf.get(), length);
#else
esp_err_t ret = esp_flash_read(NULL, buf.get(), address, length);
#endif
if (ret) {
be_raisef(vm, "internal_error", "Error calling spi_flash_read(0x%X, %i)", address, length);
}
be_pushbytes(vm, buf.get(), length);
be_return(vm);
}
#endif
be_raise(vm, kTypeError, nullptr);
}
@ -111,7 +121,6 @@ extern "C" {
// if `no_erase` is true, just call spi_flash_write
int32_t p_flash_write(struct bvm *vm);
int32_t p_flash_write(struct bvm *vm) {
#if ESP_IDF_VERSION_MAJOR < 5
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isint(vm, 1) && be_isinstance(vm, 2)) {
be_getglobal(vm, "bytes"); /* get the bytes class */ /* TODO eventually replace with be_getbuiltin */
@ -125,7 +134,11 @@ extern "C" {
const void * bytes = be_tobytes(vm, 2, &length);
if (bytes && length > 0) {
if (no_erase) {
#if ESP_IDF_VERSION_MAJOR < 5
esp_err_t ret = spi_flash_write(address, (const uint8_t*)bytes, length);
#else
esp_err_t ret = esp_flash_write(NULL, (const uint8_t*)bytes, address, length);
#endif
if (ret) {
be_raisef(vm, "internal_error", "Error calling spi_flash_write() ret=%i", ret);
}
@ -140,7 +153,6 @@ extern "C" {
}
}
}
#endif
be_raise(vm, kTypeError, nullptr);
}
@ -149,7 +161,6 @@ extern "C" {
// Address and length must be 4KB aligned
int32_t p_flash_erase(struct bvm *vm);
int32_t p_flash_erase(struct bvm *vm) {
#if ESP_IDF_VERSION_MAJOR < 5
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isint(vm, 1) && be_isint(vm, 2)) {
int32_t address = be_toint(vm, 1);
@ -160,10 +171,13 @@ extern "C" {
if ((length % 0x1000) != 0 || length < 0) {
be_raise(vm, "value_error", "Length must be a multiple of 0x1000");
}
#if ESP_IDF_VERSION_MAJOR < 5
esp_err_t ret = spi_flash_erase_range(address, length);
#else
esp_err_t ret = esp_flash_erase_region(NULL, address, length);
#endif
be_return_nil(vm);
}
#endif
be_raise(vm, kTypeError, nullptr);
}