bool FlashUnlock(void) { volatile FUNIT *s=(FUNIT *)FLASH_BASE; // do command. *s = FlashCMD(FLASH_SETUP); *s = FlashCMD(BLOCK_LOCK_BIT_CLEAR); if (!FullStatusCheck(s, ACT_UNLOCK)) return false; return true; } // FlashUnlock.
static bool EraseOneFlashBlock(FUNIT *addr) { volatile FUNIT *s=addr; // error. if ((long)addr%FLASH_BLOCK_SIZE) return false; // do command. *s = FlashCMD(ERASE_SETUP); *s = FlashCMD(ERASE_CONFIRM); if (!FullStatusCheck(s, ACT_ERASE)) return false; return true; } // EraseOne.
bool FlashLock(FUNIT *addr) { volatile FUNIT *s=addr; // error. if ((long)addr % FLASH_BLOCK_SIZE){ printf("addr is not flash block base.\n"); return false; } // do command. *s = FlashCMD(FLASH_SETUP); *s = FlashCMD(BLOCK_LOCK_BIT_SET); if (!FullStatusCheck(s, ACT_LOCK)) return false; return true; } // FlashLock.
U8 Flash_Erase(U16 num){ union{ U32 Word; U8 Byte[4]; }FlashDestination; FlashDestination.Word=ADDR+num*SECTOR_SIZE; FTFL->FCCOB0=FTFL_FCCOB0_CCOBn(ERSSCR); FTFL->FCCOB1=FlashDestination.Byte[2]; FTFL->FCCOB2=FlashDestination.Byte[1]; FTFL->FCCOB3=FlashDestination.Byte[0]; if(FlashCMD()==1){return 1;}//Error return 0;//Success }
// error true return. bool FullStatusCheck(volatile FUNIT *addr, FLASH_ACTION which) { FUNIT result; // delay before command is done. do { *addr = FlashCMD(STATUS_READ); result = *addr; } while ((~result & STATUS_BUSY)); *addr = FlashCMD(READ_ARRAY); return true; // if no error, return true. if ((result & STATUS_ERR_FILTER) == 0) return true; // if error, print out error message. if (result & STATUS_LOCK_DETECT){ printf("Block Lock-bit detected.\n\n"); } else if (result & STATUS_VOLT_RANG_ERR){ printf("Voltage Range Error.\n\n"); } else if ((result & STATUS_CMD_SEQ_ERR) == STATUS_CMD_SEQ_ERR){ printf("Command Sequence Error.\n\n"); } else if ((result & STATUS_PGM_ERR) && ACT_PGM){ printf("\nWrite error at address 0x%08lx\n\n", (long)addr); } else if ((result & STATUS_LOCK_ERR) && ACT_LOCK){ printf("Set Lock-Bit Error.\n\n"); } else if ((result & STATUS_ERASE_ERR) && ACT_ERASE){ printf("Fail to erase. retry again.\n\n"); } else if ((result & STATUS_UNLOCK_ERR) && ACT_UNLOCK){ printf("Clear Lock-Bit Error.\n\n"); } else { printf("Unknown Error.\n\n"); } *addr = FlashCMD(STATUS_CLEAR); *addr = FlashCMD(READ_ARRAY); return true; }
U8 Flash_Program(U16 num, U16 WriteCounter, U16 *DataSource){ U32 size; U32 destaddr; union{ U32 Word; U8 Byte[4]; }FlashDestination; FTFL->FCCOB0=PGM4; destaddr=(ADDR+num*SECTOR_SIZE); FlashDestination.Word=destaddr; for(size=0;size<WriteCounter;size+=2,FlashDestination.Word+=4,DataSource+=2){ FTFL->FCCOB1=FlashDestination.Byte[2]; FTFL->FCCOB2=FlashDestination.Byte[1]; FTFL->FCCOB3=FlashDestination.Byte[0]; FTFL->FCCOB4=DataSource[1]>>8; FTFL->FCCOB5=DataSource[1]&0xFF; FTFL->FCCOB6=DataSource[0]>>8; FTFL->FCCOB7=DataSource[0]&0xFF; if(FlashCMD()==1)return 2; } return 0; }
bool DoWriteToFlashBlocks(CMD_TBL *cptr, int argc, char **argv) { long dest=0, src=0, len, wsize; switch (argc){ case 2 : if (!StrCmp(argv[1], "kernel")){ dest = (long)KERNEL_SRAM_BASE; src = (long)KERNEL_DRAM_BASE; len = (long)KERNEL_MAX_SIZE; printf("Saving kernel to flash...\n"); } else if (!StrCmp(argv[1], "root")){ dest = (long)ROOT_SRAM_BASE; src = (long)ROOT_DRAM_BASE; len = (long)ROOT_MAX_SIZE; printf("Saving root to flash...\n"); } else if (!StrCmp(argv[1], "loader")){ dest = (long)LOADER_SRAM_BASE; src = (long)LOADER_DRAM_BASE; len = (long)LOADER_MAX_SIZE; printf("Saving bootloader to flash...\n"); } else { printf(cptr->usage); return false; } break; // "flash [dest] [src] [len]". case 4 : if (!HexToInt(argv[1], &dest, 32) || !HexToInt(argv[2], &src, 32) || !HexToInt(argv[3], &len, 32)){ printf(cptr->usage); return false; } if (dest % FLASH_BLOCK_SIZE){ printf("dest is not Flash Block Base.\n"); return false; } break; default : printf(cptr->usage); return false; break; } // erase flash blocks. printf("Erase flash blocks from 0x%08lx to 0x%08lx.\n", dest, (long)dest+len-1); if (!EraseFlashBlocks((FUNIT *)dest, len)) return false; printf("\tDone.\n"); // write to flash. printf("Write to flash...\n"); wsize = FLASH_BLOCK_SIZE; do{ printf("\tWriting at 0x%08lx...", (ulong)dest); if (!WriteToFlashBuffer((FUNIT *)dest, (FUNIT *)src)) break; dest += FLASH_BLOCK_SIZE; src += FLASH_BLOCK_SIZE; ClearLine(); } while((len -= FLASH_BLOCK_SIZE) >0); printf("\tWriting at 0x%08lx\r\n", (ulong)dest); printf("\tDone\n"); IT(dest) = FlashCMD(READ_ARRAY); return true; } // DoWriteToFlashBlocks.
bool WriteToFlashBuffer(void *dest, void *src) { #ifdef XHYPER255A int i; volatile FUNIT *s1=dest, *s2=src, result, *end=s1+(FLASH_BLOCK_SIZE/FBOUND); ushort writeBuf = 32; while (s1<end){ *s1 = FlashCMD(WRITE_BUF); do { *s1 = FlashCMD(STATUS_READ); result = *s1; } while ((~result & STATUS_BUSY)); *s1 = (writeBuf)/2 - 1; for (i=0; i<(writeBuf)/FBOUND; i++) *s1++ = *s2++; IT((s1)) = FlashCMD(WRITE_BUF_COMFIRM); do { result = IT(s1); } while((result & STATUS_BUSY ) != STATUS_BUSY); IT(s1) = FlashCMD(READ_ARRAY); } #else ulong i=0; volatile uchar *s1=(uchar *)dest; uchar *s2=(uchar *)src; ushort writeBuf = 32; while(i < FLASH_BLOCK_SIZE) { int cnt = writeBuf / sizeof(ushort); int result; do { IT(s1) = WRITE_BUF; result = IT(s1); } while((result & STATUS_BUSY ) != STATUS_BUSY); IT(s1) = FlashCMD((writeBuf / sizeof(ushort) -1) | \ ((writeBuf / sizeof(ushort) -1 ) << (sizeof(ulong) * 4))); while(cnt--) { IT((s1+i)) = IT(s2); i += sizeof(ulong); s2 += sizeof(ulong); } IT((s1)) = FlashCMD(WRITE_BUF_COMFIRM); do { result = IT(s1); } while((result & STATUS_BUSY ) != STATUS_BUSY); IT(s1) = FlashCMD(READ_ARRAY); } #endif return true; }