diff --git a/extras/spiffs/esp_spiffs.c b/extras/spiffs/esp_spiffs.c index d6ec7d6..a2c1dd1 100644 --- a/extras/spiffs/esp_spiffs.c +++ b/extras/spiffs/esp_spiffs.c @@ -9,6 +9,9 @@ #include "spiffs.h" #include #include +#include "common_macros.h" +#include "FreeRTOS.h" +#include "esp/rom.h" spiffs fs; @@ -16,6 +19,144 @@ static void *work_buf = 0; static void *fds_buf = 0; static void *cache_buf = 0; + +// ROM functions +uint32_t SPI_read_data(sdk_flashchip_t *p, uint32_t dest_addr, void *src, + uint32_t size); +uint32_t SPI_page_program(sdk_flashchip_t *p, uint32_t dest_addr, void *dst, + uint32_t size); +uint32_t SPI_write_enable(sdk_flashchip_t *p); +uint32_t SPI_sector_erase(sdk_flashchip_t *p, uint32_t sector_addr); + + +/** + * Reverse engineered implementation of spi_flash.o:sdk_SPIRead + */ +uint32_t IRAM spi_read(uint32_t dest_addr, void *src, uint32_t size) +{ + if (SPI_read_data(&sdk_flashchip, dest_addr, src, size)) { + return 1; + } else { + return 0; + } +} + +/** + * Reverse engineered implementation of spi_flash.o:sdk_spi_flash_read + */ +uint32_t IRAM spi_flash_read(uint32_t dest_addr, void *src, uint32_t size) +{ + if (src) { + vPortEnterCritical(); + Cache_Read_Disable(); + uint32_t result = spi_read(dest_addr, src, size); + Cache_Read_Enable(0, 0, 1); + vPortExitCritical(); + return result; + } else { + return 1; + } +} + +/** + * Reverse engineered implementation of spi_flash.o:sdk_SPIWrite + */ +uint32_t IRAM spi_write(uint32_t dest_addr, void *dst, uint32_t size) +{ + if (sdk_flashchip.chip_size < (dest_addr + size)) { + return 1; + } + + uint32_t write_bytes_to_page = sdk_flashchip.page_size - + (dest_addr % sdk_flashchip.page_size); + + if (size < write_bytes_to_page) { + if (SPI_page_program(&sdk_flashchip, dest_addr, dst, size)) { + return 1; + } else { + return 0; + } + } + + if (SPI_page_program(&sdk_flashchip, dest_addr, dst, write_bytes_to_page)) { + return 1; + } + + uint32_t offset = write_bytes_to_page; + uint32_t pages_to_write = (size - offset) / sdk_flashchip.page_size; + for (uint8_t i = 0; i != pages_to_write; i++) { + if (SPI_page_program(&sdk_flashchip, dest_addr + offset, + dst + ((offset>>2)<<2), sdk_flashchip.page_size)) { + return 1; + } + offset += sdk_flashchip.page_size; + } + + if (SPI_page_program(&sdk_flashchip, dest_addr + offset, + dst + ((offset>>2)<<2), size - offset)) { + return 1; + } else { + return 0; + } +} + +/** + * Reverse engineered implementation of spi_flash.o:sdk_spi_flash_write + */ +uint32_t IRAM spi_flash_write(uint32_t dest_addr, void *dst, uint32_t size) +{ + if (dst) { + if (size & 0b11) { // not 4-byte aligned + size = size >> 2; + size = (size << 2) + 1; + } + vPortEnterCritical(); + Cache_Read_Disable(); + uint32_t result = spi_write(dest_addr, dst, size); + Cache_Read_Enable(0, 0, 1); + vPortExitCritical(); + return result; + } else { + return 1; + } +} + +/** + * Reverse engineered implementation of spi_flash.o:sdk_SPIEraseSector + */ +uint32_t IRAM spi_erase_sector(uint32_t sector) +{ + if (sector >= (sdk_flashchip.chip_size / sdk_flashchip.sector_size)) { + return 1; + } + + if (SPI_write_enable(&sdk_flashchip)) { + return 1; + } + + if (SPI_sector_erase(&sdk_flashchip, sdk_flashchip.sector_size * sector)) { + return 1; + } + return 0; +} + +/** + * Reverse engineered implementation of spi_flash.o:sdk_spi_flash_erase_sector + */ +uint32_t IRAM spi_flash_erase_sector(uint32_t sector) +{ + vPortEnterCritical(); + Cache_Read_Disable(); + + uint32_t result = spi_erase_sector(sector); + + Cache_Read_Enable(0, 0, 1); + vPortExitCritical(); + + return result; +} + + /* * Flash addresses and size alignment is a rip-off of Arduino implementation. */ @@ -32,7 +173,7 @@ static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) if (addr < alignedBegin) { uint32_t nb = alignedBegin - addr; uint32_t tmp; - if (sdk_spi_flash_read(alignedEnd - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) { + if (spi_flash_read(alignedEnd - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) { printf("spi_flash_read failed\n"); return SPIFFS_ERR_INTERNAL; } @@ -40,7 +181,7 @@ static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) } if (alignedEnd != alignedBegin) { - if (sdk_spi_flash_read(alignedBegin, + if (spi_flash_read(alignedBegin, (uint32_t*) (dst + alignedBegin - addr), alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) { printf("spi_flash_read failed\n"); @@ -51,7 +192,7 @@ static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) if (addr + size > alignedEnd) { uint32_t nb = addr + size - alignedEnd; uint32_t tmp; - if (sdk_spi_flash_read(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { + if (spi_flash_read(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { printf("spi_flash_read failed\n"); return SPIFFS_ERR_INTERNAL; } @@ -77,7 +218,7 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) uint32_t nb = (size < ofs) ? size : ofs; uint8_t tmp[4] __attribute__((aligned(4))) = {0xff, 0xff, 0xff, 0xff}; memcpy(tmp + 4 - ofs, src, nb); - if (sdk_spi_flash_write(alignedBegin - 4, (uint32_t*) tmp, 4) + if (spi_flash_write(alignedBegin - 4, (uint32_t*) tmp, 4) != SPI_FLASH_RESULT_OK) { printf("spi_flash_write failed\n"); return SPIFFS_ERR_INTERNAL; @@ -88,7 +229,7 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr); uint32_t srcAlign = ((uint32_t) srcLeftover) & 3; if (!srcAlign) { - if (sdk_spi_flash_write(alignedBegin, (uint32_t*) srcLeftover, + if (spi_flash_write(alignedBegin, (uint32_t*) srcLeftover, alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) { printf("spi_flash_write failed\n"); return SPIFFS_ERR_INTERNAL; @@ -100,7 +241,7 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) size_t willCopy = sizeLeft < sizeof(buf) ? sizeLeft : sizeof(buf); memcpy(buf, srcLeftover, willCopy); - if (sdk_spi_flash_write(alignedBegin, (uint32_t*) buf, willCopy) + if (spi_flash_write(alignedBegin, (uint32_t*) buf, willCopy) != SPI_FLASH_RESULT_OK) { printf("spi_flash_write failed\n"); return SPIFFS_ERR_INTERNAL; @@ -118,7 +259,7 @@ static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) uint32_t tmp = 0xffffffff; memcpy(&tmp, src + size - nb, nb); - if (sdk_spi_flash_write(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { + if (spi_flash_write(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) { printf("spi_flash_write failed\n"); return SPIFFS_ERR_INTERNAL; } @@ -140,7 +281,7 @@ static s32_t esp_spiffs_erase(u32_t addr, u32_t size) const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE; for (uint32_t i = 0; i < sectorCount; ++i) { - sdk_spi_flash_erase_sector(sector + i); + spi_flash_erase_sector(sector + i); } return SPIFFS_OK; }