Skip to content

Instantly share code, notes, and snippets.

@andrewrt
Created October 13, 2020 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewrt/c94499159a41e9de918be266423b98b6 to your computer and use it in GitHub Desktop.
Save andrewrt/c94499159a41e9de918be266423b98b6 to your computer and use it in GitHub Desktop.
rt1052 flash copy scratch
__RAMFUNC(RAM) status_t flash_copy_62000000_to_60000000(){
uint8_t retry_count = 0;
uint8_t *ptr;
status_t status = eraseFlashBulk(FlexSPI_AMBA_BASE, xip_image_sizee_in_bytes);
if (status != kStatus_Success){
return -1;
}
//move everything from scratch space to FLASH START
uint32_t pages = xip_image_sizee_in_bytes / FLASH_PAGE_SIZE;
for (uint32_t i=0; i < pages; i++){
L1CACHE_CleanInvalidateDCacheByRange(0x62000000 + i * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE);
ptr = (uint8_t *)(0x62000000 + i * FLASH_PAGE_SIZE);
for (int cpyidx = 0; cpyidx < FLASH_PAGE_SIZE; cpyidx++){
page_buffer[cpyidx] = ptr[cpyidx];
}
retry_count = 8;
do {
status = programFlashPageNoErase(FlexSPI_AMBA_BASE + i * FLASH_PAGE_SIZE, page_buffer);
} while ((status != kStatus_Success) && retry_count-- > 0);
if (status != kStatus_Success){
return -1;
}
}
if (xip_image_sizee_in_bytes % FLASH_PAGE_SIZE > 0){
//one extra page - incoming flash already erase padded:
L1CACHE_CleanInvalidateDCacheByRange(0x62000000 + pages * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE);
ptr = (uint8_t *)(0x62000000 + pages * FLASH_PAGE_SIZE);
for (int cpyidx = 0; cpyidx < FLASH_PAGE_SIZE; cpyidx++){
page_buffer[cpyidx] = ptr[cpyidx];
}
retry_count = 8;
do {
status = programFlashPageNoErase(FlexSPI_AMBA_BASE + pages * FLASH_PAGE_SIZE, page_buffer);
} while ((status != kStatus_Success) && retry_count-- > 0);
if (status != kStatus_Success){
return -1;
}
}
return kStatus_Success;
}
__RAMFUNC(RAM) status_t verifyProgramFlash(uint32_t flashAddr, uint8_t *data, uint32_t size){
__asm("nop");
L1CACHE_CleanInvalidateDCacheByRange(flashAddr, size);
__asm("nop");
uint8_t *ptr = (uint8_t *)(flashAddr);
for (int i=0; i < size; i++){
if (data[i] != ptr[i]){
return -1;
}
}
// - can't trust memcpy - running from flash...
// memcpy(s_nor_read_buffer, (void *)(flashAddr), testSize);
// if (memcmp(s_nor_read_buffer, data, testSize) != 0){
// return -1;
// }
return kStatus_Success;
}
__RAMFUNC(RAM) status_t programFlashPageNoErase(uint32_t flashAddr, uint8_t *data){
status_t status = kStatus_Success;
status = flexspi_nor_flash_page_program(FLEXSPI, flashAddr - FlexSPI_AMBA_BASE, (void *)data);
if (status != kStatus_Success){
return -1;
}
status = verifyProgramFlash(flashAddr, data, FLASH_PAGE_SIZE);
if (status != kStatus_Success){
return -1;
}
return status;
}
__RAMFUNC(RAM) status_t eraseFlashBulk(uint32_t flashAddr, uint32_t size){
status_t status;
//Erase blocks involved:
//1. Get 64KB Block address offset
uint32_t firstBlockStartAddress = (flashAddr / 0x10000) * 0x10000;
//2. Get last 64KB Block address
uint32_t lastBlockStartAddress = (( flashAddr + size) / 0x10000) * 0x10000;
//3. Erase blocks:
for (uint32_t addr = firstBlockStartAddress; addr <= lastBlockStartAddress; addr+= 0x10000 ){
// flexspi_nor_flash_erase_64KB_block - directly calls flex spi driver with 64KB erase block
status = flexspi_nor_flash_erase_64KB_block(FLEXSPI, addr - FlexSPI_AMBA_BASE);
if (status != kStatus_Success){
return -1;
}
//verify 1st sector of each block erased at least:
status = verifyEraseFlash(addr , SECTOR_SIZE);
if (status != kStatus_Success){
return -1;
}
}
return kStatus_Success;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment