@@ -364,52 +364,66 @@ void hal_init(void)
364364 */
365365int RAMFUNCTION hal_flash_write (uint32_t address , const uint8_t * data , int size )
366366{
367- /* base address of containing sector (TODO what if size spans sectors?)
368- */
369- const uint32_t sectorAddress = GET_SECTOR_ADDR ( address ) ;
370- const IfxFlash_FlashType type = getFlashTypeFromAddr ( address ) ;
367+ const IfxFlash_FlashType type = getFlashTypeFromAddr ( address );
368+ uint32_t currentAddress = address ;
369+ int remainingSize = size ;
370+ int bytesWrittenTotal = 0 ;
371371
372- /* Determine the range of pages affected */
373- const uint32_t startPage = GET_PAGE_ADDR (address );
374- const uint32_t endPage = GET_PAGE_ADDR (address + size - 1 );
375- uint32_t page ;
372+ LED_ON (LED_PROG );
376373
377- /* Flag to check if sector read-modify-write is necessary */
378- int needsSectorRmw ;
374+ /* Process the data sector by sector */
375+ while (remainingSize > 0 ) {
376+ uint32_t currentSectorAddress = GET_SECTOR_ADDR (currentAddress );
377+ uint32_t offsetInSector = currentAddress - currentSectorAddress ;
378+ uint32_t bytesInThisSector = WOLFBOOT_SECTOR_SIZE - offsetInSector ;
379379
380- LED_ON (LED_PROG );
380+ /* Adjust bytes to write if this would overflow the current sector */
381+ if (bytesInThisSector > remainingSize ) {
382+ bytesInThisSector = remainingSize ;
383+ }
381384
382- /* Check if any page within the range is not erased */
383- needsSectorRmw = 0 ;
384- for (page = startPage ; page <= endPage ;
385- page += IFXFLASH_PFLASH_PAGE_LENGTH ) {
386- if (!flashIsErased (page , IFXFLASH_PFLASH_PAGE_LENGTH , type )) {
387- needsSectorRmw = 1 ;
388- break ;
385+ /* Determine the range of pages affected in this sector */
386+ const uint32_t startPage = GET_PAGE_ADDR (currentAddress );
387+ const uint32_t endPage =
388+ GET_PAGE_ADDR (currentAddress + bytesInThisSector - 1 );
389+ uint32_t page ;
390+ int needsSectorRmw = 0 ;
391+
392+ /* Check if any page within the range is not erased */
393+ for (page = startPage ; page <= endPage ;
394+ page += IFXFLASH_PFLASH_PAGE_LENGTH ) {
395+ if (!flashIsErased (page , IFXFLASH_PFLASH_PAGE_LENGTH , type )) {
396+ needsSectorRmw = 1 ;
397+ break ;
398+ }
389399 }
390- }
391400
392- /* If a page within the range is erased, we need to read-modify-write the
393- * whole sector */
394- if (needsSectorRmw ) {
395- size_t offsetInSector ;
401+ /* If a page within the range is not erased, we need to
402+ * read-modify-write the sector */
403+ if (needsSectorRmw ) {
404+ /* Read entire sector into RAM */
405+ cacheSector (currentSectorAddress , type );
396406
397- /* Read entire sector into RAM */
398- cacheSector ( sectorAddress , type );
407+ /* Erase the entire sector */
408+ hal_flash_erase ( currentSectorAddress , WOLFBOOT_SECTOR_SIZE );
399409
400- /* Erase the entire sector */
401- hal_flash_erase (sectorAddress , WOLFBOOT_SECTOR_SIZE );
410+ /* Modify the relevant part of the RAM sector buffer */
411+ memcpy ((uint8_t * )sectorBuffer + offsetInSector ,
412+ data + bytesWrittenTotal , bytesInThisSector );
402413
403- /* Modify the relevant part of the RAM sector buffer */
404- offsetInSector = address - sectorAddress ;
405- memcpy ((uint8_t * )sectorBuffer + offsetInSector , data , size );
414+ /* Program the modified sector back into flash */
415+ programCachedSector (currentSectorAddress , type );
416+ }
417+ else {
418+ /* All affected pages are erased, program the data directly */
419+ programBytesToErasedFlash (currentAddress , data + bytesWrittenTotal ,
420+ bytesInThisSector , type );
421+ }
406422
407- /* Program the modified sector back into flash */
408- programCachedSector (sectorAddress , type );
409- }
410- else {
411- /* All affected pages are erased, program the data directly */
412- programBytesToErasedFlash (address , data , size , type );
423+ /* Update pointers and counters */
424+ bytesWrittenTotal += bytesInThisSector ;
425+ currentAddress += bytesInThisSector ;
426+ remainingSize -= bytesInThisSector ;
413427 }
414428
415429 LED_OFF (LED_PROG );
0 commit comments