⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jflash.c

📁 samsung s3c2410 烧写文件
💻 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 + -