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

📄 jflash.cpp

📁 亿道pxa255烧录Jflash源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
**  FILENAME:       Jflash.cpp
**
**  PURPOSE:        A utility to program Intel flash devices from a PC parallel port.
**
**  LAST MODIFIED:  2003.06.03 
******************************************************************************/
#include <stdio.h>
#include <time.h>
#ifdef __windows__
#include <windows.h>
#include <conio.h>
#else
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/perm.h>
#include <errno.h>
#define _getche getchar
#define BOOL	int
#define FALSE	0
#define TRUE	1
/* Some types */
typedef long DWORD;
typedef short WORD;
#endif

#include "Compile_switches.h"
#include "Jflash.h"
#include "xhyper255jtag.h"

#ifdef __linux__
/* in/out macros */
#include <asm/io.h>
#define _inp(a) inb(a)
#define _outp(a,d) outb(d,a)
#endif

/*
*******************************************************************************
Globals
*******************************************************************************
*/

int lpt_address;	// Global variable assigned to parallel port address

FILE *in_file;

int out_dat[MAX_DR_LENGTH];

int WORKBUF[XHYPER255_CHAIN_LENGTH];

#ifdef __linux__
int io_access_on( unsigned long port )
{
	if (ioperm (port, 3, 1)) {
		perror ("ioperm()");
		return 0;
	}
	if (ioperm (0x80, 1, 1)) {
		perror ("ioperm()");
		return 0;
	}
	return 1;
}

void io_access_off( unsigned long port )
{
	ioperm (port, 3, 0);
	ioperm (0x80, 1, 0);
}

#else
#define io_access_on(x) (1)
#define io_access_off(x)
#endif


/*
*******************************************************************************
Forward declarations
*******************************************************************************
*/

int putp(int,int, int); // writes the JTAG data on the parallel port
void id_command(void);	// issues the JTAG command to read the device ID for all 3 chips
void bypass_all(void);	// issues the JTAG command to put all 3 device in bypass mode
void extest(void);		// issues the JTAG command EXTEST to the Processor

#ifdef XHYPER255A
WORD access_rom(int, DWORD, WORD, int);		// Passes read/write/setup data for the Flash memory
#else
DWORD access_rom(int, DWORD, DWORD, int);	// Passes read/write/setup data for the Flash memory
#endif  

DWORD access_bus(int, DWORD, DWORD, int);	// Read/write access to the Processor pins

int test_port(void);	// Looks for and finds a valid parallel port address
int check_id(char*);	// Compares the device IDs for the 3 JTAG chips to expected values
void error_out(char*);	// Prints error and exits program
void erase_flash(DWORD, DWORD, DWORD, DWORD, int);
void program_flash(DWORD, DWORD, DWORD);
void verify_flash(DWORD, DWORD);
void test_logic_reset(void);
void test_lock_flash(DWORD, DWORD, DWORD, DWORD, int);
void set_lock_flash(DWORD, DWORD, DWORD, DWORD, int);
void set_address (DWORD);
int PZ_scan_code(int, int, int);
int controller_scan_code(int, int, int);
void pre_DRSCAN(void);
void post_DRSCAN(void);
void pre_IRSCAN(void);
void post_IRSCAN(void);
void mem_rw_mode(int);
void mem_data_driver(int);
void mem_write_enable(int);
void mem_output_enable(int);
void clear_chip_selects(void);
void set_chip_select(DWORD);
DWORD shift_data(int);
void set_data(DWORD);
void jtag_test(void);
void dump_chain(void);
void init_workbuf(void);
void invert_workbuf(void);
void set_pin_chip_select(DWORD);

void check_file_info(DWORD *fsize , DWORD *last_non_zero, DWORD *last_non_ff, DWORD rom_size);
void check_rom_info(DWORD *max_erase_time, DWORD * dsize, DWORD * max_write_buffer, DWORD * block_size, int * nblocks );
/*
*******************************************************************************
*
* FUNCTION:         main
*
* DESCRIPTION:      Entry point for utility
*
* INPUT PARAMETERS: uses optional input parameters:
*                       argv[1] = filename to flash (binary files only)
*                       argv[2] = program options, currently only 'P' for Program
*                       argv[3] = block number (used to compute base_address)    
*
* RETURNS:          void
*
*******************************************************************************
*/

//void main( int argc, char *argv[] )
int main( int argc, char *argv[] )
{
    time_t start;
	DWORD fsize = 0;
	DWORD last_non_zero = 0 ;
	DWORD last_non_ff = 0;
//	DWORD li;
	int block_number = 0;
    DWORD i;

    DWORD max_erase_time, dsize, max_write_buffer, block_size;
	int   nblocks;

    
    printf("JFLASH Version %s\n",VERSION);
    printf("COPYRIGHT (C) 2000, 2001 Intel Corporation\n");

#ifdef __windows__ 
    //Test operating system, if WinNT or Win2000 then get device driver handle
	OSVERSIONINFO osvi;
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osvi);
	if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
	{
        HANDLE h;

		h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,
					OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if(h == INVALID_HANDLE_VALUE)
			error_out("Couldn't access giveio device");
		CloseHandle(h);
	}
