📄 flash_amd.c
字号:
int i; addr = (unsigned short *) BSPCONF_FLASH_BASE; if ( array_size < (CFI_END_ADDR +1)) { util_printf("read_cfi_array: ERROR array too small\n"); return(0); } if ( ! cfi_supported() ) { return(0); } enable_read_mode(); addr[0x55] = 0x98; /* Enter read array mode */ for ( i=CFI_START_ADDR; i <= CFI_END_ADDR; i++) { array[i] = addr[i]; } enable_read_mode(); return(1);}/****************************** Routine: Description: returns number of sectors if chip supports CFI. sector_map contains size of each sector. Returns false if chip doesn't support CFI. WARNING: the generated sector may not be ordered correctly******************************/int build_sector_map(unsigned int sector_map[], int sector_map_size){ unsigned short array[CFI_END_ADDR]; int ret, i, j; int region_count; int sector_count = 0; int region_sector_count; long region_size; int sector_index = 0; long calculated_flash_size = 0; if ( ! cfi_supported() ) { return(0); } ret = read_cfi_array(array, CFI_END_ADDR + 1); if ( ! ret ) { util_printf("build_sector_map: ERROR unable to read CFI array\n"); return(0); } region_count = array[0x2C]; /* process each region in the chip */ for ( i=0; i<region_count; i++) { region_sector_count = (array[0x2E + (i * 4)] << 8) + array[0x2D + (i * 4)] + 1; sector_count += region_sector_count; region_size = ((array[0x30 + (i * 4)] << 8) + array[0x2F + (i * 4)]) * 256;// util_printf(" Region %d contains %d sectors of size 0x%X\n", // i, region_sector_count, region_size); /*process each sector in the current region */ for (j=0; j<region_sector_count; j++) { if ( sector_index >= sector_map_size) { util_printf( "build_sector_map: ERROR sector map array too small %d\n", sector_map_size); return(0); } sector_map[sector_index++] = region_size; calculated_flash_size += region_size; } } if ( (calculated_flash_size >> 20) != (1 << (array[0x27]-20)) ) { util_printf("Warning: calculated flash size doesn't match CFI query flash size\n"); util_printf("Calculated flash size: %d Mbytes", calculated_flash_size >> 20); util_printf("CFI stated flash size: %d Mbytes", 1 << (array[0x27]-20)); } return(sector_count);}#endif/****************************** Routine: Description: returns true if block erased successfully******************************/static int block_erase(unsigned short *block_addr){ unsigned char retVal; volatile unsigned short *addr; //only erase block if it is not already erased if (verify_block_erased((unsigned short *)block_addr, false)) { return(true); } addr = (unsigned short *)BSPCONF_FLASH_BASE; addr[0x555] = 0xAA; addr[0x2aa] = 0x55; addr[0x555] = 0x80; addr[0x555] = 0xAA; addr[0x2aa] = 0x55; *block_addr = 0x30; WaitForFlashEraseToStart(); retVal=IsFlashOperationSuccessful(block_addr); return(verify_block_erased((unsigned short *)block_addr, true));}/****************************** Routine: Description:******************************/static void prog_data(unsigned short *block_addr, unsigned short data){ int retVal; volatile unsigned short *addr; if ((*block_addr & data) != data) { // we can only change bits from a "1" to "0". util_printf("\nProg error; not sufficiently erased; addr = 0x%X (0x%X)\n", block_addr, *block_addr); SYSTEM_FATAL("Fatal"); } addr = (unsigned short *)BSPCONF_FLASH_BASE; addr[0x555] = 0xAA; addr[0x2aa] = 0x55; addr[0x555] = 0xA0; *block_addr = data; retVal = IsFlashOperationSuccessful(block_addr); while (!retVal); if (*block_addr != data) { util_printf("Unable to write flash address 0x%X (%s line %d)\n", block_addr, __FILE__, __LINE__); while (1); }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/void flash_read(unsigned int offset, // Of flash. unsigned short *dest, // Destination buffer. unsigned int num_bytes, PutValAtAddrCallBack_t CBack){ unsigned int i, num_words; unsigned short fval, *s_addr, *d_addr; s_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset); d_addr = dest; num_words = ((num_bytes+1)>>1); // round up. for (i=0; i<num_words; i++) { // Flash, for this board, requires that we read words, not bytes. fval = *s_addr; if (CBack) { (*CBack)(d_addr,fval); // write out the the 16bit value. } else { *d_addr=fval; // write out the the 16bit value. } s_addr++; d_addr++; }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/int flash_write(unsigned int offset, // Of flash. unsigned short *src, // Source buffer. unsigned int num_bytes, GetValAtAddrCallBack_t CBack){ unsigned int i, num_words; unsigned short fval, *d_addr, *s_addr; s_addr = src; d_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset); num_words = ((num_bytes+1)>>1); // round up. for (i=0; i<num_words; i++) { if (CBack) { (*CBack)(s_addr,&fval); } else { fval = *s_addr; } prog_data(d_addr,fval); s_addr++; d_addr++; } return 0;}/****************************** Routine: Description: Note: See flash.h for description. ******************************/int flash_flush(void){ // Return a -1 if all went well, otherwise // return the flash offset which presented // a problem. return -1;}/****************************** Routine: Description: Note: See flash.h for description. ******************************/void flash_erase(void){ // Erase the entire flash chip. int i; for (i=0; i<TOTAL_SECT; i++) { util_printf("Erasing block %i of %i\n",i,TOTAL_SECT); block_erase((unsigned short *)(sect_info[i].start_addr)); }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/void flash_erase_range(int start_addr, int end_addr){ int i; int start_erase=-1; int end_erase=-1; util_printf("Erasing blocks containing addresses 0x%X to 0x%X\n",start_addr,end_addr); for (i=0; i<TOTAL_SECT; i++) { if ((sect_info[i].start_addr <= start_addr) && (sect_info[i].end_addr >= start_addr)) { start_erase = i; } if ((sect_info[i].start_addr <= end_addr) && (sect_info[i].end_addr >= end_addr)) { end_erase = i; } } if (( start_erase < 0 ) || ( end_erase < 0 )) { util_printf("Erase flash bad address range\n"); } for (i=start_erase; i<=end_erase; i++) { util_printf("Erasing block %i of %i\n",i,TOTAL_SECT); block_erase((unsigned short *)(sect_info[i].start_addr)); }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/int flash_init(){ int i, addr_tally; addr_tally = BSPCONF_FLASH_BASE; for (i=0; i < TOTAL_SECT; i++) { sect_info[i].start_addr = addr_tally; addr_tally += sect_sizes[i]; sect_info[i].end_addr = addr_tally-1; } return 640;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -