Skip to content

Commit 21a726a

Browse files
bigbrettdanielinux
authored andcommitted
fix tc3xx HAL to properly handle flash writes across sector boundariese
1 parent 8ae5ec2 commit 21a726a

File tree

1 file changed

+50
-36
lines changed

1 file changed

+50
-36
lines changed

hal/aurix_tc3xx.c

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -364,52 +364,66 @@ void hal_init(void)
364364
*/
365365
int 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

Comments
 (0)