From 1259f8d776a49f5daf1dbb3aff0c3643e377e8e0 Mon Sep 17 00:00:00 2001 From: Bernd Meyer Date: Tue, 4 Aug 2015 12:59:59 +1000 Subject: [PATCH] Deal with unaligned destination parameter to flash read (Occurs e.g. when SPIFFS cache is disabled.) Implementation mirrors the existing handling in the write path. --- app/platform/common.c | 2 +- app/platform/platform.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/platform/common.c b/app/platform/common.c index 711a8a4a..617f6831 100644 --- a/app/platform/common.c +++ b/app/platform/common.c @@ -220,7 +220,7 @@ uint32_t platform_flash_read( void *to, uint32_t fromaddr, uint32_t size ) #else // #ifindef INTERNAL_FLASH_READ_UNIT_SIZE uint32_t temp, rest, ssize = size; unsigned i; - char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ]; + char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); uint8_t *pto = ( uint8_t* )to; const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE; const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1; diff --git a/app/platform/platform.c b/app/platform/platform.c index 40aa50ad..6ed88d18 100644 --- a/app/platform/platform.c +++ b/app/platform/platform.c @@ -460,6 +460,11 @@ spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data ) // **************************************************************************** // Flash access functions +/* + * Assumptions: + * > toaddr is INTERNAL_FLASH_WRITE_UNIT_SIZE aligned + * > size is a multiple of INTERNAL_FLASH_WRITE_UNIT_SIZE + */ uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t size ) { toaddr -= INTERNAL_FLASH_START_ADDRESS; @@ -484,12 +489,37 @@ uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t siz } } +/* + * Assumptions: + * > fromaddr is INTERNAL_FLASH_READ_UNIT_SIZE aligned + * > size is a multiple of INTERNAL_FLASH_READ_UNIT_SIZE + */ uint32_t platform_s_flash_read( void *to, uint32_t fromaddr, uint32_t size ) { + if (size==0) + return 0; + fromaddr -= INTERNAL_FLASH_START_ADDRESS; SpiFlashOpResult r; WRITE_PERI_REG(0x60000914, 0x73); - r = flash_read(fromaddr, (uint32 *)to, size); + + const uint32_t blkmask = (INTERNAL_FLASH_READ_UNIT_SIZE - 1); + if( ((uint32_t)to) & blkmask ) + { + uint32_t size2=size-INTERNAL_FLASH_READ_UNIT_SIZE; + uint32* to2=(uint32*)((((uint32_t)to)&(~blkmask))+INTERNAL_FLASH_READ_UNIT_SIZE); + r = flash_read(fromaddr, to2, size2); + if(SPI_FLASH_RESULT_OK == r) + { + os_memmove(to,to2,size2); + char back[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); + r=flash_read(fromaddr+size2,(uint32*)back,INTERNAL_FLASH_READ_UNIT_SIZE); + os_memcpy((uint8_t*)to+size2,back,INTERNAL_FLASH_READ_UNIT_SIZE); + } + } + else + r = flash_read(fromaddr, (uint32 *)to, size); + if(SPI_FLASH_RESULT_OK == r) return size; else{