#endif


	lpt_address = test_port();	// find a valid parallel port address
	if(!lpt_address)
		error_out("Error, unable to find parallel port");

    test_logic_reset();
    jtag_test();
    
	char filename[MAX_IN_LENGTH];
	if(argc >= 2)
		strcpy(filename,argv[1]);
	else
		{
				
		printf("enter file: ");
		
		gets(filename);
		}

	test_logic_reset();

	id_command();
	bypass_all();
    //init_workbuf();

    test_logic_reset();

    check_rom_info(&max_erase_time, &dsize, &max_write_buffer, &block_size, &nblocks);
	
	if( (in_file = fopen(filename, "rb" )) == NULL)
    {
		error_out("error, can not open binary input file");
    }

	check_file_info(&fsize , &last_non_zero, &last_non_ff, dsize);
    
    // Don't wast time programming ff's at the end of the file this is the erase state
    fsize = last_non_ff;  

	if(argc >= 4)
    {
		block_number = atoi(argv[3]);
	}
    
    DWORD base_address = block_number * block_size; //the block_size is byte number, 
	                                                //the base_address is 16-bit word address for each device

  #ifdef XHYPER255B  
    printf("There are two 16-bit Flash devices in parallel\n\n");
#else
    printf("There is 16-bit Flash devices\n\n");
#endif
    
    printf("Characteristics for one device:\n");
	printf(" Number of blocks in device = %ld\n",nblocks);
	printf(" Block size = %ld 0x%lx word(16-bit)\n",block_size,block_size);
	printf(" Device size = %ld 0x%lx word(16-bit)\n\n",dsize,dsize);
    printf("Sample block to address list:\n\n");

    for (i = 0; i < 129; i += 40)
    { 
       #ifdef XHYPER255B 
        printf(" Block %d = hex address: %08X \n", i, i * block_size * 4); 
#else
        printf(" Block %d = hex address: %08X \n", i, i * block_size * 2); 
#endif
	
    }
    if(block_number >= nblocks || block_number < 0)
	{
    	error_out("error specifying block number");
    }

	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(toupper(_getche()) == 'Y')
			fsize = last_non_zero;
	}

	printf("\n");
	char option = 'P';
	if(argc >= 3)
	{
    	option = toupper(*argv[2]);
    }
	
    if(option == 'P')
	{

		test_lock_flash(base_address, fsize, block_size, max_erase_time, block_number);
		erase_flash(base_address, fsize, block_size, max_erase_time, block_number);
		program_flash(max_write_buffer, base_address, fsize);
	}

	access_rom(SETUP, 0, F_READ_ARRAY, IGNORE_PORT); // put back into read mode
	access_rom(WRITE, 0, F_READ_ARRAY, IGNORE_PORT);
	access_rom(HOLD, 0, F_READ_ARRAY, IGNORE_PORT);

	access_rom(READ, base_address, 0x0L, IGNORE_PORT); //extra read to get the pipeline going

	time(&start);

	verify_flash(base_address, fsize);

	fclose(in_file);

	test_logic_reset();
	test_logic_reset();
	test_logic_reset();
}

