mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #12035 from gschorcht/cpu/esp32/fix_periph_flash
cpu/esp32: fix and improve periph/flash
This commit is contained in:
commit
52bf448a3b
@ -20,16 +20,12 @@
|
|||||||
|
|
||||||
#if MODULE_MTD
|
#if MODULE_MTD
|
||||||
|
|
||||||
#define ENABLE_DEBUG (0)
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "esp_common.h"
|
#include "esp_common.h"
|
||||||
#include "irq_arch.h"
|
#include "irq_arch.h"
|
||||||
#include "log.h"
|
|
||||||
#include "mtd.h"
|
#include "mtd.h"
|
||||||
|
|
||||||
#include "rom/cache.h"
|
#include "rom/cache.h"
|
||||||
@ -38,6 +34,9 @@
|
|||||||
#include "esp_partition.h"
|
#include "esp_partition.h"
|
||||||
#include "esp_spi_flash.h"
|
#include "esp_spi_flash.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#define ESP_PART_TABLE_ADDR 0x8000 /* TODO configurable as used in Makefile.include */
|
#define ESP_PART_TABLE_ADDR 0x8000 /* TODO configurable as used in Makefile.include */
|
||||||
#define ESP_PART_TABLE_SIZE 0xC00
|
#define ESP_PART_TABLE_SIZE 0xC00
|
||||||
#define ESP_PART_ENTRY_SIZE 0x20
|
#define ESP_PART_ENTRY_SIZE 0x20
|
||||||
@ -169,9 +168,6 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
|
|||||||
/* size must be within the flash address space */
|
/* size must be within the flash address space */
|
||||||
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
||||||
|
|
||||||
/* prepare for write access */
|
|
||||||
critical_enter();
|
|
||||||
Cache_Read_Disable(PRO_CPU_NUM);
|
|
||||||
int result = ESP_ROM_SPIFLASH_RESULT_OK;
|
int result = ESP_ROM_SPIFLASH_RESULT_OK;
|
||||||
uint32_t len = size;
|
uint32_t len = size;
|
||||||
|
|
||||||
@ -182,9 +178,17 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
|
|||||||
uint32_t len_in_word = 4 - pos_in_word;
|
uint32_t len_in_word = 4 - pos_in_word;
|
||||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
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, (uint32_t*)_flash_buf, 4);
|
result = esp_rom_spiflash_read (word_addr, (uint32_t*)_flash_buf, 4);
|
||||||
memcpy(buff, _flash_buf + pos_in_word, len_in_word);
|
memcpy(buff, _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;
|
buff = (uint8_t*)buff + len_in_word;
|
||||||
addr += len_in_word;
|
addr += len_in_word;
|
||||||
len -= len_in_word;
|
len -= len_in_word;
|
||||||
@ -198,9 +202,17 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
|
|||||||
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, (uint32_t*)_flash_buf, len_full_words);
|
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, len_full_words);
|
||||||
memcpy(buff, _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;
|
buff = (uint8_t*)buff + len_full_words;
|
||||||
addr += len_full_words;
|
addr += len_full_words;
|
||||||
len -= len_full_words;
|
len -= len_full_words;
|
||||||
@ -208,13 +220,17 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
|
|||||||
|
|
||||||
/* if there is some remaining, we need to prepare last word */
|
/* if there is some remaining, we need to prepare last word */
|
||||||
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
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, (uint32_t*)_flash_buf, 4);
|
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, 4);
|
||||||
memcpy(buff, _flash_buf, len);
|
memcpy(buff, _flash_buf, len);
|
||||||
}
|
|
||||||
|
|
||||||
/* reset read access */
|
/* enable interrupts and the cache */
|
||||||
Cache_Read_Enable(PRO_CPU_NUM);
|
Cache_Read_Enable(PRO_CPU_NUM);
|
||||||
critical_exit();
|
critical_exit();
|
||||||
|
}
|
||||||
|
|
||||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||||
RETURN_WITH_ESP_ERR_CODE(result);
|
RETURN_WITH_ESP_ERR_CODE(result);
|
||||||
@ -230,8 +246,6 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
|
|||||||
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
||||||
|
|
||||||
/* prepare for write access */
|
/* prepare for write access */
|
||||||
critical_enter();
|
|
||||||
Cache_Read_Disable(PRO_CPU_NUM);
|
|
||||||
int result = esp_rom_spiflash_unlock();
|
int result = esp_rom_spiflash_unlock();
|
||||||
uint32_t len = size;
|
uint32_t len = size;
|
||||||
|
|
||||||
@ -242,10 +256,18 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
|
|||||||
uint32_t len_in_word = 4 - pos_in_word;
|
uint32_t len_in_word = 4 - pos_in_word;
|
||||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
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, (uint32_t*)_flash_buf, 4);
|
result |= esp_rom_spiflash_read (word_addr, (uint32_t*)_flash_buf, 4);
|
||||||
memcpy(_flash_buf + pos_in_word, buff, len_in_word);
|
memcpy(_flash_buf + pos_in_word, buff, len_in_word);
|
||||||
result |= esp_rom_spiflash_write (word_addr, (uint32_t*)_flash_buf, 4);
|
result |= esp_rom_spiflash_write (word_addr, (uint32_t*)_flash_buf, 4);
|
||||||
|
|
||||||
|
/* enable interrupts and the cache */
|
||||||
|
Cache_Read_Enable(PRO_CPU_NUM);
|
||||||
|
critical_exit();
|
||||||
|
|
||||||
buff = (uint8_t*)buff + len_in_word;
|
buff = (uint8_t*)buff + len_in_word;
|
||||||
addr += len_in_word;
|
addr += len_in_word;
|
||||||
len -= len_in_word;
|
len -= len_in_word;
|
||||||
@ -259,9 +281,17 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
|
|||||||
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);
|
memcpy(_flash_buf, buff, len_full_words);
|
||||||
result |= esp_rom_spiflash_write (addr, (uint32_t*)_flash_buf, len_full_words);
|
result |= esp_rom_spiflash_write (addr, (uint32_t*)_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;
|
buff = (uint8_t*)buff + len_full_words;
|
||||||
addr += len_full_words;
|
addr += len_full_words;
|
||||||
len -= len_full_words;
|
len -= len_full_words;
|
||||||
@ -269,15 +299,21 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
|
|||||||
|
|
||||||
/* if there is some remaining, we need to prepare last word */
|
/* if there is some remaining, we need to prepare last word */
|
||||||
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
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, (uint32_t*)_flash_buf, 4);
|
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, 4);
|
||||||
memcpy(_flash_buf, buff, len);
|
memcpy(_flash_buf, buff, len);
|
||||||
result |= esp_rom_spiflash_write (addr, (uint32_t*)_flash_buf, 4);
|
result |= esp_rom_spiflash_write (addr, (uint32_t*)_flash_buf, 4);
|
||||||
|
|
||||||
|
/* enable interrupts and the cache */
|
||||||
|
Cache_Read_Enable(PRO_CPU_NUM);
|
||||||
|
critical_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset write access */
|
/* reset write access */
|
||||||
esp_rom_spiflash_lock();
|
esp_rom_spiflash_lock();
|
||||||
Cache_Read_Enable(PRO_CPU_NUM);
|
|
||||||
critical_exit();
|
|
||||||
|
|
||||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||||
RETURN_WITH_ESP_ERR_CODE(result);
|
RETURN_WITH_ESP_ERR_CODE(result);
|
||||||
@ -298,21 +334,36 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t addr, size_t size)
|
|||||||
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -ENOTSUP)
|
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -ENOTSUP)
|
||||||
|
|
||||||
/* prepare for write access */
|
/* prepare for write access */
|
||||||
critical_enter();
|
|
||||||
Cache_Read_Disable(PRO_CPU_NUM);
|
|
||||||
uint32_t result = esp_rom_spiflash_unlock();
|
uint32_t result = esp_rom_spiflash_unlock();
|
||||||
|
|
||||||
/* erase as many sectors as necessary */
|
/* erase as many sectors as necessary */
|
||||||
uint32_t sec = addr / _flashchip->sector_size;
|
uint32_t sec = addr / _flashchip->sector_size;
|
||||||
uint32_t cnt = size / _flashchip->sector_size;
|
uint32_t cnt = size / _flashchip->sector_size;
|
||||||
while (cnt-- && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
uint32_t sec_per_block = _flashchip->block_size / _flashchip->sector_size;
|
||||||
result = esp_rom_spiflash_erase_sector (sec++);
|
|
||||||
|
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 */
|
/* reset write access */
|
||||||
esp_rom_spiflash_lock();
|
esp_rom_spiflash_lock();
|
||||||
Cache_Read_Enable(PRO_CPU_NUM);
|
|
||||||
critical_exit();
|
|
||||||
|
|
||||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||||
RETURN_WITH_ESP_ERR_CODE(result);
|
RETURN_WITH_ESP_ERR_CODE(result);
|
||||||
@ -406,7 +457,11 @@ static int _flash_write (mtd_dev_t *dev, const void *buff, uint32_t addr, uint32
|
|||||||
/* size must be within the flash address space */
|
/* size must be within the flash address space */
|
||||||
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
||||||
|
|
||||||
return (spi_flash_write(_flash_beg + addr, buff, size) == ESP_OK) ?(int)size : -EIO;
|
/* addr + size must be within a page */
|
||||||
|
CHECK_PARAM_RET (size <= _flashchip->page_size, -EOVERFLOW);
|
||||||
|
CHECK_PARAM_RET ((addr % _flashchip->page_size) + size <= _flashchip->page_size, -EOVERFLOW);
|
||||||
|
|
||||||
|
return (spi_flash_write(_flash_beg + addr, buff, size) == ESP_OK) ? (int)size : -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _flash_erase (mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
static int _flash_erase (mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
||||||
@ -419,8 +474,8 @@ static int _flash_erase (mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
|||||||
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
||||||
|
|
||||||
/* size must be a multiple of sector_size && at least one sector */
|
/* 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, -EOVERFLOW);
|
||||||
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -ENOTSUP)
|
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -EOVERFLOW)
|
||||||
|
|
||||||
return (spi_flash_erase_range(_flash_beg + addr, size) == ESP_OK) ? 0 : -EIO;
|
return (spi_flash_erase_range(_flash_beg + addr, size) == ESP_OK) ? 0 : -EIO;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user