📄 jflash.c
字号:
//JFLASH V1.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> /* toupper() */
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "sa1110jtag.h"
#include <curses.h> /* for getch() */
#define MAX_IN_LENGTH 100 // max length for user input strings
#define STATUS_UPDATE 2 // time between updates of program/verify status in sec
FILE *in_file;
void error_out(char*); // Prints error and exits program
void erase_flash(long, long, long, long, int);
void program_flash(long, long, long);
void verify_flash(int, long, long);
void test_lock_flash(long, long, long, long, int);
void set_lock_flash(long, long, long, long, int);
void error_out(char *error_string)
{
printf("%s\n",error_string);
exit(0);
}
void checkboth(long arg_value, char *errmsg)
{
if((arg_value & 0xffffL) != (arg_value >> 16)) {
printf("error, %s are different\n", errmsg);
exit(-1);
}
}
void erase_flash(long base_address, long fsize, long block_size, long max_erase_time, int block_number)
{
long lj;
printf("Starting erase\n");
for(lj = base_address; lj < fsize + base_address; lj = lj + block_size) // Erase only blocks to be programmed
{
flash_write_cmd(0, 0x20);
flash_write_cmd(lj, 0xd0);
printf("Erasing block %3d \r",block_number++);
flash_wait(max_erase_time);
}
printf("Erasing done\n");
}
void program_flash(long max_write_buffer, long base_address, long fsize)
{
time_t start, now;
long li, lj, lk, write_word_count;
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).
write_word_count = (max_write_buffer - 1) + ((max_write_buffer - 1) << 16);
time(&start);
for(lj = base_address; lj < fsize + base_address; lj = lj + max_write_buffer) {
flash_write_val_hold(lj, bothbanks(0xe8)); // write buffer command
flash_write_val_hold(lj, write_word_count); // write word count (max write buffer size)
time(&now);
if(difftime(now,start) > STATUS_UPDATE) // Update status every 2 sec
{
printf("Writing flash at hex address %8lx, %5.2f%% done \r"
,lj,(float)(lj - base_address)/(float)fsize*100.0);
time(&start);
}
for(lk = 0; lk < max_write_buffer; lk++) {
fread((long *)&li, sizeof(long) , 1, in_file);
flash_write_val_hold(lj+lk, li); // Write buffer data
}
flash_write_val_hold(0, bothbanks(0xd0)); // Program Buffer to Flash Confirm
}
printf("Programming done\nStarting verify\n");
rewind(in_file);
}
void verify_flash(int verify, long base_address, long fsize)
{
time_t start, now;
long li, li1;
long lj;
time(&start);
for(lj = base_address + 1; lj <= fsize + base_address; lj++) {
li1 = flash_read_val(lj);
if (verify)
fread((long *)&li, sizeof(long) , 1, in_file);
else
fwrite((long *)&li1, sizeof(long) , 1, in_file);
time(&now);
if(difftime(now,start) > STATUS_UPDATE) // Update status every 2 sec
{
printf("Verifying flash at hex address %8lx, %5.2f%% done \r"
,lj,(float)(lj - base_address)/(float)fsize*100.0);
time(&start);
}
if(verify && 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");
}
void test_lock_flash(long base_address, long fsize, long block_size, long max_erase_time, int block_number)
{
long lj;
char ch;
for(lj = base_address; lj < fsize + base_address; lj = lj + block_size) // Test only blocks to be programmed
{
flash_write_cmd(0, 0x90);
flash_read_val(lj + 2); // read lock configuration (extra read to get JTAG pipeline going)
if(flash_read_val(lj + 2) == bothbanks(0x1)) {
printf("Block of Flash Memory is Write Locked, would you like to unlock it? [y/n]: ");
fread(&ch, 1, 1, stdin);
if(toupper(ch) == 'Y') {
printf("\nblock is locked\n");
flash_write_cmd(0, 0x60);
flash_write_cmd(lj, 0xd0);
printf("Unlocking block %3d \r",block_number++);
flash_wait(max_erase_time);
}
else
error_out("\nUnable to program Write Locked Flash Memory Block");
}
}
}
void set_lock_flash(long base_address, long fsize, long block_size, long max_erase_time, int block_number)
{
long lj;
printf("Starting set block lock bit\n");
for(lj = base_address; lj < fsize + base_address; lj = lj + block_size) // Erase only blocks to be programmed
{
flash_write_cmd(0, 0x60);
flash_write_cmd(lj, 0x1);
printf("Erasing block %3d \r",block_number++);
flash_wait(max_erase_time);
}
printf("Set lock bit done\n");
}
int main( int argc, char *argv[] )
{
char filename[MAX_IN_LENGTH];
int nblocks;
long max_erase_time, max_write_buffer, dsize, fsize = 0;
long last_non_zero = 0, last_non_ff = 0;
long base_address, block_size;
long li;
int block_number = 0;
char option = 'V';
printf("JFLASH Version xxx\n");
if(argc >= 2)
strcpy(filename,argv[1]);
else {
printf("jflash 'filename' ");
exit(-1);
}
if(argc >= 3)
option = toupper(*argv[2]);
if(argc >= 4)
block_number = atoi(argv[3]);
reset_port();
test_logic_reset();
id_command();
tap_submit_instr(BYPASS);
flash_write_cmd(0, 0x50);
flash_write_cmd(0, 0x98);
// To read data from the Flash Memory you must first fill the SA-1110 JTAG chain
// with the Address, then pump the entire chain out.
// however while pumping data out you can be pumping the next cycle's Address in
// Therefore the JTAG chain looks like a pipeline, valid read data always coming
// out one cycle late.
// Note that both Flash Memory devices are accessed in parallel (i.e. 32 data bits)
flash_read_val(0x10); // Test to see if the Flash supports Query Structured Output
if(flash_read_val(0x11) != bothbanks(0x51)) //Q
error_out("error reading flash attribute space\ncheck cables, power and flash sockets");
if(flash_read_val(0x12) != bothbanks(0x52)) //R
error_out("error reading flash attribute space R");
if(flash_read_val(0x25) != bothbanks(0x59)) //Y
error_out("error reading flash attribute space Y\n");
max_erase_time = flash_read_val(0x27); // "n" such that the max block erase time = 2^n
checkboth(max_erase_time, "max erase time");
max_erase_time = 1 << (max_erase_time & 0xffffL); // convert erase time 2^n to the number of sec
dsize = flash_read_val(0x2a); // "n" such that the device size = 2^n in number of bytes
checkboth(dsize, "device size");
dsize = 1 << (dsize & 0xffffL); // convert data size from 2^n to the number of bytes
max_write_buffer = flash_read_val(0x2d); // "n" such that the max num of bytes in write buffer = 2^n
checkboth(max_write_buffer, "write buffer size");
max_write_buffer = (1 << (max_write_buffer & 0xffffL)) / 2; // convert from 2^n bytes to the number of words
nblocks = flash_read_val(0x2e); // get the number of erase blocks in Flash - 1
checkboth(nblocks, "number of blocks");
nblocks = (nblocks & 0xffffL) + 1L; // need to add '1' for true number
if (option == 'R') {
if( (in_file = fopen(filename, "wb" )) == NULL)
error_out("error, can not open binary output file");
last_non_ff = dsize / 2;
}
else {
if( (in_file = fopen(filename, "rb" )) == NULL)
error_out("error, can not open binary input file");
while(1) {
fread((long *)&li, sizeof(long) , 1, in_file);
if(feof(in_file))break; // Any bytes not on a 4 byte boundry at end-of-file will be ignored
fsize++;
if(li != 0 && li != 0xffffffff) // Find point in file were only 0's and ff's remain
last_non_zero = fsize;
if(li != 0xffffffff) // Find point in file were only ff's remain
last_non_ff = fsize;
}
rewind(in_file);
}
if(fsize * 2 > dsize)
error_out("error, file size is bigger than device size");
fsize = last_non_ff; // Don't wast time programming ff's at the end of the file this is the erase state
block_size = dsize / 2 / nblocks;
base_address = block_number * block_size;
printf("Number of blocks in device = %d\n",nblocks);
printf("Block size = %ld 0x%lx\n",block_size,block_size);
printf("Device size = %ld 0x%lx\n",dsize,dsize);
if(block_number >= nblocks || block_number < 0)
error_out("error specifying block number");
#if 0
if(100 - (last_non_zero * 100)/last_non_ff > 20) {
printf("The last %2ld percent of image file is all zeros\n",100 - (last_non_zero * 100)/last_non_ff);
printf("Would you like to save time by not programming that area? [y/n]: ");
#if 1
exit(-1);
#else
if(toupper(_getche()) == 'Y')
fsize = last_non_zero;
#endif
}
printf("\n");
#endif
if(option == 'W') {
set_vppen();
test_lock_flash(base_address, fsize, block_size, max_erase_time, block_number);
//jca printf ("dont erase [%d]\n", __LINE__); exit(-1);
erase_flash(base_address, fsize, block_size, max_erase_time, block_number);
program_flash(max_write_buffer, base_address, fsize);
clr_vppen();
}
flash_write_val(0, bothbanks(0xff));
flash_read_val(base_address); //extra read to get the pipeline going
if(option != 'W') {
printf("verify base %lx size = %ld 0x%lx\n", base_address, fsize, fsize);
verify_flash(option != 'R', base_address, fsize);
}
fclose(in_file);
test_logic_reset();
reset_port();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -