📄 fl_wrt.c
字号:
/* write_sector
*
* This function writes the sector data from the image file to the specified
* device in the specified sector size. The module checks that all of the data
* is written before returning for the next sector write. The Block Lock bit
* is used to prevent unwanted writes. This means that before entry to this
* routine, all block lock bits must be cleared (since they can't be cleared
* individually), the block is then erased, the data are written, and the
* lock bit set again (on this block).
*
* We return the number of verify errors
*/
int write_sector(unsigned long base_address, unsigned long start_address,
int sector_size, unsigned int sector_data[])
{
int i;
volatile UNS_16 data;
int verify_errors = 0;
volatile unsigned int *source_word;
volatile unsigned int *dest_word;
volatile UNS_16 *source_half;
volatile UNS_16 *dest_half;
/* check that the sector size is not greater than the maximum */
if (sector_size > MAX_SECTOR_SIZE)
{
printf ("Error: Sector size too large\n");
return 1;
}
ASSERT(base_defined);
ASSERT(rom_identified);
/* if for some reason, we don't need to change anything,
* just set the block lock bit */
source_word = (volatile unsigned int *)sector_data;
dest_word = (volatile unsigned int *)start_address;
dest_half = (volatile UNS_16 *)start_address;
/* make sure we're in read array mode to start */
if (use_sync_interface)
data = *dest_half; /* clear any pending command return */
else
cmd_write(base_address, RESET_COM);
for (i = 0; i < (sector_size/4) && (verify_errors == 0); i++)
{
if (*dest_word++ != *source_word++) {
verify_errors++;
}
}
if (verify_errors) /* changes required */
{
verify_errors = 0;
if (use_sync_interface)
/* NOTE: currently only one algorithm supported */
{
/* erase the block */
sync_flash_command(BLK_ERASE_COM1, dest_half);
*dest_half = BLK_ERASE_COM2;
sync_wait_for_ready(dest_half);
/* Write the data in halfword steps */
source_half = (volatile unsigned short *)sector_data;
dest_half = (volatile unsigned short *)start_address;
for (i = 0;
i < (sector_size/sizeof(short)) ;
i++, source_half++, dest_half++)
{
/* fetch halfword, issue write command */
data = *source_half;
sync_flash_command(WRITE_COM, dest_half);
*dest_half = data;
sync_wait_for_ready(dest_half);
if (*source_half != *dest_half)
printf("Write data verify failed at 0x%x, src = 0x%x, dest = 0x%x\n",
(int)dest_half,*source_half, *dest_half);
}
}
else
{
/* if must unlock by sectors, unlock the sector */
if (sector_unlockable)
{
cmd_write(start_address, UNLOCK_COM1);
cmd_write(start_address, UNLOCK_COM2);
}
/* must erase the sector first */
wait_for_ready();
cmd_write(start_address, BLK_ERASE_COM1);
cmd_write(start_address, BLK_ERASE_COM2);
wait_for_ready();
/* Exit Read Status Mode */
cmd_write(base_address, RESET_COM);
if (device_code == SHARP_LH28F160S_ID)
{
/* Write the data in halfword steps */
source_half = (volatile unsigned short *)sector_data;
dest_half = (volatile unsigned short *)start_address;
for (i = 0; i < (sector_size/sizeof(short)) ;
i++, source_half++, dest_half++) {
// fetch halfword, issue write command
data = *source_half;
cmd_write(dest_half, WRITE_COM);
*dest_half = data;
// put chip in read status mode after write
cmd_write(dest_half, READ_STATUS_COM);
while (!(*dest_half & 0x80))
; // wait for done writing
// put chip back in read mode, check data written
cmd_write(base_address, RESET_COM);
if (*source_half != *dest_half)
printf("Write data verify failed at 0x%x\n",
(int)dest_half);
/* check bit 4 of status register for possible write fault */
cmd_write(base_address, READ_STATUS_COM);
if (read_status(base_address) & 0x10)
{
printf("Write error detected. Resetting status and aborting\n");
cmd_write(base_address, CLR_STATUS_COM);
cmd_write(base_address, RESET_COM);
exit(1);
}
}
}
else if (device_code == SHARP_LH28F800S_ID)
{
/* Write the data in halfword steps */
source_half = (volatile unsigned short *)sector_data;
dest_half = (volatile unsigned short *)start_address;
for (i = 0; i < (sector_size/sizeof(short)) ;
i++, source_half++, dest_half++) {
// fetch word, issue write command.
// write one half word
data = *source_half;
cmd_write(dest_half, WRITE_COM);
*((volatile unsigned int *)dest_half) = data;
source_half++;
dest_half++;
// write second half word
data = *source_half;
cmd_write(dest_half, WRITE_COM);
*((volatile unsigned int *)dest_half) = data;
// put chip in read status mode after the write
cmd_write(dest_half, READ_STATUS_COM);
while (!(*dest_half & 0x80))
; // wait for done writing
// set the pointers back where they started
source_half--;
dest_half--;
// put chip back in read mode, check data written
cmd_write(base_address, RESET_COM);
source_word = (volatile unsigned int *)source_half;
dest_word = (volatile unsigned int *)dest_half;
if (*source_word != *dest_word)
printf("Write data verify failed at 0x%x\n",
(int)dest_half);
}
}
else if (device_code == SHARP_LH28F320BJE_ID ||
device_code == SHARP_LH28F640BFE_PTTL_ID ||
device_code == SHARP_LH28F320BFE_PBTL_ID)
{
/* Write the data in halfword steps */
source_half = (volatile unsigned short *)sector_data;
dest_half = (volatile unsigned short *)start_address;
for (i = 0; i < (sector_size/sizeof(short)) ;
i++, source_half++, dest_half++) {
// fetch halfword, issue write command
data = *source_half;
cmd_write(dest_half, WRITE_COM);
*dest_half = data;
// put chip in read status mode after write
cmd_write(dest_half, READ_STATUS_COM);
while (!(*dest_half & 0x80))
; // wait for done writing
// put chip back in read mode, check data written
cmd_write(base_address, RESET_COM);
if (*source_half != *dest_half)
printf("Write data verify failed at 0x%x, src = 0x%x, dest = 0x%x\n",
(int)dest_half,*source_half, *dest_half);
/* check bit 4 of status register for possible write fault */
cmd_write(base_address, READ_STATUS_COM);
if (read_status(base_address) & 0x10)
{
printf("Write error detected. Resetting status and aborting\n");
cmd_write(base_address, CLR_STATUS_COM);
cmd_write(base_address, RESET_COM);
exit(1);
}
}
}
else
{
printf("invalid device code detected, exiting.\n");
exit(1);
}
/* restore rom to read mode */
cmd_write(base_address, RESET_COM);
}
/* Reread the sector and check it matches what we wrote */
source_word = (volatile unsigned int *)sector_data;
dest_word = (volatile unsigned int *)start_address;
for (i = 0;
i < (sector_size/sizeof(unsigned int)) && verify_errors < 10;
i++, source_word++, dest_word++)
{
if (*dest_word != *source_word)
{
printf("\nError: Verify Failed at address %08x (0x%08x != 0x%08x)\n",
(int)dest_word, *dest_word, *source_word);
verify_errors++;
}
}
}
if (!use_sync_interface)
{
/* Set the Block Lock bit */
cmd_write(start_address, LOCK_COM1);
cmd_write(start_address, LOCK_COM2);
wait_for_ready();
/* set device back in read mode */
cmd_write(base_address, RESET_COM);
}
/* Return the number of cycles required to write the data */
return verify_errors;
}
void wait_for_ready(void)
{
volatile short status;
/* wait for chip to become ready for data */
cmd_write(base_address, READ_STATUS_COM);
/* XXX - possible infinite loop! */
do
status = read_status(base_address);
while ((status & 0x80) == 0);
}
static void ShowROMIdentity()
{
IdentifyChip();
if (rom_identified)
{
printf ("Manufacturer: ");
if (manuf_code == MAN_SHARP)
printf ("SHARP\n");
else
printf ("(unknown)\n");
printf ("Device type: ");
switch (device_code)
{
case SHARP_LH28F160S_ID:
printf ("LH28F160S\n");
break;
case SHARP_LH28F320BJE_ID:
printf ("LH28F320BJE\n");
break;
case SHARP_LH28F640BFE_PTTL_ID:
printf ("LH28F640BFE_PTTL\n");
break;
case SHARP_LH28F320BFE_PBTL_ID:
printf ("LH28F320BFE_PBTL\n");
break;
default :
printf ("(unknown)\n");
break;
}
printf ("Sector size: %lu bytes\n", sector_size);
printf ("Total sectors: %lu\n", no_of_sectors);
printf ("ROM size: %lu bytes\n", sector_size * no_of_sectors);
printf ("Base Address: 0x%lx\n", base_address);
}
}
/* main
*
* This is the c library entry point and controlling function for
* the whole program. It checks that there is a specified file for
* download and then checks the identity of the flash device on
* board.. The external file is then opened and transferred to the
* flash memory in the required sectors
*/
int main(int argc, char *argv[])
{
int i;
#define GETARG(i) \
((argv[i][2] == '\0' && i < (argc+1)) ? argv[++i] : argv[i]+2)
for(i = 1; i < argc && argv[i][0]=='-'; i++)
{
switch (argv[i][1])
{
case 'v':
mode = op_verify;
break;
case 'w':
mode = op_writerom;
break;
case 'B':
mode = op_blank;
break;
case 'h':
mode = op_help;
break;
case 'I':
mode = op_identify;
break;
case 'V':
verbose = TRUE;
break;
case 't':
device_code = SHARP_LH28F160S_ID;
manuf_code = MAN_SHARP;
SetDeviceParams();
break;
case 'p':
interactive = TRUE;
break;
case 's':
start_sector = atol(GETARG(i));
start_defined = TRUE;
break;
case 'b':
base_address = atol(GETARG(i));
base_defined = TRUE;
break;
case 'S':
if (atol(GETARG(i)) != 16)
{
printf("only 16-bit sync-flash supported\n");
DisplayHelp();
exit(1);
}
use_sync_interface = TRUE;
base_address = SYNC_FLASH_BASE_ADDRESS;
base_defined = TRUE;
sync_base_defined = TRUE;
break;
default:
printf("Error: unknown option letter \"%c\"\n", argv[i][1]);
DisplayHelp();
exit(1);
}
}
if (!quiet)
printf("ARM Flash Programming Utility\n\n");
if (i < argc)
{
strcpy(filename, argv[i]);
file_defined = TRUE;
}
else
filename[0] = 0;
switch(mode)
{
case op_writerom:
DownloadFileToFlash();
break;
case op_blank:
BlankFlash();
break;
case op_verify:
VerifyFileInFlash();
break;
case op_help:
DisplayHelp();
break;
case op_identify:
ShowROMIdentity();
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -