Reverse engineered some spi_flash functions
This commit is contained in:
		
							parent
							
								
									ab795350fb
								
							
						
					
					
						commit
						33b63d46a5
					
				
					 1 changed files with 149 additions and 8 deletions
				
			
		|  | @ -9,6 +9,9 @@ | |||
| #include "spiffs.h" | ||||
| #include <espressif/spi_flash.h> | ||||
| #include <stdbool.h> | ||||
| #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; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue