/**************************************************************************//** \brief Performs exchanging of entry points between application and bootloader. ******************************************************************************/ void flashExchangeEntryPoints(void) { uint32_t appLabel; uint32_t tempAddr = FLASH_START_ADDRESS; uint32_t itr; uint32_t fmrBackup; tempAddr = FLASH_END_ADDRESS + BOOT_AREA_SIZE - FLASH_PAGE_SIZE + 1; // change application entry point to boot entry point for (itr = 0; itr < FLASH_PAGE_SIZE; itr += sizeof(uint32_t)) { if ((FLASH_END_ADDRESS + BOOT_AREA_SIZE - sizeof(uint32_t) + 1) == (tempAddr + itr)) { // last flash byte for storing application entry point MMIO(tempAddr + itr) = appEntryPoint; continue; } if ((FLASH_END_ADDRESS + BOOT_AREA_SIZE - 2 * sizeof(uint32_t) + 1) == (tempAddr + itr)) { appLabel = MMIO(tempAddr + itr); appLabel |= 0xFF000000; MMIO(tempAddr + itr) = appLabel; continue; } MMIO(tempAddr + itr) = MMIO(tempAddr + itr); // copy flash page to shadow buffer } fmrBackup = EFC->EEFC_FMR; EFC->EEFC_FMR = (FWS_FOR_WRITE << 8); // Perform page erase and write. flashWritePage(LAST_PAGE, false); EFC->EEFC_FMR = fmrBackup; }
void spiFlashWriteSector(u32 nSector, u8* pBuffer) { u32 sectorAddr = nSector << 12; for(u16 i=0;i<FLASH_PAGES_PER_SECTOR;i++) { flashWritePage(pBuffer, sectorAddr, FLASH_PAGE_SIZE); sectorAddr += FLASH_PAGE_SIZE; pBuffer += FLASH_PAGE_SIZE; } }
/**************************************************************************//** \brief Function to do an atomic erase-write on one page in the flash. \note The maximum pageAddress must not be exceeded. The maximum number of pages can be found in the datasheet. \param[in] pageAddress Page address to the page to erase/write. ******************************************************************************/ void flashEraseWritePage(uint16_t pageAddress) { // Calculate actual start address of the page. uint32_t tableAddress = (uint32_t)pageAddress * (uint32_t)FLASH_PAGE_SIZE; uint16_t itr; uint32_t *ptr = (uint32_t *)temporaryPageBuffer; for (itr = 0; itr < FLASH_PAGE_SIZE; itr += sizeof(uint32_t), ptr++) { if ((FIRST_PAGE == pageAddress) && (sizeof(uint32_t) == (tableAddress + itr))) { appEntryPoint = *ptr; MMIO(tableAddress + itr) = MMIO(tableAddress + itr); } else { MMIO(tableAddress + itr) = *ptr; } } // Perform page erase. flashWritePage(pageAddress, false); }
/**----------------------------------------------------------------- * SPI_FLASH_BufferWrite * Writes block of data to the FLASH. In this function, * the number of WRITE cycles are reduced, * using Page WRITE sequence. * pointer to the buffer containing the data to be * written to the FLASH. * - WriteAddr : * FLASH's internal address to write to. * - NumByteToWrite : * number of bytes to write to the FLASH. ***----------------------------------------------------------------*/ void spiFlashBufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; Addr = WriteAddr % FLASH_PAGE_SIZE; count = FLASH_PAGE_SIZE - Addr; NumOfPage = NumByteToWrite / FLASH_PAGE_SIZE; NumOfSingle = NumByteToWrite % FLASH_PAGE_SIZE; if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */ { if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ { flashWritePage(pBuffer, WriteAddr, NumByteToWrite); } else /* NumByteToWrite > SPI_FLASH_PageSize */ { while (NumOfPage--) { flashWritePage(pBuffer, WriteAddr, FLASH_PAGE_SIZE); WriteAddr += FLASH_PAGE_SIZE; pBuffer += FLASH_PAGE_SIZE; } flashWritePage(pBuffer, WriteAddr, NumOfSingle); } } else /* WriteAddr is not SPI_FLASH_PageSize aligned */ { if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ { if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */ { temp = NumOfSingle - count; flashWritePage(pBuffer, WriteAddr, count); WriteAddr += count; pBuffer += count; flashWritePage(pBuffer, WriteAddr, temp); } else { flashWritePage(pBuffer, WriteAddr, NumByteToWrite); } } else /* NumByteToWrite > SPI_FLASH_PageSize */ { NumByteToWrite -= count; NumOfPage = NumByteToWrite / FLASH_PAGE_SIZE; NumOfSingle = NumByteToWrite % FLASH_PAGE_SIZE; flashWritePage(pBuffer, WriteAddr, count); WriteAddr += count; pBuffer += count; while (NumOfPage--) { flashWritePage(pBuffer, WriteAddr, FLASH_PAGE_SIZE); WriteAddr += FLASH_PAGE_SIZE; pBuffer += FLASH_PAGE_SIZE; } if (NumOfSingle != 0) { flashWritePage(pBuffer, WriteAddr, NumOfSingle); } } } }