📄 jflash.cpp
字号:
* DWORD fsize - size of flash device
* DWORD block_size - block size of the flash device
* DWORD max_erase_time - for timeout value
* int block_number - number of blocks to erase
*
* RETURNS: void
*
*******************************************************************************
*/
void erase_flash(DWORD base_address, DWORD fsize, DWORD block_size, DWORD max_erase_time, int block_number)
{
time_t start, now;
printf("Starting erase\n");
for(DWORD lj = base_address; lj < fsize + base_address; lj = lj + block_size) // Erase only blocks to be programmed
{
access_rom(SETUP, 0, F_BLOCK_ERASE, IGNORE_PORT); // Erase block command
access_rom(WRITE, 0, F_BLOCK_ERASE, IGNORE_PORT);
access_rom(HOLD, 0, F_BLOCK_ERASE, IGNORE_PORT);
access_rom(SETUP, lj, F_BLOCK_ERASE_2ND, IGNORE_PORT); // Erase confirm at the block address
access_rom(WRITE, lj, F_BLOCK_ERASE_2ND, IGNORE_PORT);
access_rom(HOLD, lj, F_BLOCK_ERASE_2ND, IGNORE_PORT);
time(&start);
printf("Erasing block %3d \r",block_number++);
while(access_rom(RS, 0, 0, READ_PORT) != F_STATUS_READY) // Loop until successful status return
{
access_rom(READ, 0, 0, READ_PORT);
time(&now);
if(difftime(now,start) > max_erase_time + 1) // Check for erase timeout
error_out("Error, Block erase timed out");
}
}
printf("Erasing done \n");
}
/*
*******************************************************************************
*
* FUNCTION: program_flash
*
* DESCRIPTION: program the flash using buffered writes
*
* INPUT PARAMETERS: DWORD max_write_buffer derived from the flash query
* DWORD base_address
* DWORD fsize (flash size)
*
* RETURNS: void
*
*******************************************************************************
*/
void program_flash(DWORD max_write_buffer, DWORD base_address, DWORD fsize)
{
time_t start, now;
BUS_GRAIN li;
printf("Starting programming\n");
// "Write Buffer" flow.
// This uses almost half the cycles required by "word programming" flow
// Status register is not read to save time. There is also no checking to see
// if maximum "Write Buffer Program Time" is violated. However even with the
// fastest parallel port bus speed this should not be a problem
// (i.e. 16 words * 300 JTAG chain length * 4 parallel port cycles * 1uS fast
// parallel port cycle = 19mS, typical write buffer program times are in the 200uS range).
#ifdef XHYPER255B
DWORD write_word_count = (max_write_buffer - 1) + ((max_write_buffer - 1) << 16);
#else
WORD write_word_count = (WORD)(max_write_buffer - 1);
#endif
time(&start);
for(DWORD lj = base_address; lj < fsize + base_address; lj = lj + max_write_buffer)
{
access_rom(WRITE, lj, F_WRITE_BUFFER, IGNORE_PORT); // write buffer command
access_rom(HOLD, lj, F_WRITE_BUFFER, IGNORE_PORT);
access_rom(WRITE, lj, write_word_count, IGNORE_PORT); // write word count (max write buffer size)
access_rom(HOLD, lj, write_word_count, IGNORE_PORT);
time(&now);
if(difftime(now,start) > STATUS_UPDATE) // Update status every 2 seconds
{
printf("Writing flash at hex address %8lx, %5.2f%% done \r"
,lj * 4,(float)(lj - base_address)/(float)fsize*100.0);
fflush(stdout);
time(&start);
}
for(DWORD lk = 0; lk < max_write_buffer; lk++)
{
fread((BUS_GRAIN *)&li, sizeof(BUS_GRAIN) , 1, in_file);
access_rom(WRITE, lj+lk, li, IGNORE_PORT); // Write buffer data
access_rom(HOLD, lj+lk, li, IGNORE_PORT); // New
}
#ifdef XHYPER255B
access_rom(WRITE, 0, 0xd000d0L, IGNORE_PORT); // Program Buffer to Flash Confirm
access_rom(HOLD, 0, 0xd000d0L, IGNORE_PORT); //New
#else
access_rom(WRITE, 0, 0x00d0L, IGNORE_PORT); // Program Buffer to Flash Confirm
access_rom(HOLD, 0, 0x00d0L, IGNORE_PORT); //New
#endif
}
printf("Programming done \n");
rewind(in_file);
}
/*
*******************************************************************************
*
* FUNCTION: verify_flash
*
* DESCRIPTION: compares data programmed in flash with the original binary file.
*
* INPUT PARAMETERS: DWORD base_address
* DWORD flash_size
*
* RETURNS: void
*
*******************************************************************************
*/
void verify_flash(DWORD base_address, DWORD fsize)
{
time_t start, now;
BUS_GRAIN li, li1;
printf("Starting Verify\n");
time(&start);
for(DWORD lj = base_address + 1; lj <= fsize + base_address; lj++)
{
fread((BUS_GRAIN *)&li, sizeof(BUS_GRAIN) , 1, in_file);
li1 = access_rom(READ, lj, 0x0L, READ_PORT);
time(&now);
if(difftime(now,start) > STATUS_UPDATE) // Update status every 2 seconds
{
printf("Verifying flash at hex address %8lx, %5.2f%% done \r"
,lj * 4,(float)(lj - base_address)/(float)fsize*100.0);
fflush(stdout);
time(&start);
}
if(li != li1)
{
printf("verify error at address = %lx exp_dat = %lx act_dat = %lx\n",lj - 1,li,li1);
exit(1);
}
}
printf("Verification successful! \n");
}
/*
*******************************************************************************
*
* FUNCTION: test_logic_reset
*
* DESCRIPTION: initializes the JTAG state machine to a known state
*
* INPUT PARAMETERS: void
*
* RETURNS: void
*
*******************************************************************************
*/
void test_logic_reset(void)
{
#ifdef DEBUG
printf("begin test logic reset\n");
#endif
putp(1,1,IGNORE_PORT); // keep TMS set to 1 force a test logic reset
putp(1,1,IGNORE_PORT); // no matter where you are in the TAP controller
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
putp(1,1,IGNORE_PORT);
#ifdef DEBUG
printf("finish test logic reset\n");
#endif
}
/*
*******************************************************************************
*
* FUNCTION: test_lock_flash
*
* DESCRIPTION: Tests whether a specified block is locked and if it is, asks
* if you would like to unlock it. It will perform an unlock
* procedure if requested.
*
* INPUT PARAMETERS: DWORD base_address of flash (16-bit address for each device)
* DWORD fsize - size of flash (if Sabinal 16-bit data bus used, this is the 16-bit
word number, if 32-bit data bus used, this is the 32
-bit DWORD number)
* DWORD block_size - block size of flash (1-bit word number)
* DWORD max_erase_time - used for a timeout (s number)
* int block_number - block number of interest
*
* RETURNS: void
*
*
*******************************************************************************
*/
void test_lock_flash(DWORD base_address, DWORD fsize, DWORD block_size,
DWORD max_erase_time, int block_number)
{
time_t start, now;
DWORD lockstatus;
for(DWORD lj = base_address; lj < fsize + base_address; lj = lj + block_size) // Test only blocks to be programmed
{
access_rom(SETUP, 0, F_READ_IDCODES, IGNORE_PORT); // Read Identifier Codes
access_rom(WRITE, 0, F_READ_IDCODES, IGNORE_PORT);
access_rom(HOLD, 0, F_READ_IDCODES, IGNORE_PORT);
access_rom(READ, lj + 2, 0, IGNORE_PORT); // read lock configuration (extra read to get JTAG pipeline going)
lockstatus = access_rom(READ, lj + 2, 0, READ_PORT);
if((lockstatus == 0x10001) || (lockstatus == 0x10000) || (lockstatus == 0x00001))
//if(lockstatus == F_BLOCK_LOCKED )
{
printf("Block of Flash Memory is Write Locked, would you like to unlock it? [y/n]: ");
if(toupper(_getche()) == 'Y')
{
printf("\nblock is locked\n");
access_rom(SETUP, 0, F_CLEAR_BLOCK_LOCK, IGNORE_PORT); // Clear block lock bit command
access_rom(WRITE, 0, F_CLEAR_BLOCK_LOCK, IGNORE_PORT);
access_rom(HOLD, 0, F_CLEAR_BLOCK_LOCK, IGNORE_PORT);
access_rom(SETUP, lj, F_CLEAR_BLOCK_LOCK_2ND, IGNORE_PORT); // Confirm
access_rom(WRITE, lj, F_CLEAR_BLOCK_LOCK_2ND, IGNORE_PORT);
access_rom(HOLD, lj, F_CLEAR_BLOCK_LOCK_2ND, IGNORE_PORT);
time(&start);
printf("Unlocking block %3d \r",block_number++);
while(access_rom(RS, 0, 0, READ_PORT) != F_STATUS_READY) // Loop until successful status return 0x0080
{
access_rom(READ, 0, 0, READ_PORT);
time(&now);
if(difftime(now,start) > max_erase_time + 1) // Check for status timeout
error_out("\nError, Clear lock timed out");
}
}
else
error_out("\nUnable to program Write Locked Flash Memory Block");
}
}
}
/*
*******************************************************************************
*
* FUNCTION: set_lock_flash
*
* DESCRIPTION: sets locks bits in specified block
*
* INPUT PARAMETERS: DWORD base_address of flash
* DWORD fsize - size of flash
* DWORD block_size - block size of flash
* DWORD max_erase_time - used for a timeout
* int block_number - block number of interest
*
* RETURNS: void
*
*******************************************************************************
*/
void set_lock_flash(DWORD base_address, DWORD fsize, DWORD block_size, DWORD max_erase_time, int block_number)
{
time_t start, now;
printf("Starting set block lock bit\n");
for(DWORD lj = base_address; lj < fsize + base_address; lj = lj + block_size) // locks only blocks to be programmed
{
access_rom(SETUP, 0, F_SET_BLOCK_LOCK, IGNORE_PORT); // block lock bit command
access_rom(WRITE, 0, F_SET_BLOCK_LOCK, IGNORE_PORT);
access_rom(HOLD, 0, F_SET_BLOCK_LOCK, IGNORE_PORT);
access_rom(SETUP, lj, F_SET_BLOCK_LOCK_2ND, IGNORE_PORT); // Confirm
access_rom(WRITE, lj, F_SET_BLOCK_LOCK_2ND, IGNORE_PORT);
access_rom(HOLD, lj, F_SET_BLOCK_LOCK_2ND, IGNORE_PORT);
time(&start);
printf("Erasing block %3d \r",block_number++);
while(access_rom(RS, 0, 0, READ_PORT) != F_STATUS_READY) // Loop until successful status return
{
access_rom(READ, 0, 0, READ_PORT);
time(&now);
if(difftime(now,start) > max_erase_time + 1) // Check for status timeout
error_out("Error, Clear lock timed out");
}
}
printf("Set lock bit done \n");
}
/*
*******************************************************************************
*
* FUNCTION: set_address
*
* DESCRIPTION: Loads the address into the address bits
*
* INPUT PARAMETERS: address
*
* RETURNS: void
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS: None
*
* CALLED BY: Anyone
*
* PROTOTYPE: void set_address(unsigned int address);
*
*******************************************************************************
*/
void set_address (DWORD address)
{
unsigned int i;
for (i = 0; i < 26; i++)
{
pin[addr_order[i]] = (int)((address >> i) & 1);
}
}
/*
*******************************************************************************
*
* FUNCTION: set_data
*
* DESCRIPTION: Fills the chain with the data bits
*
* INPUT PARAMETERS: DWORD data
*
* RETURNS: void
*
*******************************************************************************
*/
void set_data(DWORD data)
{
DWORD i;
#ifdef XHYPER255B
for(i = 0; i < 32; i++)
{
pin[dat_order[i]] = (int)((data >> i) & 1); // set data pins
}
#else
for(i = 0; i < 16; i++)
{
pin[dat_order[i]] = (int)((data >> i) & 1); // set data pins
}
#endif
}
/*
*******************************************************************************
*
* FUNCTION: shift_data (Not used at this time)
*
* DESCRIPTION: Extracts the data from the chain
*
* INPUT PARAMETERS: Void
*
* RETURNS: DWORD data
*
*******************************************************************************
*/
DWORD shift_data(int rp)
{
int i;
DWORD busdat = 0;
int tms = 0;
int dr_length = XHYPER255_CHAIN_LENGTH;
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,1,IGNORE_PORT); //select DR scan
putp(1,0,IGNORE_PORT); //capture DR
putp(1,0,IGNORE_PORT); //shift IR
for(i = 0; i < dr_length; i++) // shift write data into JTAG port and read data out
{
out_dat[i] = putp((int)WORKBUF[i], 0, rp); // fill the global out_dat array
}
// replace the work buffer with the captured data
for(i = 0; i < dr_length; i++)
{
WORKBUF[i] = out_dat[i];
}
putp(0,1,IGNORE_PORT); //Exit1-DR
putp(1,1,IGNORE_PORT); //Update-DR
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,0,IGNORE_PORT); //Run-Test/Idle
putp(1,0,IGNORE_PORT); //Run-Test/Idle
for(i = 0; i < 32; i++) // convert serial data to single DWORD
{
busdat = busdat | (DWORD)((int)WORKBUF[input_dat_order[i] + DEVICES_AFTER ] << i);
}
#ifdef DEBUG
printf("Boundary Chain After Scan out\n");
dump_chain();
#endif
return busdat;
}
/*
*******************************************************************************
*
* FUNCTION: set_pin_chip_select
*
* DESCRIPTION: Sets chip selects depending on the address and the platform
*
* INPUT PARAMETERS: DWORD address
*
* RETURNS: void
*
*******************************************************************************
*/
void set_pin_chip_select(DWORD address)
{
if(address < 0x04000000) pin[nCS0_OUT] = 0;
if((address >= 0x04000000) && (address < 0x08000000)) pin[nCS1_OUT] = 0;
if((address >= 0x08000000) && (address < 0x0c000000)) pin[nCS2_OUT] = 0;
if((address >= 0x0c000000) && (address < 0x10000000)) pin[nCS3_OUT] = 0;
if((address >= 0x10000000) && (address < 0x14000000)) pin[nCS4_OUT] = 0;
if((address >= 0x14000000) && (address < 0x18000000)) pin[nCS5_OUT] = 0;
}
/*
*******************************************************************************
*
* FUNCTION: set_chip_select (not used at this time)
*
* DESCRIPTION: Sets the chip select lines relative to the address required.
*
* INPUT PARAMETERS: DWORD address
*
* RETURNS: void
*
*******************************************************************************
*/
void set_chip_select(DWORD address)
{
// memory has 26 bits of byte address and 6 chip selects. This means 64 Mb
// for each bank and we can have 6 banks for a total of 384 Mb
switch(address >> 27)
{
case 0:{WORKBUF[nCS0_OUT + DEVICES_AFTER] = 0; break;}
case 1:{WORKBUF[nCS1_OUT + DEVICES_AFTER] = 0; break;}
case 2:{WORKBUF[nCS2_OUT + DEVICES_AFTER] = 0; break;}
case 3:{WORKBUF[nCS3_OUT + DEVICES_AFTER] = 0; break;}
case 4:{WORKBUF[nCS4_OUT + DEVICES_AFTER] = 0; break;}
case 5:{WORKBUF[nCS5_OUT + DEVICES_AFTER] = 0; break;}
}
}
/*
*******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -