/* ST20 Tools Standard Includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* GLC includes */
#include "types.h"
#include "target.h"
#include "ilut.h"
#include "auxdat.h"
#include "asc.h"
#include "error.h"
#include "os.h"
#include "cons.h"
#include "pio.h"
#include "eeprom.h"
#include "nvman.h"
#include "flash.h"
#include "ttool.h"
#include "i2c.h"
#include "idchip.h"
#include "tm.h"
#include "mtst.h"
#define MAX_BYTES_PER_ROW 32
#define MAX_STRING_LENGTH 104
#define AMD_BASE1 0x7FF00000 /* start
of flash memory */
#define AMD_BASE2 0x7F700000 /* start
of flash memory */
#define DATA32_A 0xaaaaaaaa
#define DATA32_5 0x55555555
#define MASK_BIT7 0x80808080
#define MASK_A0
0xa0a0a0a0
typedef struct hex_rom_struct
{
int
entries;
unsigned int address;
int
row[16];
} HEX_ROM_STRUCT;
int init_sys(void);
int flash_boot(char*);
int flash_app(FlashDevice_t, char*);
void program_row(HEX_ROM_STRUCT row, int);
NVMan_t nvman;
FlashDevice_t flashdevA;
FlashDevice_t flashdevB;
unsigned long crc32(unsigned char*, unsigned long);
int main(int argc, char* argv[])
{
int
errorwarn = NO_ERROR; /* Set to !NO_ERROR, if any error */
int
i, result;
char
flashpairAfilename[32]; /* boot file name
*/
char
flashpairBfilename[32]; /* boot file name
*/
char
app[32]; /* app file name
*/
BYTE
data[1024];
SectorParams_t params;
int
count;
if ( init_sys() )
{
exit(-1);
}
printf("\n\n==============================================\n");
printf("\n
Set-Top Box Flash Program.\n");
printf("\n==============================================\n\n");
flashpairAfilename[0] = '\0';
flashpairBfilename[0] = '\0';
app[0] = '\0';
/* Read the input filenames from the command line and
store them
in strings for fopen. */
i = 1;
while(i < argc)
{
if ( strcmp(argv[i], "-b1") ==
0 && i+1 < argc )
{
sprintf(flashpairAfilename, "%s.hex", argv[i+1]);
i += 2;
}
else if ( strcmp(argv[i], "-b2")
== 0 && i+1 < argc )
{
sprintf(flashpairBfilename, "%s.hex", argv[i+1]);
i += 2;
}
else if ( strcmp(argv[i], "-r")
== 0 && i+1 < argc )
{
sprintf(app, "%s.rsc", argv[i+1]);
i += 2;
}
else
{
printf("------------------------------------------\n");
printf("Usage:
flash.lku -b1 <BankA Hex filename> -b2 <BankB Hex filename> -r
<Resident App filename>\n");
printf("(In the
switches, do not type the extensions or the dot)\n");
printf("------------------------------------------\n\n");
exit(-1);
}
}
memset(data, 0, 1024);
printf("\nErase All EEPROM .....\n");
nvman->eepromWrite(nvman, data, 0, 1024);
printf("\nErasing all sectors in Flash Pair A.....");
fflush(stdout);
result = flashdevA->erase(flashdevA, 0xFF);
if (result != NO_ERROR)
{
printf("****Error erasing flash****\n");
errorwarn = !NO_ERROR;
}
/* In the 830, all Flash is in TP 3 Region 3 Bank 3 */
printf("\nErasing all sectors in Flash Pair B.....");
fflush(stdout);
result = flashdevB->erase(flashdevB, 0xFF);
if (result != NO_ERROR)
{
printf("****Error erasing flash****\n");
errorwarn = !NO_ERROR;
}
if (strlen(flashpairBfilename))
{
/* In the 830, all Flash is
in TP 3 Region 3 Bank 3 */
printf("\nFlashing Pair A for boot .....");
result = flash_boot(flashpairBfilename);
if (result == NO_ERROR)
{
printf("\nPair A
flashed for boot.");
}
else
{
printf("\nError flashing
Pair A for boot.");
errorwarn =
!NO_ERROR;
}
fflush(stdout);
}
if ( strlen(flashpairAfilename) )
{
printf("\nFlashing Pair B for boot .....");
result = flash_boot(flashpairAfilename);
if (result == NO_ERROR)
{
printf("\nPair B
flashed for boot.");
}
else
{
printf("\nError flashing
Pair B for boot.");
errorwarn =
!NO_ERROR;
}
fflush(stdout);
}
if ( strlen(app) )
{
printf("\nFlashing resident application
in Pair A.....");
result = flash_app(flashdevA, app);
if (result == NO_ERROR)
{
printf("\nResident
application flashed in Pair A.");
}
else
{
printf("\nError flashing
the Resident application in Pair A.");
errorwarn =
!NO_ERROR;
}
fflush(stdout);
}
if (errorwarn)
{
printf("\nDone. Error(s) occurred.\n");
}
else
{
printf("\nFlash complete. No errors
detected.\n");
}
exit (result);
}
int init_sys(void)
{
error_t result;
I2c_t
I2c;
Asc_t
Asc;
EepromDevice_t Eeprom;
IdChip_t IdChip;
Os_t
Os;
Tm_t
Tm;
Cons_t
Cons;
Ilut_t
Ilut;
/*
** create the ILUT
*/
result = IlutCreate(&Ilut);
result = OsCreate(&Os, "FLASH OS", 1);
Os->start(Os);
/*
** create the ID chip, we may need info from it
*/
result = IdChipCreate(&IdChip, IDCHIP_LOOKUP);
result = TmCreate(&Tm, TM_LOOKUP);
/*
** create an asc on the console port if not already done
*/
result = AscCreate(&Asc,
/* asc instance name */
CONS_ASC_LOOKUP,
CONS_ASC_NUM, /* Instance of ASC HW we
control */
CONS_ASC_INTR_LEVEL,/* from glcemb\target.h */
CONS_BAUD_RATE, /* baud rate */
CONS_DATA_BITS, /* 8 data bits */
CONS_PARITY, /* no parity */
CONS_STOP_BITS, /* 1.0 stop bits */
FALSE,
/* do not use flow control */
CONS_BUFFER_SIZE); /* 128 byte receive buffer */
result = ConsCreate(&Cons, CLI_CONS_LOOKUP, CONS_IF_TYPE_ASC);
/*
** default printing to the cliConsole
*/
Cons->setPrint(Cons);
I2cCreate(&I2c,
"I2c0",
I2C0,
/* the one connected to micro */
I2C0_INTR_LEVEL, /*
from glcemb\target.h */
FALSE,
/* slow mode == 100kbps */
3);
/* max 3 retries */
result = EepromCreate(&Eeprom, EEPROM_LOOKUP, 0);
result = FlashCreate(&flashdevA, FLASH_LOOKUP, AMD_BASE1,
TRUE);
result = FlashCreate(&flashdevB, "flashdevB", AMD_BASE2,
TRUE);
result = NVManCreate(&nvman, NVMAN_LOOKUP);
return 0;
}
/*
Programs the flash banks. In the 830, both Flash addresses are
in Region 3, Bank 3 of the TP3 Memory Map.
*/
int flash_boot(char* boot)
{
FILE
*boot_fp; /* boot file descriptor */
HEX_ROM_STRUCT rom_data;
char
raw_data[MAX_STRING_LENGTH];
int
entries, rows;
boot_fp = fopen(boot, "r");
if (boot_fp == NULL)
{
fprintf(stderr, "boot flash: cannot
open data file %s\n", boot);
return -1;
}
printf("boot flash: data file %s opened\n",boot);
/************************************************************************
* read lines from the hex datafile, this has the following
syntax:
*
* address 1{byte}32
*
* where n{...}m means at least n terms and no more than
m
*/
rows = 0;
while (1)
{
/* Design a loop to simply read in
sixteen represented bytes and
stuff in the addresses
that sscanf expects. */
inint = fgetc(boot_fp);
if (inint == EOF)
{
fprintf(stderr,
"boot flash: data file %s ended unexpectedly.\n", boot);
return(-1);
}
inch = (unsigned char)inint;
fprintf(stderr, "boot flash: data file %s did not contain a quantity of bytes
to be programmed divisible by sixteen.\n", boot);
if (fgets(raw_data, MAX_STRING_LENGTH,
boot_fp) == NULL)
{
/* Should only hit
newlines, and not hit the end of the file,
from
checking the hex file we will be using. According to ANSI C,
fgets
does not return NULL due to hitting a newline.
Thus
variable length lines should not pose a problem.
*/
break;
}
/* Some of the line lengths in the
hex file might be shorter than
32 depicted bytes of data.
*/
/* According to ANSI C, if fgets reaches
a newline within the length
that it is told to get,
it will include the newline at the end of
the string and then stop
there. */
/* So, strip-off newline chars from
the end of the string of raw data
that fgets returns, if
there were any. */
i = strlen(raw_data)-1;
while (
(raw_data[i]
== 0x0A)
||
(raw_data[i]
== 0x0D)
)
{
raw_data[i]
= 0;
i -= 1;
}
/* Add code to check for EOF from sscanf
*/
entries = sscanf(raw_data,
"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x
%x %x %x %x %x %x %x %x %x",
&rom_data.address,
&rom_data.row[0],
&rom_data.row[1],
&rom_data.row[2],
&rom_data.row[3],
&rom_data.row[4],
&rom_data.row[5],
&rom_data.row[6],
&rom_data.row[7],
&rom_data.row[8],
&rom_data.row[9],
&rom_data.row[10],
&rom_data.row[11],
&rom_data.row[12],
&rom_data.row[13],
&rom_data.row[14],
&rom_data.row[15],
&rom_data.row[16],
&rom_data.row[17],
&rom_data.row[18],
&rom_data.row[19],
&rom_data.row[20],
&rom_data.row[21],
&rom_data.row[22],
&rom_data.row[23],
&rom_data.row[24],
&rom_data.row[25],
&rom_data.row[26],
&rom_data.row[27],
&rom_data.row[28],
&rom_data.row[29],
&rom_data.row[30],
&rom_data.row[31],
&rom_data.row[32]);
/* don't count address, 0 <=
rom_data.entries <= 32 */
rom_data.entries = entries - 1;
/**********************************************************************
* If we read some data,
either program or verify it
*/
if (rom_data.entries > 0)
{
program_row(rom_data,
bank);
if ((rows++
% 0x100) == 0)
{
printf("flash: Programmed upto 0x%x\r", rom_data.address);
fflush(stdout);
}
}
}
fclose(boot_fp);
printf("\nflash: Operation complete\n");
return 0;
}
/* programs a row from the bank?.hex file. The bank? file
name is incorrect. The hardware banks are 3 and 1. So
bank1 from command line refers to bank3 in hardware.
Bank2 from command line refers to bank1 in hardware. */
void program_row(HEX_ROM_STRUCT row, int bank)
{
int i;
long data;
long *base;
base = (long *)(row.address); /* initialise address
pointer */
for (i = 0; i < (row.entries/4); i++)
{
data=(long)row.row[i*4]+
((long)(row.row[(i*4)+1])<<8)+
((long)(row.row[(i*4)+2])<<16)+
((long)(row.row[(i*4)+3])<<24);
if ( bank == 1 )
{
/* program the flash word. Address offset is shifted 2 bits to
the left to account for A0,A1 from bus not connected, A2 - A19
from bus are connected to flash'es A0 - A17. 5555 -> 15555,
2AAA -> AAAA */
*((volatile unsigned long *) FLASH_BASEA + 0x15555) = DATA32_AA;
*((volatile unsigned long *) FLASH_BASEA + 0xAAAA) = DATA32_55;
*((volatile unsigned long *) FLASH_BASEA + 0x15555) = DATA32_A0;
*((volatile unsigned long *) base) = data;
}
else if (bank == 2 )
{
/* program the flash word. Address offset is shifted 2 bits to
the left to account for A0,A1 from bus not connected, A2 - A19
from bus are connected to flash'es A0 - A17. 5555 -> 15555,
2AAA -> AAAA*/
*((volatile unsigned long *) FLASH_BASEB0 + 0x15555) = DATA32_AA;
*((volatile unsigned long *) FLASH_BASEB0 + 0xAAAA) = DATA32_55;
*((volatile unsigned long *) FLASH_BASEB0 + 0x15555) = DATA32_A0;
*((volatile unsigned long *) base) = data;
}
else
{
/* program the flash word. Address offset is shifted 2 bits to
the left to account for A0,A1 from bus not connected, A2 - A19
from bus are connected to flash'es A0 - A17. 5555 -> 15555,
2AAA -> AAAA*/
*((volatile unsigned long *) FLASH_BASEB1 + 0x15555) = DATA32_AA;
*((volatile unsigned long *) FLASH_BASEB1 + 0xAAAA) = DATA32_55;
*((volatile unsigned long *) FLASH_BASEB1 + 0x15555) = DATA32_A0;
*((volatile unsigned long *) base) = data;
}
/* poll for completion */
while ((*((volatile unsigned long
*) base) & MASK_BIT7) != (data & MASK_BIT7))
{
;
}
if (*((volatile unsigned long *)base)
!= data)
printf("\nProgram failed
at address %x : read %x but expected %x\n",(int)base,(int)*((volatile unsigned
long *) base),(int)data);
base++;
}
}
int flash_app(FlashDevice_t fl_ptr, char* app)
{
FILE
*app_fp; /* boot file descriptor */
long
*data;
int
re, len;
SectorParams_t params;
int
count;
unsigned long crc1, crc2;
int
len1;
unsigned char c1, c2, c3, c4;
unsigned char* s;
fl_ptr->getSectorParams(fl_ptr, ¶ms, &count);
app_fp = fopen(app, "rb");
if (app_fp == NULL)
{
printf("flash: cannot open data
file %s\n", app);
return -1;
}
re = fseek(app_fp, 0L, SEEK_END);
if (re)
{
printf("flash: cannot fseek data
file %s\n", app);
return -1;
}
len = (int) ftell(app_fp);
if (len <=0)
{
printf("flash: cannot read data
file %s\n", app);
return -1;
}
re = fseek (app_fp, 0L, SEEK_SET);
if (re)
{
printf("flash: cannot fseek data
file %s\n", app);
return -1;
}
s = (unsigned char*) malloc(len);
re = fread(s, 1, len, app_fp);
if ( re != len )
{
printf("flash: cannot read data
file %s\n", app);
return -1;
}
c1 = s[0]; c2 = s[1]; c3 = s[2]; c4 = s[3];
crc1 = c1 << 24 | c2 << 16 | c3 << 8
| c4;
c1 = s[4]; c2 = s[5]; c3 = s[6]; c4 = s[7];
len1 = c1 << 24 | c2 << 16 | c3 << 8
| c4;
if ( len1 != len-8 )
{
printf("flash: the resident (%s)
image is NOT good!\n", app);
return -1;
}
crc2 = crc32(s+8, len1);
if ( crc1 != crc2 )
{
printf("flash: the resident (%s)
image is NOT good!\n", app);
return -1;
}
free(s);
if ( len % 4 == 0 )
len = len / 4;
else
len = len / 4 + 1;
data = (long*) malloc(len*4);
if (data == NULL)
{
printf("flash: cannot alloc memory
for data file %s\n", app);
return -1;
}
re = fseek (app_fp, 0L, SEEK_SET);
if (re)
{
printf("flash: cannot fseek data
file %s\n", app);
return -1;
}
re = fread(data, 4, len, app_fp);
if ( re != len )
{
printf("flash: cannot read data
file %s\n", app);
return -1;
}
/* addr = 0x7FF00000; */
/* Flash resident application from the first sector */
/* re = flash->program(flash, (long*)addr, data, len);
*/
re = fl_ptr->program(fl_ptr, (long*)params->sctrAddr,
data, len);
if ( re != SUCCESS )
{
printf("flash: cannot write data
file to FLASH %s\n", app);
return -1;
}
free(data);
fclose(app_fp);
s = (unsigned char*)params->sctrAddr;
c1 = s[0]; c2 = s[1]; c3 = s[2]; c4 = s[3];
crc1 = c1 << 24 | c2 << 16 | c3 << 8
| c4;
c1 = s[4]; c2 = s[5]; c3 = s[6]; c4 = s[7];
len1 = c1 << 24 | c2 << 16 | c3 << 8
| c4;
crc2 = crc32(s+8, len1);
if ( crc1 != crc2 )
{
printf("flash: Flashing resident
(%s) image failed!\n", app);
return -1;
}
return 0;
}
#define CAL_CRC(A) crc = (crc << 4) ^ crc_mask[((crc >> 28) ^
\
((unsigned long)A >> 4)) & 0x0f], \
crc = (crc << 4) ^ crc_mask[((crc >> 28) ^ \
((unsigned long)A)) & 0x0f]
unsigned long crc32(unsigned char* data, unsigned long length)
{
unsigned long i;
unsigned long crc;
unsigned char *ptr;
static const unsigned long crc_mask[] =
{
0x00000000L,
0x04c11db7L,
0x09823b6eL,
0x0d4326d9L,
0x130476dcL,
0x17c56b6bL,
0x1a864db2L,
0x1e475005L,
0x2608edb8L,
0x22c9f00fL,
0x2f8ad6d6L,
0x2b4bcb61L,
0x350c9b64L,
0x31cd86d3L,
0x3c8ea00aL,
0x384fbdbdL
};
/* init the start value */
crc = 0xffffffffL;
ptr = data;
for (i = 0; i<length; i++)
{
CAL_CRC(ptr[i]);
}
return crc;
}
back
First posted Oct 30, 2003