/*
*******************************************************************************
*
* FUNCTION:         get_rom_info
*
* DESCRIPTION:      get the flash information such as max erase time, flash size, 
*                   max write buffer, block number               
*                   
*
* INPUT PARAMETERS: DWORD *max_erase_time	: max erase time, number of seconds
*					DWORD *dsize			: each flash size, number of 16-bit word
*					DWORD *max_write_buffer : each flash max write buffer, number of 16-bit word
					DWORD *block_size		: each block size, number of 16-bit word
*					DWORD *nblocks			: number of erase blocks in each Flash*
					
* RETURNS:          None
*
* GLOBAL EFFECTS:   None
*
*******************************************************************************
*/
void check_rom_info(DWORD *max_erase_time, DWORD * dsize, DWORD * max_write_buffer, DWORD * block_size, int * nblocks )
{	access_rom(SETUP, 0, F_CLEAR_STATUS, IGNORE_PORT); // clear status register
	access_rom(WRITE, 0, F_CLEAR_STATUS, IGNORE_PORT);
	access_rom(HOLD, 0, F_CLEAR_STATUS, IGNORE_PORT);

	access_rom(SETUP, 0, F_READ_QUERY, IGNORE_PORT); // read query
	access_rom(WRITE, 0, F_READ_QUERY, IGNORE_PORT);
	access_rom(HOLD, 0, F_READ_QUERY, IGNORE_PORT);

	// To read data from the Flash Memory you must first fill the processor 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)
    
    // Test to see if the Flash supports Query Structured Output
	access_rom(READ, 0x10, 0, IGNORE_PORT);  
	
    #ifdef DEBUG
    printf("about to read flash attributes....\n");
    #endif
    
    if(access_rom(READ, 0x11, 0, READ_PORT) != F_ATTR_Q) //Q
    {
	error_out("error reading flash attribute space!!!\ncheck cables, power and flash sockets");
    }
	if(access_rom(READ, 0x12, 0, READ_PORT) != F_ATTR_R) //R
	{
    	error_out("error reading flash attribute space R");
	}
        if(access_rom(READ, 0x25, 0, READ_PORT) != F_ATTR_Y) //Y
	{
    	error_out("error reading flash attribute space Y\n");
        }

            
    // "n" such that the max block erase time = 2^n
	*max_erase_time = access_rom(READ, 0x27, 0, READ_PORT);  

#ifdef XHYPER255B
	if((*max_erase_time & 0xffffL) != (*max_erase_time >> 16)) // both devices should be the same time
	{
    	error_out("error, max erase time of E11 and E12 are different");
    	}
#endif

    // convert erase time 2^n to the number of seconds
    *max_erase_time = 1 << (*max_erase_time & 0xffffL);  

    // "n" such that the device size = 2^n in number of bytes
	*dsize = access_rom(READ, 0x2a, 0, READ_PORT);  

#ifdef XHYPER255B
	if((*dsize & 0xffffL) != (*dsize >> 16)) // both devices should be the same size
	{
    	error_out("error, device size of E11 and E12 are different");
	}
#endif

    // convert data size from 2^n to the number of bytes
    *dsize = 1 << (*dsize & 0xffffL);  

    // "n" such that the max num of bytes in write buffer = 2^n
	*max_write_buffer = access_rom(READ, 0x2d, 0, READ_PORT);  

#ifdef XHYPER255B
	if((*max_write_buffer & 0xffffL) != (*max_write_buffer >> 16)) // both devices should have the same write buffer size
	{
    	error_out("error, write buffer size of E11 and E12 are different");
	}
#endif

    // convert from 2^n bytes to the number of byte
    *max_write_buffer = (1 << (*max_write_buffer & 0xffffL));  

    // get the number of erase blocks in Flash - 1
	*nblocks = access_rom(READ, 0x2e, 0, READ_PORT);

#ifdef XHYPER255B
	if((*nblocks & 0xffffL) != (*nblocks >> 16))	// both devices should have the same number
	{
    	error_out("error, number of blocks of E11 and E12 are different");
	}
#endif

    *nblocks = (*nblocks & 0xffffL) + 1L;  // need to add '1' for true number

	*block_size = (*dsize) / (*nblocks);

	//change the dsize, max_write_buffer, block_size from byte number to 16-bit word number
	*dsize = *dsize / 2;
	*max_write_buffer = *max_write_buffer / 2;
	*block_size = *block_size / 2;
}

/*
*******************************************************************************
*
* FUNCTION:         check_file_info
*
* DESCRIPTION:      get the file information and check with rom size
*                   
*
* INPUT PARAMETERS: DWORD *fsize	: file size
		DWORD *last_non_zero	: the point where only 0 or FF remain
		DWORD *last_non_ff	: the point where only ff remain
									
	if LUBBOCK_SABINAL is defined, the upper 3 parameters are in 16-bit word number
	else they are in 32-bit DWORD number

		DWORD rom_size		: the rom size in 
* RETURNS:          None
* GLOBAL EFFECTS:   None
*******************************************************************************
*/
void check_file_info(DWORD *fsize , DWORD *last_non_zero, DWORD *last_non_ff, DWORD rom_size)
{	BUS_GRAIN li;
		
	for(;;)
	{
		int n = fread((BUS_GRAIN *)&li, sizeof(BUS_GRAIN) , 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 != -1) // Find point in file were only 0's and ff's remain
		{						// For 32 bit data bus, -1 is 0xffffffff, for 16 bit data bus -1 is 0xffff
        	*last_non_zero = *fsize;
        }
		if(li != -1)  // Find point in file were only ff's remain
		{
        	*last_non_ff = *fsize;
        }
	}
	

	rewind(in_file);

#ifdef XHYPER255B
	// if 32-bit data width used. It assume 2 16-bit flash installed. each flash size=fsize
	if ((*fsize) * 2 > rom_size * 2)
		error_out("error, file size is bigger than device size");
#else
	// if SABINAL 16-bit data width used, it assume only one 16-bit flash installed
	if ((*fsize) > rom_size)
		error_out("error, file size is bigger than device size");
#endif
}


/*
*******************************************************************************
*
* FUNCTION:         putp
*
* DESCRIPTION:      Drives TCK, TDI, and TMS signals and reads TDO signal 
*                   via _outp and _inp calls.
*                   
*                   Cable used had 100 ohm resistors between the following pins
*                   (Cable shipped as part of SA-1110 Development Kit)
*                   Output pins (LPT driving)
*                       LPT D0 Pin 2 and TCK J10 Pin 4
*                       LPT D1 Pin 3 and TDI J10 Pin 11
*                       LPT D2 Pin 4 and TMS J10 Pin 9
*
*                   Input pin (SA-1110 board drives)
*                       LPT Busy Pin 11 and TDO J10 Pin 13
*                   
*                   
*
* INPUT PARAMETERS: int tdi - test data in
*
* RETURNS:          int - TDO (Test Data Out)
*
* GLOBAL EFFECTS:   None

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -