1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #18250 from gschorcht/cpu/esp32/remove_spli_flash_funcs

cpu/esp_common: use spli_flash_* funcs from ESP-IDF in periph/flash
This commit is contained in:
benpicco 2022-06-25 19:02:55 +02:00 committed by GitHub
commit 593f8bbe62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 275 deletions

View File

@ -181,6 +181,7 @@ extern "C" {
* SPI Flash driver configuration (DO NOT CHANGE)
*/
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_SPI_FLASH_USE_LEGACY_IMPL 1
/**
* Ethernet driver configuration (DO NOT CHANGE)

View File

@ -6,6 +6,8 @@ ESP32_SDK_SRC = \
components/driver/spi_common.c \
components/spi_flash/$(CPU)/flash_ops_$(CPU).c \
components/spi_flash/$(CPU)/spi_flash_rom_patch.c \
components/spi_flash/esp_flash_api.c \
components/spi_flash/partition.c \
#
ifeq (,$(filter periph_spi,$(USEMODULE)))

View File

@ -33,7 +33,7 @@
#include "esp_partition.h"
#ifdef MCU_ESP32
#ifndef MCU_ESP8266
#include "esp_flash_partitions.h"
#include "esp_spi_flash.h"
@ -41,13 +41,13 @@
#include "rom/spi_flash.h"
#include "soc/soc.h"
#else /* MCU_ESP32 */
#else /* !MCU_ESP8266 */
#include "esp_flash_data_types.h"
#include "rom_functions.h"
#include "spi_flash.h"
#endif /* MCU_ESP32 */
#endif /* !MCU_ESP8266 */
#define ENABLE_DEBUG 0
#include "debug.h"
@ -154,7 +154,7 @@ void spi_flash_drive_init (void)
spi_flash_read (part_addr, (void*)part_buf, ESP_PART_ENTRY_SIZE);
if (part->magic == ESP_PART_ENTRY_MAGIC) {
DEBUG("%s partition @%08x size=%08x label=%s\n", __func__,
DEBUG("%s partition @%08"PRIx32" size=%08"PRIx32" label=%s\n", __func__,
part->pos.offset, part->pos.size, part->label);
if (part->pos.offset + part->pos.size > part_top) {
part_top = part->pos.offset + part->pos.size;
@ -166,13 +166,13 @@ void spi_flash_drive_init (void)
}
}
#ifdef MCU_ESP32
#ifndef MCU_ESP8266
/* map the partition top address to next higher multiple of 0x100000 (1 MB) */
part_top = (part_top + 0x100000) & ~0xfffff;
#else /* MCU_ESP32 */
#else /* !MCU_ESP8266 */
/* map the partition top address to next higher multiple of 0x80000 (512 kB) */
part_top = (part_top + 0x80000) & ~0x7ffff;
#endif /* MCU_ESP32 */
#endif /* !MCU_ESP8266 */
/*
* if flash drive start address is not configured, use the determined
@ -198,8 +198,9 @@ void spi_flash_drive_init (void)
_flash_end = _flashchip->chip_size - 5 * _flashchip->sector_size;
_flash_size = _flash_end - _flash_beg; /* MUST be at least 3 sectors (0x3000) */
LOG_TAG_DEBUG("spi_flash", "MTD in SPI flash starts at address 0x%08x "
"with a size of %d kbytes\n", _flash_beg, _flash_size >> 10);
LOG_TAG_DEBUG("spi_flash", "MTD in SPI flash starts at address "
"0x%08"PRIx32" with a size of %"PRIu32" kbytes\n",
_flash_beg, _flash_size >> 10);
_flash_dev.driver = &_flash_driver;
_flash_dev.sector_count = _flash_size / _flashchip->sector_size;
@ -212,241 +213,17 @@ void spi_flash_drive_init (void)
* performance */
_flash_dev.write_size = 4;
DEBUG("%s flashchip chip_size=%d block_size=%d sector_size=%d page_size=%d\n", __func__,
DEBUG("%s flashchip chip_size=%"PRIu32" block_size=%"PRIu32
" sector_size=%"PRIu32" page_size=%"PRIu32"\n", __func__,
_flashchip->chip_size, _flashchip->block_size,
_flashchip->sector_size, _flashchip->page_size);
DEBUG("%s flash_dev sector_count=%d pages_per_sector=%d page_size=%d\n", __func__,
DEBUG("%s flash_dev sector_count=%"PRIu32" pages_per_sector=%"PRIu32
" page_size=%"PRIu32"\n", __func__,
_flash_dev.sector_count, _flash_dev.pages_per_sector, _flash_dev.page_size);
DEBUG("\n");
}
#ifdef MCU_ESP32
#define RETURN_WITH_ESP_ERR_CODE(err) do { \
switch (err) { \
case ESP_ROM_SPIFLASH_RESULT_OK : return ESP_OK; \
case ESP_ROM_SPIFLASH_RESULT_ERR : return ESP_ERR_FLASH_OP_FAIL; \
case ESP_ROM_SPIFLASH_RESULT_TIMEOUT: return ESP_ERR_FLASH_OP_TIMEOUT; \
} \
return ESP_FAIL; \
} while(0)
static uint32_t _flash_buf[ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM / sizeof(uint32_t)];
esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
{
DEBUG("%s addr=%08x size=%u buf=%p\n", __func__, addr, size, buff);
CHECK_PARAM_RET (buff != NULL, -ENOTSUP);
/* size must be within the flash address space */
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
int result = ESP_ROM_SPIFLASH_RESULT_OK;
uint32_t len = size;
/* if addr is not 4 byte aligned, we need to read the first full word */
if (addr & 0x3) {
uint32_t word_addr = addr & ~0x3;
uint32_t pos_in_word = addr & 0x3;
uint32_t len_in_word = 4 - pos_in_word;
len_in_word = (len_in_word < len) ? len_in_word : len;
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
result = esp_rom_spiflash_read(word_addr, _flash_buf, 4);
memcpy(buff, (uint8_t *)_flash_buf + pos_in_word, len_in_word);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
buff = (uint8_t*)buff + len_in_word;
addr += len_in_word;
len -= len_in_word;
}
/* read all full words, maximum ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM
in one read operation */
while (len > 4 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
uint32_t len_full_words = len & ~0x3;
if (len_full_words > ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
len_full_words = ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
}
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
result |= esp_rom_spiflash_read(addr, _flash_buf, len_full_words);
memcpy(buff, _flash_buf, len_full_words);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
buff = (uint8_t*)buff + len_full_words;
addr += len_full_words;
len -= len_full_words;
}
/* if there is some remaining, we need to prepare last word */
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
result |= esp_rom_spiflash_read(addr, _flash_buf, 4);
memcpy(buff, _flash_buf, len);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
}
/* return with the ESP-IDF error code that is mapped from ROM error code */
RETURN_WITH_ESP_ERR_CODE(result);
}
esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
{
DEBUG("%s addr=%08x size=%u buf=%p\n", __func__, addr, size, buff);
CHECK_PARAM_RET (buff != NULL, -ENOTSUP);
/* size must be within the flash address space */
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
/* prepare for write access */
int result = esp_rom_spiflash_unlock();
uint32_t len = size;
/* if addr is not 4 byte aligned, we need to prepare first full word */
if (addr & 0x3 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
uint32_t word_addr = addr & ~0x3;
uint32_t pos_in_word = addr & 0x3;
uint32_t len_in_word = 4 - pos_in_word;
len_in_word = (len_in_word < len) ? len_in_word : len;
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
result |= esp_rom_spiflash_read(word_addr, _flash_buf, 4);
memcpy((uint8_t *)_flash_buf + pos_in_word, buff, len_in_word);
result |= esp_rom_spiflash_write(word_addr, _flash_buf, 4);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
buff = (uint8_t*)buff + len_in_word;
addr += len_in_word;
len -= len_in_word;
}
/* write all full words, maximum ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM
in one write operation */
while (len > 4 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
uint32_t len_full_words = len & ~0x3;
if (len_full_words > ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM) {
len_full_words = ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM;
}
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
memcpy(_flash_buf, buff, len_full_words);
result |= esp_rom_spiflash_write(addr, _flash_buf, len_full_words);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
buff = (uint8_t*)buff + len_full_words;
addr += len_full_words;
len -= len_full_words;
}
/* if there is some remaining, we need to prepare last word */
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
result |= esp_rom_spiflash_read(addr, _flash_buf, 4);
memcpy(_flash_buf, buff, len);
result |= esp_rom_spiflash_write(addr, _flash_buf, 4);
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
}
/* reset write access */
esp_rom_spiflash_lock();
/* return with the ESP-IDF error code that is mapped from ROM error code */
RETURN_WITH_ESP_ERR_CODE(result);
}
#if !IS_USED(MODULE_ESP_IDF_SPI_FLASH)
esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sector)
{
return spi_flash_erase_range(sector * _flashchip->sector_size, 1);
}
#endif
esp_err_t IRAM_ATTR spi_flash_erase_range(size_t addr, size_t size)
{
/* size must be within the flash address space */
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
/* size must be a multiple of sector_size && at least one sector */
CHECK_PARAM_RET (size >= _flashchip->sector_size, -ENOTSUP);
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -ENOTSUP)
/* prepare for write access */
uint32_t result = esp_rom_spiflash_unlock();
/* erase as many sectors as necessary */
uint32_t sec = addr / _flashchip->sector_size;
uint32_t cnt = size / _flashchip->sector_size;
uint32_t sec_per_block = _flashchip->block_size / _flashchip->sector_size;
while (cnt && result == ESP_ROM_SPIFLASH_RESULT_OK) {
/* disable interrupts and the cache */
critical_enter();
Cache_Read_Disable(PRO_CPU_NUM);
/* erase block-wise (64 kByte) if cnt is at least sec_per_block */
if (cnt >= sec_per_block) {
result = esp_rom_spiflash_erase_block (sec / sec_per_block);
sec += sec_per_block;
cnt -= sec_per_block;
}
else {
result = esp_rom_spiflash_erase_sector (sec++);
cnt--;
}
/* enable interrupts and the cache */
Cache_Read_Enable(PRO_CPU_NUM);
critical_exit();
}
/* reset write access */
esp_rom_spiflash_lock();
/* return with the ESP-IDF error code that is mapped from ROM error code */
RETURN_WITH_ESP_ERR_CODE(result);
}
#endif /* MCU_ESP32 */
#ifdef MCU_ESP8266
const esp_partition_t* esp_partition_find_first(esp_partition_type_t type,
esp_partition_subtype_t subtype,
const char* label)
@ -464,7 +241,7 @@ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type,
spi_flash_read(info_addr, (void*)info_buf, ESP_PART_ENTRY_SIZE);
if (info->magic == ESP_PART_ENTRY_MAGIC) {
DEBUG("%s partition @%08x size=%08x label=%s\n", __func__,
DEBUG("%s partition @%08"PRIx32" size=%08"PRIx32" label=%s\n", __func__,
info->pos.offset, info->pos.size, info->label);
if ((info->type == type) &&
(info->subtype == subtype || subtype == ESP_PARTITION_SUBTYPE_ANY) &&
@ -503,6 +280,7 @@ esp_err_t esp_partition_erase_range(const esp_partition_t* part,
return spi_flash_erase_range(part->address + addr, size);
}
#endif /* MCU_ESP8266 */
static int _flash_init(mtd_dev_t *dev)
{
@ -511,7 +289,7 @@ static int _flash_init (mtd_dev_t *dev)
CHECK_PARAM_RET(dev == &_flash_dev, -ENODEV);
if (_flashchip->chip_size <= _flash_beg) {
LOG_ERROR("Flash size is equal or less than %d Byte, "
LOG_ERROR("Flash size is equal or less than %"PRIu32" Byte, "
"SPIFFS cannot be used\n", _flash_beg);
return -ENODEV;
}
@ -521,7 +299,8 @@ static int _flash_init (mtd_dev_t *dev)
static int _flash_read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size)
{
DEBUG("%s dev=%p addr=%08x size=%u buf=%p\n", __func__, dev, addr, size, buff);
DEBUG("%s dev=%p addr=%08"PRIx32" size=%"PRIu32" buf=%p\n",
__func__, dev, addr, size, buff);
CHECK_PARAM_RET(dev == &_flash_dev, -ENODEV);
CHECK_PARAM_RET(buff != NULL, -ENOTSUP);
@ -534,7 +313,8 @@ static int _flash_read (mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t siz
static int _flash_write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size)
{
DEBUG("%s dev=%p addr=%08x size=%u buf=%p\n", __func__, dev, addr, size, buff);
DEBUG("%s dev=%p addr=%08"PRIx32" size=%"PRIu32" buf=%p\n",
__func__, dev, addr, size, buff);
CHECK_PARAM_RET(dev == &_flash_dev, -ENODEV);
CHECK_PARAM_RET(buff != NULL, -ENOTSUP);
@ -561,7 +341,7 @@ static int _flash_write_page (mtd_dev_t *dev, const void *buff, uint32_t page,
static int _flash_erase(mtd_dev_t *dev, uint32_t addr, uint32_t size)
{
DEBUG("%s dev=%p addr=%08x size=%u\n", __func__, dev, addr, size);
DEBUG("%s dev=%p addr=%08"PRIx32" size=%"PRIu32"\n", __func__, dev, addr, size);
CHECK_PARAM_RET(dev == &_flash_dev, -ENODEV);

View File

@ -5,8 +5,9 @@ FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_spi
# esp8266 vendor code and atwinc15x0 both define conflicting
# esp8266 and esp32 vendor code and atwinc15x0 both define conflicting
# spi_flash_{read, write} functions.
# esp8266 already has build-in WiFi, so it's unlikely to ever
# esp8266 and esp32 already have build-in WiFi, so it's unlikely to ever
# use this driver - just blacklist the architecture.
FEATURES_BLACKLIST += arch_esp8266
FEATURES_BLACKLIST += arch_esp32