forked from len0rd/rockbox
Massive code-policing. Use proper indent. Use proper comments. Use proper
source code width. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3857 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
bf6481e79d
commit
754426e11f
1 changed files with 490 additions and 468 deletions
|
@ -35,31 +35,30 @@
|
||||||
#define UINT32 unsigned long
|
#define UINT32 unsigned long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// hard-coded values
|
/* hard-coded values */
|
||||||
static volatile UINT8* FB = (UINT8*)0x02000000; // Flash base address
|
static volatile UINT8* FB = (UINT8*)0x02000000; /* Flash base address */
|
||||||
#define SECTORSIZE 4096 // size of one flash sector
|
#define SECTORSIZE 4096 /* size of one flash sector */
|
||||||
|
|
||||||
#define ROCKBOX_DEST 0x09000000
|
#define ROCKBOX_DEST 0x09000000
|
||||||
#define ROCKBOX_EXEC 0x09000200
|
#define ROCKBOX_EXEC 0x09000200
|
||||||
#define FILENAME "/rockbox.ucl"
|
#define FILENAME "/rockbox.ucl"
|
||||||
#define VERS_ADR 0xFE // position of firmware version value in Flash
|
#define VERS_ADR 0xFE /* position of firmware version value in Flash */
|
||||||
#define UCL_HEADER 26 // size of the header generated by uclpack
|
#define UCL_HEADER 26 /* size of the header generated by uclpack */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT32 destination; // address to copy it to
|
UINT32 destination; /* address to copy it to */
|
||||||
UINT32 size; // how many bytes of payload (to the next header)
|
UINT32 size; /* how many bytes of payload (to the next header) */
|
||||||
UINT32 execute; // entry point
|
UINT32 execute; /* entry point */
|
||||||
UINT32 flags; // uncompressed or compressed
|
UINT32 flags; /* uncompressed or compressed */
|
||||||
// end of header, now comes the payload
|
/* end of header, now comes the payload */
|
||||||
} tImageHeader;
|
} tImageHeader;
|
||||||
|
|
||||||
|
/* result of the CheckFirmwareFile() function */
|
||||||
// result of the CheckFirmwareFile() function
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
eOK = 0,
|
eOK = 0,
|
||||||
eFileNotFound, // errors from here on
|
eFileNotFound, /* errors from here on */
|
||||||
eTooBig,
|
eTooBig,
|
||||||
eTooSmall,
|
eTooSmall,
|
||||||
eReadErr,
|
eReadErr,
|
||||||
|
@ -76,92 +75,94 @@ typedef struct
|
||||||
char name[32];
|
char name[32];
|
||||||
} tFlashInfo;
|
} tFlashInfo;
|
||||||
|
|
||||||
static struct plugin_api* rb; // here is a global api struct pointer
|
static struct plugin_api* rb; /* here is a global api struct pointer */
|
||||||
|
|
||||||
#define SEC_SIZE 4096 // size of one flash sector
|
|
||||||
static UINT8 sector[SEC_SIZE]; // better not place this on the stack...
|
|
||||||
|
|
||||||
|
#define SEC_SIZE 4096 /* size of one flash sector */
|
||||||
|
static UINT8 sector[SEC_SIZE]; /* better not place this on the stack... */
|
||||||
|
|
||||||
/***************** Flash Functions *****************/
|
/***************** Flash Functions *****************/
|
||||||
|
|
||||||
|
|
||||||
// read the manufacturer and device ID
|
/* read the manufacturer and device ID */
|
||||||
bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID)
|
bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID)
|
||||||
{
|
{
|
||||||
UINT8 not_manu, not_id; // read values before switching to ID mode
|
UINT8 not_manu, not_id; /* read values before switching to ID mode */
|
||||||
UINT8 manu, id; // read values when in ID mode
|
UINT8 manu, id; /* read values when in ID mode */
|
||||||
|
|
||||||
pBase = (UINT8*)((UINT32)pBase & 0xFFF80000); // round down to 512k align, to make shure
|
pBase = (UINT8*)((UINT32)pBase & 0xFFF80000); /* round down to 512k align,
|
||||||
|
to make sure */
|
||||||
|
|
||||||
not_manu = pBase[0]; // read the normal content
|
not_manu = pBase[0]; /* read the normal content */
|
||||||
not_id = pBase[1]; // should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker
|
not_id = pBase[1]; /* should be 'A' (0x41) and 'R' (0x52) from the
|
||||||
|
"ARCH" marker */
|
||||||
|
|
||||||
pBase[0x5555] = 0xAA; // enter command mode
|
pBase[0x5555] = 0xAA; /* enter command mode */
|
||||||
pBase[0x2AAA] = 0x55;
|
pBase[0x2AAA] = 0x55;
|
||||||
pBase[0x5555] = 0x90; // ID command
|
pBase[0x5555] = 0x90; /* ID command */
|
||||||
rb->sleep(HZ/50); // Atmel wants 20ms pause here
|
rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
|
||||||
|
|
||||||
manu = pBase[0];
|
manu = pBase[0];
|
||||||
id = pBase[1];
|
id = pBase[1];
|
||||||
|
|
||||||
pBase[0] = 0xF0; // reset flash (back to normal read mode)
|
pBase[0] = 0xF0; /* reset flash (back to normal read mode) */
|
||||||
rb->sleep(HZ/50); // Atmel wants 20ms pause here
|
rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
|
||||||
|
|
||||||
/* I assume success if the obtained values are different from
|
/* I assume success if the obtained values are different from
|
||||||
the normal flash content. This is not perfectly bulletproof, they
|
the normal flash content. This is not perfectly bulletproof, they
|
||||||
could theoretically be the same by chance, causing us to fail. */
|
could theoretically be the same by chance, causing us to fail. */
|
||||||
if (not_manu != manu || not_id != id) // a value has changed
|
if (not_manu != manu || not_id != id) /* a value has changed */
|
||||||
{
|
{
|
||||||
*pManufacturerID = manu; // return the results
|
*pManufacturerID = manu; /* return the results */
|
||||||
*pDeviceID = id;
|
*pDeviceID = id;
|
||||||
return true; // success
|
return true; /* success */
|
||||||
}
|
}
|
||||||
return false; // fail
|
return false; /* fail */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eraze the sector which contains the given address */
|
||||||
// eraze the sector which contains the given address
|
|
||||||
bool ErazeSector(volatile UINT8* pAddr)
|
bool ErazeSector(volatile UINT8* pAddr)
|
||||||
{
|
{
|
||||||
volatile UINT8* pBase = (UINT8*)((UINT32)pAddr & 0xFFF80000); // round down to 512k align
|
volatile UINT8* pBase =
|
||||||
unsigned timeout = 43000; // the timeout loop should be no less than 25ms
|
(UINT8*)((UINT32)pAddr & 0xFFF80000); /* round down to 512k align */
|
||||||
|
unsigned timeout = 43000; /* the timeout loop should be no less than
|
||||||
|
25ms */
|
||||||
|
|
||||||
pBase[0x5555] = 0xAA; // enter command mode
|
pBase[0x5555] = 0xAA; /* enter command mode */
|
||||||
pBase[0x2AAA] = 0x55;
|
pBase[0x2AAA] = 0x55;
|
||||||
pBase[0x5555] = 0x80; // eraze command
|
pBase[0x5555] = 0x80; /* eraze command */
|
||||||
pBase[0x5555] = 0xAA; // enter command mode
|
pBase[0x5555] = 0xAA; /* enter command mode */
|
||||||
pBase[0x2AAA] = 0x55;
|
pBase[0x2AAA] = 0x55;
|
||||||
*pAddr = 0x30; // eraze the sector
|
*pAddr = 0x30; /* eraze the sector */
|
||||||
|
|
||||||
// I counted 7 instructions for this loop -> min. 0.58 us per round
|
/* I counted 7 instructions for this loop -> min. 0.58 us per round
|
||||||
// Plus memory waitstates it will be much more, gives margin
|
Plus memory waitstates it will be much more, gives margin */
|
||||||
while (*pAddr != 0xFF && --timeout); // poll for erazed
|
while (*pAddr != 0xFF && --timeout); /* poll for erazed */
|
||||||
|
|
||||||
return (timeout != 0);
|
return (timeout != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// address must be in an erazed location
|
/* address must be in an erazed location */
|
||||||
inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data)
|
inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data)
|
||||||
{
|
{
|
||||||
unsigned timeout = 35; // the timeout loop should be no less than 20us
|
unsigned timeout = 35; /* the timeout loop should be no less than 20us */
|
||||||
|
|
||||||
if (~*pAddr & data) // just a safety feature, not really necessary
|
if (~*pAddr & data) /* just a safety feature, not really necessary */
|
||||||
return false; // can't set any bit from 0 to 1
|
return false; /* can't set any bit from 0 to 1 */
|
||||||
|
|
||||||
FB[0x5555] = 0xAA; // enter command mode
|
FB[0x5555] = 0xAA; /* enter command mode */
|
||||||
FB[0x2AAA] = 0x55;
|
FB[0x2AAA] = 0x55;
|
||||||
FB[0x5555] = 0xA0; // byte program command
|
FB[0x5555] = 0xA0; /* byte program command */
|
||||||
|
|
||||||
*pAddr = data;
|
*pAddr = data;
|
||||||
|
|
||||||
// I counted 7 instructions for this loop -> min. 0.58 us per round
|
/* I counted 7 instructions for this loop -> min. 0.58 us per round
|
||||||
// Plus memory waitstates it will be much more, gives margin
|
Plus memory waitstates it will be much more, gives margin */
|
||||||
while (*pAddr != data && --timeout); // poll for programmed
|
while (*pAddr != data && --timeout); /* poll for programmed */
|
||||||
|
|
||||||
return (timeout != 0);
|
return (timeout != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this returns true if supported and fills the info struct
|
/* this returns true if supported and fills the info struct */
|
||||||
bool GetFlashInfo(tFlashInfo* pInfo)
|
bool GetFlashInfo(tFlashInfo* pInfo)
|
||||||
{
|
{
|
||||||
rb->memset(pInfo, 0, sizeof(tFlashInfo));
|
rb->memset(pInfo, 0, sizeof(tFlashInfo));
|
||||||
|
@ -169,17 +170,17 @@ bool GetFlashInfo(tFlashInfo* pInfo)
|
||||||
if (!ReadID(FB, &pInfo->manufacturer, &pInfo->id))
|
if (!ReadID(FB, &pInfo->manufacturer, &pInfo->id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pInfo->manufacturer == 0xBF) // SST
|
if (pInfo->manufacturer == 0xBF) /* SST */
|
||||||
{
|
{
|
||||||
if (pInfo->id == 0xD6)
|
if (pInfo->id == 0xD6)
|
||||||
{
|
{
|
||||||
pInfo->size = 256* 1024; // 256k
|
pInfo->size = 256* 1024; /* 256k */
|
||||||
rb->strcpy(pInfo->name, "SST39VF020");
|
rb->strcpy(pInfo->name, "SST39VF020");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (pInfo->id == 0xD7)
|
else if (pInfo->id == 0xD7)
|
||||||
{
|
{
|
||||||
pInfo->size = 512* 1024; // 512k
|
pInfo->size = 512* 1024; /* 512k */
|
||||||
rb->strcpy(pInfo->name, "SST39VF040");
|
rb->strcpy(pInfo->name, "SST39VF040");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +193,7 @@ bool GetFlashInfo(tFlashInfo* pInfo)
|
||||||
|
|
||||||
/*********** Tool Functions ************/
|
/*********** Tool Functions ************/
|
||||||
|
|
||||||
// place a 32 bit value into memory, big endian
|
/* place a 32 bit value into memory, big endian */
|
||||||
void Write32(UINT8* pByte, UINT32 value)
|
void Write32(UINT8* pByte, UINT32 value)
|
||||||
{
|
{
|
||||||
pByte[0] = (UINT8)(value >> 24);
|
pByte[0] = (UINT8)(value >> 24);
|
||||||
|
@ -201,12 +202,12 @@ void Write32(UINT8* pByte, UINT32 value)
|
||||||
pByte[3] = (UINT8)(value);
|
pByte[3] = (UINT8)(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read a 32 bit value from memory, big endian
|
/* read a 32 bit value from memory, big endian */
|
||||||
UINT32 Read32(UINT8* pByte)
|
UINT32 Read32(UINT8* pByte)
|
||||||
{
|
{
|
||||||
UINT32 value = 0;
|
UINT32 value;
|
||||||
|
|
||||||
value |= (UINT32)pByte[0] << 24;
|
value = (UINT32)pByte[0] << 24;
|
||||||
value |= (UINT32)pByte[1] << 16;
|
value |= (UINT32)pByte[1] << 16;
|
||||||
value |= (UINT32)pByte[2] << 8;
|
value |= (UINT32)pByte[2] << 8;
|
||||||
value |= (UINT32)pByte[3];
|
value |= (UINT32)pByte[3];
|
||||||
|
@ -214,33 +215,35 @@ UINT32 Read32(UINT8* pByte)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the start address of the second image */
|
||||||
// get the start address of the second image
|
|
||||||
tImageHeader* GetSecondImage(void)
|
tImageHeader* GetSecondImage(void)
|
||||||
{
|
{
|
||||||
tImageHeader* pImage1;
|
tImageHeader* pImage1;
|
||||||
UINT32 pos = 0; // dafault: not found
|
UINT32 pos = 0; /* default: not found */
|
||||||
UINT32* pFlash = (UINT32*)FB;
|
UINT32* pFlash = (UINT32*)FB;
|
||||||
|
|
||||||
UINT16 version = *(UINT16*)(FB + VERS_ADR);
|
UINT16 version = *(UINT16*)(FB + VERS_ADR);
|
||||||
if (version < 200) // at least 2.00
|
if (version < 200) /* at least 2.00 */
|
||||||
{
|
{
|
||||||
return 0; // not our flash layout
|
return 0; /* not our flash layout */
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine the first image position
|
/* determine the first image position */
|
||||||
pos = pFlash[2] + pFlash[3]; // position + size of the bootloader = after it
|
pos = pFlash[2] + pFlash[3]; /* position + size of the bootloader = after
|
||||||
pos = (pos + 3) & ~3; // be shure it's 32 bit aligned
|
it */
|
||||||
|
pos = (pos + 3) & ~3; /* be sure it's 32 bit aligned */
|
||||||
pImage1 = (tImageHeader*)pos;
|
pImage1 = (tImageHeader*)pos;
|
||||||
|
|
||||||
if (pImage1->destination != ROCKBOX_DEST || pImage1->execute != ROCKBOX_EXEC)
|
if (pImage1->destination != ROCKBOX_DEST ||
|
||||||
return 0; // seems to be no Rockbox stuff in here
|
pImage1->execute != ROCKBOX_EXEC)
|
||||||
|
return 0; /* seems to be no Rockbox stuff in here */
|
||||||
|
|
||||||
if (pImage1->size != 0)
|
if (pImage1->size != 0)
|
||||||
{ // success, we have a second image
|
{
|
||||||
|
/* success, we have a second image */
|
||||||
pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size;
|
pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size;
|
||||||
if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos)
|
if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos)
|
||||||
{ // not sector-aligned
|
{ /* not sector-aligned */
|
||||||
pos = 0; // sanity check failed
|
pos = 0; // sanity check failed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,17 +254,17 @@ tImageHeader* GetSecondImage(void)
|
||||||
|
|
||||||
/*********** Image File Functions ************/
|
/*********** Image File Functions ************/
|
||||||
|
|
||||||
// so far, only compressed images in UCL NRV algorithm 2e supported
|
/* so far, only compressed images in UCL NRV algorithm 2e supported */
|
||||||
tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fd;
|
int fd;
|
||||||
int filesize; // size info
|
int filesize; /* size info */
|
||||||
|
|
||||||
int fileread = 0; // total size as read from the file
|
int fileread = 0; /* total size as read from the file */
|
||||||
int read; // how many for this sector
|
int read; /* how many for this sector */
|
||||||
|
|
||||||
// magic file header for compressed files
|
/* magic file header for compressed files */
|
||||||
static const UINT8 magic[8] = { 0x00,0xe9,0x55,0x43,0x4c,0xff,0x01,0x1a };
|
static const UINT8 magic[8] = { 0x00,0xe9,0x55,0x43,0x4c,0xff,0x01,0x1a };
|
||||||
UINT8 ucl_header[UCL_HEADER];
|
UINT8 ucl_header[UCL_HEADER];
|
||||||
|
|
||||||
|
@ -275,13 +278,13 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
rb->close(fd);
|
rb->close(fd);
|
||||||
return eTooBig;
|
return eTooBig;
|
||||||
}
|
}
|
||||||
else if (filesize < 50000) // give it some reasonable lower limit
|
else if (filesize < 50000) /* give it some reasonable lower limit */
|
||||||
{
|
{
|
||||||
rb->close(fd);
|
rb->close(fd);
|
||||||
return eTooSmall;
|
return eTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do some sanity checks
|
/* do some sanity checks */
|
||||||
|
|
||||||
read = rb->read(fd, ucl_header, sizeof(ucl_header));
|
read = rb->read(fd, ucl_header, sizeof(ucl_header));
|
||||||
fileread += read;
|
fileread += read;
|
||||||
|
@ -291,7 +294,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
return eReadErr;
|
return eReadErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compare the magic header
|
/* compare the magic header */
|
||||||
for (i=0; i<8; i++)
|
for (i=0; i<8; i++)
|
||||||
{
|
{
|
||||||
if (ucl_header[i] != magic[i])
|
if (ucl_header[i] != magic[i])
|
||||||
|
@ -301,30 +304,32 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for supported algorithm
|
/* check for supported algorithm */
|
||||||
if (ucl_header[12] != 0x2E)
|
if (ucl_header[12] != 0x2E)
|
||||||
{
|
{
|
||||||
rb->close(fd);
|
rb->close(fd);
|
||||||
return eWrongAlgorithm;
|
return eWrongAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
pHeader->size = Read32(ucl_header + 22); // compressed size
|
pHeader->size = Read32(ucl_header + 22); /* compressed size */
|
||||||
if (pHeader->size != filesize - sizeof(ucl_header) - 8)
|
if (pHeader->size != filesize - sizeof(ucl_header) - 8)
|
||||||
{
|
{
|
||||||
rb->close(fd);
|
rb->close(fd);
|
||||||
return eMultiBlocks;
|
return eMultiBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Read32(ucl_header + 18) > pHeader->size) // compare with uncompressed size
|
if (Read32(ucl_header + 18) > pHeader->size) /* compare with uncompressed
|
||||||
{ // normal case
|
size */
|
||||||
pHeader->flags = 0x00000001; // flags for UCL compressed
|
{ /* normal case */
|
||||||
|
pHeader->flags = 0x00000001; /* flags for UCL compressed */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pHeader->flags = 0x00000000; // very unlikely, content was not compressible
|
pHeader->flags = 0x00000000; /* very unlikely, content was not
|
||||||
|
compressible */
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we can read the whole file
|
/* check if we can read the whole file */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
read = rb->read(fd, sector, SEC_SIZE);
|
read = rb->read(fd, sector, SEC_SIZE);
|
||||||
|
@ -336,7 +341,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
if (fileread != filesize)
|
if (fileread != filesize)
|
||||||
return eReadErr;
|
return eReadErr;
|
||||||
|
|
||||||
// fill in the hardcoded rest of the header
|
/* fill in the hardcoded rest of the header */
|
||||||
pHeader->destination = ROCKBOX_DEST;
|
pHeader->destination = ROCKBOX_DEST;
|
||||||
pHeader->execute = ROCKBOX_EXEC;
|
pHeader->execute = ROCKBOX_EXEC;
|
||||||
|
|
||||||
|
@ -344,31 +349,35 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns the # of failures, 0 on success
|
/* returns the # of failures, 0 on success */
|
||||||
unsigned ProgramImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader, int start, int size)
|
unsigned ProgramImageFile(char* filename, UINT8* pos,
|
||||||
|
tImageHeader* pImageHeader, int start, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fd;
|
int fd;
|
||||||
int read; // how many for this sector
|
int read; /* how many for this sector */
|
||||||
unsigned failures = 0;
|
unsigned failures = 0;
|
||||||
|
|
||||||
fd = rb->open(filename, O_RDONLY);
|
fd = rb->open(filename, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// no error checking necessary here, we checked for minimum size already
|
/* no error checking necessary here, we checked for minimum size
|
||||||
rb->lseek(fd, start, SEEK_SET); // go to start position
|
already */
|
||||||
|
rb->lseek(fd, start, SEEK_SET); /* go to start position */
|
||||||
|
|
||||||
*(tImageHeader*)sector = *pImageHeader; // copy header into sector buffer
|
*(tImageHeader*)sector = *pImageHeader; /* copy header into sector
|
||||||
read = rb->read(fd, sector + sizeof(tImageHeader), SEC_SIZE - sizeof(tImageHeader)); // payload behind
|
buffer */
|
||||||
|
read = rb->read(fd, sector + sizeof(tImageHeader),
|
||||||
|
SEC_SIZE - sizeof(tImageHeader)); /* payload behind */
|
||||||
size -= read;
|
size -= read;
|
||||||
read += sizeof(tImageHeader); // to be programmed, but not part of the file
|
read += sizeof(tImageHeader); /* to be programmed, but not part of the
|
||||||
|
file */
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
if (!ErazeSector(pos))
|
if (!ErazeSector(pos))
|
||||||
{
|
{
|
||||||
// nothing we can do, let the programming count the errors
|
/* nothing we can do, let the programming count the errors */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<read; i++)
|
for (i=0; i<read; i++)
|
||||||
|
@ -380,7 +389,8 @@ unsigned ProgramImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += SEC_SIZE;
|
pos += SEC_SIZE;
|
||||||
read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size); // payload for next sector
|
read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size);
|
||||||
|
/* payload for next sector */
|
||||||
size -= read;
|
size -= read;
|
||||||
} while (read > 0);
|
} while (read > 0);
|
||||||
|
|
||||||
|
@ -389,25 +399,31 @@ unsigned ProgramImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader
|
||||||
return failures;
|
return failures;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the # of failures, 0 on success
|
/* returns the # of failures, 0 on success */
|
||||||
unsigned VerifyImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader, int start, int size)
|
unsigned VerifyImageFile(char* filename, UINT8* pos,
|
||||||
|
tImageHeader* pImageHeader, int start, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fd;
|
int fd;
|
||||||
int read; // how many for this sector
|
int read; /* how many for this sector */
|
||||||
unsigned failures = 0;
|
unsigned failures = 0;
|
||||||
|
|
||||||
fd = rb->open(filename, O_RDONLY);
|
fd = rb->open(filename, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// no error checking necessary here, we checked for minimum size already
|
/* no error checking necessary here, we checked for minimum size
|
||||||
rb->lseek(fd, start, SEEK_SET); // go to start position
|
already */
|
||||||
|
rb->lseek(fd, start, SEEK_SET); /* go to start position */
|
||||||
|
|
||||||
|
*(tImageHeader*)sector = *pImageHeader; /* copy header into sector
|
||||||
|
buffer */
|
||||||
|
read = rb->read(fd, sector + sizeof(tImageHeader),
|
||||||
|
SEC_SIZE - sizeof(tImageHeader)); /* payload behind */
|
||||||
|
|
||||||
*(tImageHeader*)sector = *pImageHeader; // copy header into sector buffer
|
|
||||||
read = rb->read(fd, sector + sizeof(tImageHeader), SEC_SIZE - sizeof(tImageHeader)); // payload behind
|
|
||||||
size -= read;
|
size -= read;
|
||||||
read += sizeof(tImageHeader); // to be programmed, but not part of the file
|
read += sizeof(tImageHeader); /* to be programmed, but not part of the
|
||||||
|
file */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -420,7 +436,8 @@ unsigned VerifyImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader,
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += SEC_SIZE;
|
pos += SEC_SIZE;
|
||||||
read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size); // payload for next sector
|
read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size);
|
||||||
|
/* payload for next sector */
|
||||||
size -= read;
|
size -= read;
|
||||||
} while (read);
|
} while (read);
|
||||||
|
|
||||||
|
@ -435,7 +452,7 @@ unsigned VerifyImageFile(char* filename, UINT8* pos, tImageHeader* pImageHeader,
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
||||||
// helper for DoUserDialog()
|
/* helper for DoUserDialog() */
|
||||||
void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
|
void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
@ -448,7 +465,8 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
|
||||||
{
|
{
|
||||||
if (pInfo->size)
|
if (pInfo->size)
|
||||||
{
|
{
|
||||||
rb->snprintf(buf, sizeof(buf), "Flash size: %d KB", pInfo->size / 1024);
|
rb->snprintf(buf, sizeof(buf), "Flash size: %d KB",
|
||||||
|
pInfo->size / 1024);
|
||||||
rb->lcd_puts(0, 0, buf);
|
rb->lcd_puts(0, 0, buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -460,7 +478,8 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
|
||||||
|
|
||||||
if (pImageHeader)
|
if (pImageHeader)
|
||||||
{
|
{
|
||||||
rb->snprintf(buf, sizeof(buf), "Image at %d KB", ((UINT8*)pImageHeader - FB) / 1024);
|
rb->snprintf(buf, sizeof(buf), "Image at %d KB",
|
||||||
|
((UINT8*)pImageHeader - FB) / 1024);
|
||||||
rb->lcd_puts(0, 1, buf);
|
rb->lcd_puts(0, 1, buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -472,14 +491,14 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Kind of our main function, defines the application flow.
|
/* Kind of our main function, defines the application flow. */
|
||||||
void DoUserDialog(void)
|
void DoUserDialog(void)
|
||||||
{
|
{
|
||||||
tImageHeader ImageHeader;
|
tImageHeader ImageHeader;
|
||||||
tFlashInfo FlashInfo;
|
tFlashInfo FlashInfo;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int button;
|
int button;
|
||||||
int rc; // generic return code
|
int rc; /* generic return code */
|
||||||
UINT32 space, aligned_size, true_size;
|
UINT32 space, aligned_size, true_size;
|
||||||
UINT8* pos;
|
UINT8* pos;
|
||||||
|
|
||||||
|
@ -489,15 +508,15 @@ void DoUserDialog(void)
|
||||||
rc = GetFlashInfo(&FlashInfo);
|
rc = GetFlashInfo(&FlashInfo);
|
||||||
|
|
||||||
ShowFlashInfo(&FlashInfo, (void*)pos);
|
ShowFlashInfo(&FlashInfo, (void*)pos);
|
||||||
if (FlashInfo.size == 0) // no valid chip
|
if (FlashInfo.size == 0) /* no valid chip */
|
||||||
{
|
{
|
||||||
rb->splash(HZ*3, 0, true, "Not flashable");
|
rb->splash(HZ*3, 0, true, "Not flashable");
|
||||||
return; // exit
|
return; /* exit */
|
||||||
}
|
}
|
||||||
else if (pos == 0)
|
else if (pos == 0)
|
||||||
{
|
{
|
||||||
rb->splash(HZ*3, 0, true, "No Image");
|
rb->splash(HZ*3, 0, true, "No Image");
|
||||||
return; // exit
|
return; /* exit */
|
||||||
}
|
}
|
||||||
|
|
||||||
rb->lcd_puts(0, 3, "using file:");
|
rb->lcd_puts(0, 3, "using file:");
|
||||||
|
@ -518,11 +537,12 @@ void DoUserDialog(void)
|
||||||
rb->lcd_puts(0, 0, "checking...");
|
rb->lcd_puts(0, 0, "checking...");
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
|
|
||||||
space = FlashInfo.size - (pos-FB + sizeof(ImageHeader)); // size minus start
|
space = FlashInfo.size - (pos-FB + sizeof(ImageHeader));
|
||||||
|
/* size minus start */
|
||||||
|
|
||||||
rc = CheckImageFile(FILENAME, space, &ImageHeader);
|
rc = CheckImageFile(FILENAME, space, &ImageHeader);
|
||||||
rb->lcd_puts(0, 0, "checked:");
|
rb->lcd_puts(0, 0, "checked:");
|
||||||
switch (rc)
|
switch (rc) {
|
||||||
{
|
|
||||||
case eOK:
|
case eOK:
|
||||||
rb->lcd_puts(0, 1, "File OK.");
|
rb->lcd_puts(0, 1, "File OK.");
|
||||||
break;
|
break;
|
||||||
|
@ -565,12 +585,12 @@ void DoUserDialog(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == eOK)
|
if (rc == eOK)
|
||||||
{ // was OK
|
{ /* was OK */
|
||||||
rb->lcd_puts(0, 6, "[F2] to program");
|
rb->lcd_puts(0, 6, "[F2] to program");
|
||||||
rb->lcd_puts(0, 7, "other key to exit");
|
rb->lcd_puts(0, 7, "other key to exit");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // error occured
|
{ /* error occured */
|
||||||
rb->lcd_puts(0, 6, "Any key to exit");
|
rb->lcd_puts(0, 6, "Any key to exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,8 +605,12 @@ void DoUserDialog(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
true_size = ImageHeader.size;
|
true_size = ImageHeader.size;
|
||||||
aligned_size = ((sizeof(tImageHeader) + true_size + SECTORSIZE-1) & ~(SECTORSIZE-1)) - sizeof(tImageHeader); // round up to next flash sector
|
aligned_size = ((sizeof(tImageHeader) + true_size + SECTORSIZE-1) &
|
||||||
ImageHeader.size = aligned_size; // increase image size such that we reach the next sector
|
~(SECTORSIZE-1)) - sizeof(tImageHeader); /* round up to
|
||||||
|
next flash
|
||||||
|
sector */
|
||||||
|
ImageHeader.size = aligned_size; /* increase image size such that we reach
|
||||||
|
the next sector */
|
||||||
|
|
||||||
rb->lcd_clear_display();
|
rb->lcd_clear_display();
|
||||||
rb->lcd_puts(0, 0, "Programming...");
|
rb->lcd_puts(0, 0, "Programming...");
|
||||||
|
@ -594,7 +618,7 @@ void DoUserDialog(void)
|
||||||
|
|
||||||
rc = ProgramImageFile(FILENAME, pos, &ImageHeader, UCL_HEADER, true_size);
|
rc = ProgramImageFile(FILENAME, pos, &ImageHeader, UCL_HEADER, true_size);
|
||||||
if (rc)
|
if (rc)
|
||||||
{ // errors
|
{ /* errors */
|
||||||
rb->lcd_clear_display();
|
rb->lcd_clear_display();
|
||||||
rb->lcd_puts(0, 0, "Error:");
|
rb->lcd_puts(0, 0, "Error:");
|
||||||
rb->lcd_puts(0, 1, "Programming fail!");
|
rb->lcd_puts(0, 1, "Programming fail!");
|
||||||
|
@ -633,22 +657,20 @@ void DoUserDialog(void)
|
||||||
button = rb->button_get(true);
|
button = rb->button_get(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // HAVE_LCD_BITMAP
|
#else /* HAVE_LCD_BITMAP */
|
||||||
|
|
||||||
// Player implementation has to go here
|
/* Player implementation has to go here */
|
||||||
void DoUserDialog(void)
|
void DoUserDialog(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAVE_LCD_BITMAP
|
#endif /* HAVE_LCD_BITMAP */
|
||||||
|
|
||||||
|
|
||||||
/***************** Plugin Entry Point *****************/
|
/***************** Plugin Entry Point *****************/
|
||||||
|
|
||||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/* this macro should be called as the first thing you do in the plugin.
|
/* this macro should be called as the first thing you do in the plugin.
|
||||||
it test that the api version and model the plugin was compiled for
|
it test that the api version and model the plugin was compiled for
|
||||||
matches the machine it is running on */
|
matches the machine it is running on */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue