📄 flash_intel.c
字号:
if (retry_tally++ < 3) { goto retry; } else { util_printf("Giving up!\n"); enable_read_mode(block_addr); return 1; // failed } }#if 0 /* stuff that was helpful for a while on C547X but now doesn't seem necessary. */ { unsigned long val; enable_read_mode(block_addr); val = *l_addr; if (0xffffffff != val) { // basic sanity check. util_printf("Erase error. block addr = 0x%X, l_addr = 0x%X, val = 0x%X\n",block_addr,l_addr,val); status = read_status(block_addr); util_printf("[status = 0x%x]\n",status); util_printf("[retrying]\n"); if (retry_tally++ < 3) { goto retry; } else { util_printf("Giving up!\n"); enable_read_mode(block_addr); return 1; // failed } } }#endif enable_read_mode(block_addr); return 0; // success}#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS /****************************** Routine: Description: ******************************/ static int prog_data_32(unsigned long *block_addr, unsigned long data) { #define PROG_CODE_32 0x00400040; unsigned short status; // util_printf("0x%X = 0x%X\n", block_addr, data); // *debug* tmp if ((*block_addr & data) != data) { // we can only change bits from a "1" to "0". util_printf("Error, not previously erased; addr = 0x%X, data = 0x%X\n",block_addr,*block_addr); return 1; // failed } clear_status((unsigned short *)block_addr); if (0xBEEFFEED != FlashLockMode) { util_printf("Error: Please Unlock Flash before trying to modify it.\n"); util_printf(" Giving up.\n"); return 1; // failed } *block_addr = PROG_CODE_32; // Put each chip in program mode, and then... *block_addr = data; // 16bits+16bits=32bits; Give each chip a 16bit data value. while (is_busy((unsigned short *)block_addr)) {} if (was_error((unsigned short *)block_addr)) { status = read_status((unsigned short *)block_addr); util_printf("Prog error. addr = %X, status = %x\n",block_addr,status); clear_status((unsigned short *)block_addr); // *debug* temp util_printf("Prog error. addr = %X, status = %x\n",block_addr,status); SYSTEM_FATAL("Terminating."); } enable_read_mode((unsigned short *)block_addr); return 0; // success } #else /****************************** Routine: Description: ******************************/ static int prog_data_16(unsigned short *block_addr, unsigned short data) { #define PROG_CODE_16 0x40; unsigned short status; // util_printf("0x%X = 0x%x\n", block_addr, data); // *debug* tmp if ((*block_addr & data) != data) { // we can only change bits from a "1" to "0". util_printf("Error, not previously erased; addr = 0x%X, data = 0x%X\n",block_addr,*block_addr); return 1; // failed } clear_status(block_addr); if (0xBEEFFEED != FlashLockMode) { util_printf("Error: Please Unlock Flash before trying to modify it.\n"); util_printf(" Giving up.\n"); return 1; // failed } *block_addr = PROG_CODE_16; *block_addr = data; while (is_busy(block_addr)) {} if (was_error(block_addr)) { status = read_status(block_addr); util_printf("Prog error. addr = %X, status = %x\n",block_addr,status); clear_status(block_addr); // *debug* temp util_printf("Prog error. addr = %X, status = %x\n",block_addr,status); SYSTEM_FATAL("Terminating."); } enable_read_mode(block_addr); return 0; // success }#endif/****************************** 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; // Flash; read word at a time, not byte at a time. num_words = ((num_bytes+1)>>1); // round up. for (i=0; i<num_words; i++) { 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){#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS unsigned int i, failed, num_32bit_words; unsigned long fval, *d_addr; unsigned short fval_lo, fval_hi, *s_addr; s_addr = src; failed = 0; d_addr = (unsigned long *)(BSPCONF_FLASH_BASE+offset); if (2 == num_bytes) { // -- Special Case-- The only time that // we expect to see 2 bytes at a time coming in is // during an XIP download directly to flash. In // this case we'll have to except the two bytes (16bits) // and cache it temporarily until the next call // which gives us a second 16bit value which can // be finally combined with the first to give us // the 32bit unit we need for each flash operation. // Summary, For c547x the minimum we can flash in // one operation is 4 bytes (32bits), yet the XIP // parser is feeding us 16bits at a time. if (Cached_Short_valid) { if (CBack) { (*CBack)(s_addr,&fval_hi); } else { fval_hi = *s_addr; } // Okay this is short number two, we've got 32bits // worth of data and can send it to flash now. fval = (fval_hi << 16) | Cached_Short; failed = prog_data_32(Cached_flash_addr,fval); if (failed) goto done; Cached_Short_valid = 0; } else { if (CBack) { (*CBack)(s_addr,&Cached_Short); } else { Cached_Short = *s_addr; } // Okay, cache it and wait for next call to give // us another 16bits -- then we'll have the 32bits // we need for the flash operation. Cached_flash_addr = d_addr; Cached_Short_valid = 1; } } else { // --Normal Case-- // Flash; write 32bits at a time. num_32bit_words = ((num_bytes+3)>>2); // round up. for (i=0; i<num_32bit_words; i++) { if (CBack) { (*CBack)(s_addr, &fval_lo); (*CBack)(s_addr+1,&fval_hi); } else { fval_lo = *s_addr; fval_hi = *(s_addr+1); } fval = (fval_hi << 16) | fval_lo; failed = prog_data_32(d_addr,fval); if (failed) break; s_addr+=2; d_addr++; } }#else unsigned int i, failed, num_16bit_words; unsigned short fval, *d_addr, *s_addr; failed = 0; s_addr = src; d_addr = (unsigned short *)(BSPCONF_FLASH_BASE+offset); // Flash; write 16bits at a time. num_16bit_words = ((num_bytes+1)>>1); // round up. for (i=0; i<num_16bit_words; i++) { if (CBack) { (*CBack)(s_addr,&fval); } else { fval = *s_addr; } failed = prog_data_16(d_addr,fval); if (failed) break; s_addr++; d_addr++; }#endifdone: if (failed) { io_delay(6000); } return 0;}/****************************** Routine: Description: Note: See flash.h for description. ******************************/int flash_flush(void){#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS // This block became necessary for supporting XIP downloads // on these style boards. if (Cached_Short_valid) { { unsigned long final_val; // We hadn't finished that last 32 bit flash write // operation since we were waiting for a full 32 bit // value. It looks like we are not going to get any // more data so we'll fill out the remainder of that // 32bit value with zeros and finish up the flash // operation. final_val = 0x0000 | Cached_Short; prog_data_32(Cached_flash_addr,final_val); Cached_Short_valid = 0; } }#endif return -1; // *debug* finish later.}/****************************** Routine: Description: Note: See flash.h for description. ******************************/void flash_erase(void){ // Erase the entire flash chip(s). int i, failed; unsigned short *ChipAddr; for (i=0; i<TotalSectors; i++) { util_printf("Erasing block %i of %i\n",i,TotalSectors); ChipAddr = (unsigned short *)(SectInfoTable[i].start_addr); failed = block_erase(ChipAddr); if (failed) break; } if (failed) { io_delay(6000); }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/void flash_erase_range(int start_addr, int end_addr){ // Erases the indicated portion of the flash. // Note: the whole block containing the start_addr as well as // the whole block containing the end_addr, and all blocks // in-between, are erased. Keep this in mind when forming // your range request -- if not careful you will get more // erased than your range defines due to the erase constraints // of flash chips. They can only erase whole blocks. int i, failed; unsigned short *ChipAddr; util_printf("Erasing blocks containing addresses 0x%X to 0x%X\n",start_addr,end_addr); for (i=0; i<TotalSectors; i++) { if ((SectInfoTable[i].start_addr >= start_addr) && (SectInfoTable[i].start_addr <= end_addr)) { util_printf("Erasing block %i of %i\n",i,TotalSectors); ChipAddr = (unsigned short *)(SectInfoTable[i].start_addr); failed = block_erase(ChipAddr); if (failed) break; } } if (failed) { io_delay(6000); }}/****************************** Routine: Description: Note: See flash.h for description. ******************************/int flash_init(void){ #define Intel_28F160F3_alt 0x008988F4 // examples, ti925 and ... #define Intel_28F160F3 0x008988F3 // examples, omap1510-Helen/P1 and ... #define Intel_28F128J3A 0x00890018 // examples, omap1510-Helen/P1, ti925 and ... #define Intel_28F320_TB 0x00898896 // examples, C547X TopBoot devices and ... #define Intel_28F320_BB 0x00898897 // examples, C547X BottomBoot devices and ... int i, j, index, addr_tally; unsigned long code; short NumChipSectors;#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS // This block became necessary for supporting XIP downloads // on these style boards. Cached_Short_valid = 0; Cached_Short = 0;#endif index = 0; addr_tally = BSPCONF_FLASH_BASE; (void)read_device_codes(&code); // util_printf("device ID = 0x%X\n",code); switch(code) { case Intel_28F160F3: NumChipSectors = NUM_CHIP_SECT; TotalSectors = TOTAL_SECT; SectInfoTable = sect_info; for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) { for (i=0; i<NumChipSectors; i++) { SectInfoTable[index].start_addr = addr_tally; addr_tally += sect_sizes[i]; SectInfoTable[index].end_addr = addr_tally-1; index++; } } return 160; break; case Intel_28F160F3_alt: NumChipSectors = NUM_CHIP_SECT; TotalSectors = TOTAL_SECT; SectInfoTable = sect_info; for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) { for (i=0; i<NumChipSectors; i++) { SectInfoTable[index].start_addr = addr_tally; addr_tally += sect_sizes[i]; SectInfoTable[index].end_addr = addr_tally-1; index++; } } return 160; break; case Intel_28F320_TB: NumChipSectors = NUM_CHIP_SECT_A; TotalSectors = TOTAL_SECT_A; SectInfoTable = sect_info_A; for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) { for (i=0; i<NumChipSectors; i++) { SectInfoTable[index].start_addr = addr_tally; addr_tally += sect_sizes_A[i]; SectInfoTable[index].end_addr = addr_tally-1; index++; } } return 320; break; case Intel_28F128J3A: NumChipSectors = NUM_CHIP_SECT_B; TotalSectors = TOTAL_SECT_B; SectInfoTable = sect_info_B; for (j=0; j<NUM_SEQUENTIAL_CHIPS; j++) { for (i=0; i<NumChipSectors; i++) { SectInfoTable[index].start_addr = addr_tally; addr_tally += sect_sizes_B[i]; SectInfoTable[index].end_addr = addr_tally-1; index++; } } return 128; break; default: util_printf("***************************************\n"); util_printf("Warning: Unknown flash device detected!\n"); util_printf(" : Detected device code = 0x%X \n",code); util_printf("***************************************\n"); util_printf("\n");#if 1 SYSTEM_FATAL("Terminating.");#else io_delay(6000); // To prevent ui frontend from clearing the // screen before the user can read it. return 160; // Hmmm? just return some default value.#endif break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -