📄 jflash.cpp
字号:
mem_data_driver(DRIVE);
set_pin_chip_select(address);
set_data(data);
}
//----------------------------------------------
if(rw == SETUP || rw == HOLD) // just like a write except WE, WE needs setup time
{
#ifdef DEBUG
printf("Setup or Hold Mode\n");
#endif
mem_output_enable(DISABLE);
mem_data_driver(DRIVE);
set_data(data);
}
//----------------------------------------------
if(rw == RS) // setup prior to RD_nWR_OUT
{
#ifdef DEBUG
printf("RS Mode\n");
#endif
mem_output_enable(DISABLE);
}
// Common finish
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,1,IP); //select DR scan
putp(1,0,IP); //capture DR
putp(1,0,IP); //shift IR
#ifdef ASSABET_PLATFORM
int out_dat[300];
for(i = 0; i < 291; i++) // shift write data in to JTAG port and read data out
out_dat[i] = putp(pin[i],0,rp);
#endif
#ifndef ASSABET_PLATFORM
int out_dat[400];
for(i = 1; i < 384; i++) // shift write data in to JTAG port and read data out
out_dat[i] = putp(pin[i-1],0,rp);
// fudge factor because chain appears to be shifted by 1
// DEBUG LATER
putp(pin[0], 0, rp);
#endif
// if ASSABET defined and NOT LUBBOCK_SA1110
#ifdef ASSABET_PLATFORM
#ifndef LUBBOCK_SA1110
putp(0,0,IP); // extra clicks for the CPLDs
putp(0,0,IP);
#endif
#endif
#ifdef SANDGATE_PLATFORM
putp(0,0,IP); // extra clicks for the CPLDs
putp(0,0,IP);
#endif
putp(0,1,IP); //Exit1-DR
putp(1,1,IP); //Update-DR
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
DWORD busdat = 0;
for(i = 0; i < 32; i++) // convert serial data to single DWORD
{
#ifdef ASSABET_PLATFORM
busdat = busdat | (DWORD)(out_dat[dat_order[i] - 2] << i);
#endif
#ifdef LUBBOCK_PLATFORM
busdat = busdat | ((DWORD)(out_dat[input_dat_order[i]] << i));
#endif
#ifdef SANDGATE_PLATFORM
// mysterious behavior here. There should be a "-2" compensation
// here like the ASSABET_PLATFORM. DEBUG THIS LATER BUT IT WORKS FOR NOW.
busdat = busdat | ((DWORD)(out_dat[input_dat_order[i] ] << i));
#endif
}
extest();
#ifdef DEBUG
printf("just before return\n");
dump_chain();
#endif
return(busdat);
}
/*
*******************************************************************************
*
* FUNCTION: test_port
*
* DESCRIPTION: Searches for a valid parallel port
*
* INPUT PARAMETERS: void
*
* RETURNS: int - Address of the port or zero if none available
*
*******************************************************************************
*/
#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
int test_port(void)
{
// search for valid parallel port
if(io_access_on(LPT1))
{
_outp(LPT1, 0x55);
if((int)_inp(LPT1) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT1);
#endif
return LPT1;
}
io_access_off(LPT1);
}
if(io_access_on(LPT2))
{
_outp(LPT2, 0x55);
if((int)_inp(LPT2) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT2);
#endif
return LPT2;
}
io_access_off(LPT2);
}
if(io_access_on(LPT3))
{
_outp(LPT3, 0x55);
if((int)_inp(LPT3) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT3);
#endif
return LPT3;
}
io_access_off(LPT3);
}
return(0); // return zero if none found
}
/*
*******************************************************************************
*
* FUNCTION: check_id
*
* DESCRIPTION: Compare an ID string returned from the device with the expected string.
*
* INPUT PARAMETERS: char * device_id - a pointer to the string returned from the device
*
* RETURNS: int - 0 if ID matches expected, -1 if a match fails
*
*******************************************************************************
*/
int check_id(char *device_id)
{
// compare passed device ID to the one returned from the ID command
char in_id[40];
BOOL error_flag = FALSE;
for(int i = 34; i >= 0; i--)
{
// skip over the spaces in the ID string
if(i == 4 || i == 21 || i == 33)
{
in_id[i] = ' ';
i--;
}
if(putp(1,0,READ_PORT) == 0)
in_id[i] = '0';
else
in_id[i] = '1';
if((in_id[i] != *(device_id + i)) && (*(device_id + i) != '*'))
{
error_flag = TRUE;
}
}
in_id[35] = 0;
#ifdef DEBUG
if(error_flag)
{
printf("error, failed to read device ID\n");
printf("check cables and power\n");
printf("ACT: %s\n",in_id);
printf("EXP: %s\n\n",device_id);
return -1;
}
#endif
#ifdef ASSABET_PLATFORM
if(!strcmp(device_id,SA1110ID)) // print SA-1110 device revision
{
int sa_rev =
(int)(in_id[0] - '0') * 8 +
(int)(in_id[1] - '0') * 4 +
(int)(in_id[2] - '0') * 2 +
(int)(in_id[3] - '0');
switch(sa_rev)
{
case 0: printf("SA-1110 revision A0\n"); break;
case 4: printf("SA-1110 revision B0\n"); break;
case 5: printf("SA-1110 revision B1\n"); break;
case 6: printf("SA-1110 revision B2\n"); break;
case 8: printf("SA-1110 revision B4\n"); break;
default: printf("SA-1110 revision B4 + %d\n",sa_rev - 8);
}
}
#endif
#ifdef SANDGATE_PLATFORM
if(!strcmp(device_id, COTULLAID)) // print Cotulla device revision
{
int sa_rev =
(int)(in_id[0] - '0') * 8 +
(int)(in_id[1] - '0') * 4 +
(int)(in_id[2] - '0') * 2 +
(int)(in_id[3] - '0');
switch(sa_rev)
{
case 0: printf("PXA250 revision A0\n\n"); break;
case 1: printf("PXA250 revision A1\n\n"); break;
case 2: printf("PXA250 revision B0\n\n"); break;
case 3: printf("PXA250 revision B1\n\n"); break;
case 4: printf("PXA250 revision ??\n\n"); break;
case 5: printf("PXA250 revision ??\n\n"); break;
case 6: printf("PXA250 revision ??\n\n"); break;
case 8: printf("PXA250 revision ??\n\n"); break;
default: printf("PXA250 revision ?? + %d\n\n",sa_rev - 8);
}
}
#endif
#ifdef LUBBOCK_PLATFORM
#if !defined(LUBBOCK_SABINAL) && !defined(LUBBOCK_DALHART_16)
if(!strcmp(device_id, COTULLAID)) // print Cotulla device revision
{
int sa_rev =
(int)(in_id[0] - '0') * 8 +
(int)(in_id[1] - '0') * 4 +
(int)(in_id[2] - '0') * 2 +
(int)(in_id[3] - '0');
switch(sa_rev)
{
case 0: printf("PXA250 revision A0\n\n"); break;
case 1: printf("PXA250 revision A1\n\n"); break;
case 2: printf("PXA250 revision B0\n\n"); break;
case 3: printf("PXA250 revision B1\n\n"); break;
case 4: printf("PXA250 revision B2\n\n"); break;
case 5: printf("PXA250 revision ??\n\n"); break;
case 6: printf("PXA250 revision ??\n\n"); break;
case 8: printf("PXA250 revision ??\n\n"); break;
default: printf("PXA250 revision ?? + %d\n\n",sa_rev - 8);
}
}
#endif
#endif
#if defined(LUBBOCK_SABINAL) || defined(LUBBOCK_DALHART_16)
if((!strcmp(device_id, SABINALID))||(!strcmp(device_id, COTULLAID))) // print SABINAL device revision
{
int sa_rev =
(int)(in_id[0] - '0') * 8 +
(int)(in_id[1] - '0') * 4 +
(int)(in_id[2] - '0') * 2 +
(int)(in_id[3] - '0');
switch(sa_rev)
{
#ifdef LUBBOCK_SABINAL
case 0: printf("PXA210 revision A0\n\n"); break;
case 1: printf("PXA210 revision A1\n\n"); break;
case 2: printf("PXA210 revision B0\n\n"); break;
case 3: printf("PXA210 revision B1\n\n"); break;
case 4: printf("PXA210 revision B2\n\n"); break;
case 5: printf("PXA210 revision ??\n\n"); break;
case 6: printf("PXA210 revision ??\n\n"); break;
case 8: printf("PXA210 revision ??\n\n"); break;
default: printf("PXA210 revision ?? + %d\n\n",sa_rev - 8);
#else
case 0: printf("DALHART 16 revision A0\n\n"); break;
case 1: printf("DALHART 16 revision A1\n\n"); break;
case 2: printf("DALHART 16 revision B0\n\n"); break;
case 3: printf("DALHART 16 revision B1\n\n"); break;
case 4: printf("DALHART 16 revision B2\n\n"); break;
case 5: printf("DALHART 16 revision ??\n\n"); break;
case 6: printf("DALHART 16 revision ??\n\n"); break;
case 8: printf("DALHART 16 revision ??\n\n"); break;
default: printf("DALHART 16 revision ?? + %d\n\n",sa_rev - 8);
#endif
}
}
#endif
return 0;
}
/*
*******************************************************************************
*
* FUNCTION: error_out
*
* DESCRIPTION: generic error printout and program exit.
*
* INPUT PARAMETERS: char * error_string to print before exit
*
* RETURNS: void
*
* GLOBAL EFFECTS: Exits the program
*******************************************************************************
*/
void error_out(char *error_string)
{
printf("%s\n",error_string);
exit(0);
}
/*
*******************************************************************************
*
* FUNCTION: erase_flash
*
* DESCRIPTION: erases a selected number of flash blocks
*
* INPUT PARAMETERS: DWORD base_address of flash device
* 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -