1
0
Fork 0
forked from len0rd/rockbox

Code policed (removed tab chars, no C++ comments, line length); all register manipulation hex values match register width. No code change.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5478 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2004-12-03 21:43:21 +00:00
parent 059ada52d0
commit 4b3501f2f6

View file

@ -7,8 +7,8 @@
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$ * $Id$
* *
* Copyright (C) 2003 by Jörg Hohensohn * Copyright (C) 2003 by Jörg Hohensohn
* *
* Second-level bootloader, with dual-boot feature by holding F1/Menu * Second-level bootloader, with dual-boot feature by holding F1/Menu
* This is the image being descrambled and executed by the boot ROM. * This is the image being descrambled and executed by the boot ROM.
* It's task is to copy Rockbox from Flash to DRAM. * It's task is to copy Rockbox from Flash to DRAM.
@ -27,266 +27,268 @@
#ifdef NO_ROM #ifdef NO_ROM
// start with the vector table /* start with the vector table */
UINT32 vectors[] __attribute__ ((section (".vectors"))) = UINT32 vectors[] __attribute__ ((section (".vectors"))) =
{ {
(UINT32)_main, // entry point, the copy routine (UINT32)_main, /* entry point, the copy routine */
(UINT32)(end_stack - 1), // initial stack pointer (UINT32)(end_stack - 1), /* initial stack pointer */
FLASH_BASE + 0x200, // source of image in flash FLASH_BASE + 0x200, /* source of image in flash */
(UINT32)total_size, // size of image (UINT32)total_size, /* size of image */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0x03020080 // mask and version (just as a suggestion) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0x03020080 /* mask and version (just as a suggestion) */
}; };
#else #else
// our binary has to start with a vector to the entry point /* our binary has to start with a vector to the entry point */
tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main}; tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
#endif #endif
#ifdef NO_ROM // some code which is only needed for the romless variant #ifdef NO_ROM /* some code which is only needed for the romless variant */
void _main(void) void _main(void)
{ {
UINT32* pSrc; UINT32* pSrc;
UINT32* pDest; UINT32* pDest;
UINT32* pEnd; UINT32* pEnd;
/* /*
asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts
asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack
asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base
*/ */
// copy everything to IRAM and continue there /* copy everything to IRAM and continue there */
pSrc = begin_iramcopy; pSrc = begin_iramcopy;
pDest = begin_text; pDest = begin_text;
pEnd = pDest + (begin_stack - begin_text); pEnd = pDest + (begin_stack - begin_text);
do do
{ {
*pDest++ = *pSrc++; *pDest++ = *pSrc++;
} }
while (pDest < pEnd); while (pDest < pEnd);
main(); // jump to the real main() main(); /* jump to the real main() */
} }
void BootInit(void) void BootInit(void)
{ {
// inits from the boot ROM, whether they make sense or not /* inits from the boot ROM, whether they make sense or not */
PBDR &= 0xFFBF; // LED off (0x131E) PBDR &= 0xFFBF; /* LED off (0x131E) */
PBCR2 = 0; // all GPIO PBCR2 = 0; /* all GPIO */
PBIOR |= 0x40; // LED output PBIOR |= 0x0040; /* LED output */
PBIOR &= 0xFFF1; // LCD lines input PBIOR &= 0xFFF1; /* LCD lines input */
// init DRAM like the boot ROM does /* init DRAM like the boot ROM does */
PACR2 &= 0xFFFB; PACR2 &= 0xFFFB;
PACR2 |= 0x0008; PACR2 |= 0x0008;
CASCR = 0xAF; CASCR = 0xAF;
BCR |= 0x8000; BCR |= 0x8000;
WCR1 &= 0xFDFD; WCR1 &= 0xFDFD;
DCR = 0x0E00; DCR = 0x0E00;
RCR = 0x5AB0; RCR = 0x5AB0;
RTCOR = 0x9605; RTCOR = 0x9605;
RTCSR = 0xA518; RTCSR = 0xA518;
} }
#endif // #ifdef NO_ROM #endif /* #ifdef NO_ROM */
int main(void) int main(void)
{ {
int nButton; int nButton;
PlatformInit(); // model-specific inits PlatformInit(); /* model-specific inits */
nButton = ButtonPressed(); nButton = ButtonPressed();
if (nButton == 3) if (nButton == 3)
{ // F3 means start monitor { /* F3 means start monitor */
MiniMon(); MiniMon();
} }
else else
{ {
tImage* pImage; tImage* pImage;
pImage = GetStartImage(nButton); // which image pImage = GetStartImage(nButton); /* which image */
DecompressStart(pImage); // move into place and start it DecompressStart(pImage); /* move into place and start it */
} }
return 0; // I guess we won't return ;-) return 0; /* I guess we won't return ;-) */
} }
// init code that is specific to certain platform /* init code that is specific to certain platform */
void PlatformInit(void) void PlatformInit(void)
{ {
#ifdef NO_ROM #ifdef NO_ROM
BootInit(); // if not started by boot ROM, we need to init what it did BootInit(); /* if not started by boot ROM, we need to init what it did */
#endif #endif
#if defined PLATFORM_PLAYER #if defined PLATFORM_PLAYER
BRR1 = 0x0019; // 14400 Baud for monitor BRR1 = 0x19; /* 14400 Baud for monitor */
PACR2 &= 0xFFFC; // GPIO for PA0 (charger detection, input by default) PACR2 &= 0xFFFC; /* GPIO for PA0 (charger detection, input by default) */
if (FW_VERSION > 451 && (PADRL & 0x01)) if (FW_VERSION > 451 && (PADRL & 0x01))
{ // "new" Player and charger not plugged? { /* "new" Player and charger not plugged? */
PBDR |= 0x10; // set PB4 to 1 to power-up the harddisk early PBDR |= 0x0010; /* set PB4 to 1 to power-up the harddisk early */
PBIOR |= 0x10; // make PB4 an output PBIOR |= 0x0010; /* make PB4 an output */
} }
#elif defined PLATFORM_RECORDER #elif defined PLATFORM_RECORDER
BRR1 = 0x0002; // 115200 Baud for monitor BRR1 = 0x02; /* 115200 Baud for monitor */
if (ReadADC(7) > 0x100) // charger plugged? if (ReadADC(7) > 0x100) /* charger plugged? */
{ // switch off the HD, else a flat battery may not start { /* switch off the HD, else a flat battery may not start */
PACR2 &= 0xFBFF; // GPIO for PA5 PACR2 &= 0xFBFF; /* GPIO for PA5 */
PAIOR |= 0x20; // make PA5 an output (low by default) PAIOR |= 0x0020; /* make PA5 an output (low by default) */
} }
#elif defined PLATFORM_FM #elif defined PLATFORM_FM
BRR1 = 0x0002; // 115200 Baud for monitor BRR1 = 0x02; /* 115200 Baud for monitor */
PBDR |= 0x20; // set PB5 to keep power (fixes the ON-holding problem) PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
PBIOR |= 0x20; // make PB5 an output PBIOR |= 0x0020; /* make PB5 an output */
if (ReadADC(0) < 0x1FF) // charger plugged? if (ReadADC(0) < 0x1FF) /* charger plugged? */
{ // switch off the HD, else a flat battery may not start { /* switch off the HD, else a flat battery may not start */
PACR2 &= 0xFBFF; // GPIO for PA5 PACR2 &= 0xFBFF; /* GPIO for PA5 */
PAIOR |= 0x20; // make PA5 an output (low by default) PAIOR |= 0x0020; /* make PA5 an output (low by default) */
} }
#elif defined PLATFORM_ONDIO #elif defined PLATFORM_ONDIO
BRR1 = 0x0019; // 14400 Baud for monitor BRR1 = 0x19; /* 14400 Baud for monitor */
PBDR |= 0x20; // set PB5 to keep power (fixes the ON-holding problem) PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
PBIOR |= 0x20; // make PB5 an output PBIOR |= 0x0020; /* make PB5 an output */
#endif #endif
// platform-independent inits /* platform-independent inits */
DCR |= 0x1000; // enable burst mode on DRAM DCR |= 0x1000; /* enable burst mode on DRAM */
BCR |= 0x2000; // activate Warp mode (simultaneous internal and external mem access) BCR |= 0x2000; /* activate Warp mode (simultaneous internal and external
* mem access) */
} }
// Thinned out version of the UCL 2e decompression sourcecode /* Thinned out version of the UCL 2e decompression sourcecode
// Original (C) Markus F.X.J Oberhumer under GNU GPL license * Original (C) Markus F.X.J Oberhumer under GNU GPL license */
#define GETBIT(bb, src, ilen) \ #define GETBIT(bb, src, ilen) \
(((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1) (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
int ucl_nrv2e_decompress_8( int ucl_nrv2e_decompress_8(
const UINT8 *src, UINT8 *dst, UINT32* dst_len) const UINT8 *src, UINT8 *dst, UINT32* dst_len)
{ {
UINT32 bb = 0; UINT32 bb = 0;
unsigned ilen = 0, olen = 0, last_m_off = 1; unsigned ilen = 0, olen = 0, last_m_off = 1;
for (;;) for (;;)
{ {
unsigned m_off, m_len; unsigned m_off, m_len;
while (GETBIT(bb,src,ilen)) while (GETBIT(bb,src,ilen))
{ {
dst[olen++] = src[ilen++]; dst[olen++] = src[ilen++];
} }
m_off = 1; m_off = 1;
for (;;) for (;;)
{ {
m_off = m_off*2 + GETBIT(bb,src,ilen); m_off = m_off*2 + GETBIT(bb,src,ilen);
if (GETBIT(bb,src,ilen)) break; if (GETBIT(bb,src,ilen)) break;
m_off = (m_off-1)*2 + GETBIT(bb,src,ilen); m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
} }
if (m_off == 2) if (m_off == 2)
{ {
m_off = last_m_off; m_off = last_m_off;
m_len = GETBIT(bb,src,ilen); m_len = GETBIT(bb,src,ilen);
} }
else else
{ {
m_off = (m_off-3)*256 + src[ilen++]; m_off = (m_off-3)*256 + src[ilen++];
if (m_off == 0xffffffff) if (m_off == 0xffffffff)
break; break;
m_len = (m_off ^ 0xffffffff) & 1; m_len = (m_off ^ 0xffffffff) & 1;
m_off >>= 1; m_off >>= 1;
last_m_off = ++m_off; last_m_off = ++m_off;
} }
if (m_len) if (m_len)
m_len = 1 + GETBIT(bb,src,ilen); m_len = 1 + GETBIT(bb,src,ilen);
else if (GETBIT(bb,src,ilen)) else if (GETBIT(bb,src,ilen))
m_len = 3 + GETBIT(bb,src,ilen); m_len = 3 + GETBIT(bb,src,ilen);
else else
{ {
m_len++; m_len++;
do { do {
m_len = m_len*2 + GETBIT(bb,src,ilen); m_len = m_len*2 + GETBIT(bb,src,ilen);
} while (!GETBIT(bb,src,ilen)); } while (!GETBIT(bb,src,ilen));
m_len += 3; m_len += 3;
} }
m_len += (m_off > 0x500); m_len += (m_off > 0x500);
{ {
const UINT8 *m_pos; const UINT8 *m_pos;
m_pos = dst + olen - m_off; m_pos = dst + olen - m_off;
dst[olen++] = *m_pos++; dst[olen++] = *m_pos++;
do dst[olen++] = *m_pos++; while (--m_len > 0); do dst[olen++] = *m_pos++; while (--m_len > 0);
} }
} }
*dst_len = olen; *dst_len = olen;
return ilen; return ilen;
} }
// move the image into place and start it /* move the image into place and start it */
void DecompressStart(tImage* pImage) void DecompressStart(tImage* pImage)
{ {
UINT32* pSrc; UINT32* pSrc;
UINT32* pDest; UINT32* pDest;
pSrc = pImage->image; pSrc = pImage->image;
pDest = pImage->pDestination; pDest = pImage->pDestination;
if (pSrc != pDest) // if not linked to that flash address if (pSrc != pDest) /* if not linked to that flash address */
{ {
if (pImage->flags & IF_UCL_2E) if (pImage->flags & IF_UCL_2E)
{ // UCL compressed, algorithm 2e { /* UCL compressed, algorithm 2e */
UINT32 dst_len; // dummy UINT32 dst_len; /* dummy */
ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len); ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len);
} }
else else
{ // uncompressed, copy it { /* uncompressed, copy it */
UINT32 size = pImage->size; UINT32 size = pImage->size;
UINT32* pEnd; UINT32* pEnd;
size = (size + 3) / 4; // round up to 32bit-words size = (size + 3) / 4; /* round up to 32bit-words */
pEnd = pDest + size; pEnd = pDest + size;
do do
{ {
*pDest++ = *pSrc++; *pDest++ = *pSrc++;
} }
while (pDest < pEnd); while (pDest < pEnd);
} }
} }
pImage->pExecute(); pImage->pExecute();
} }
#ifdef USE_ADC #ifdef USE_ADC
int ReadADC(int channel) int ReadADC(int channel)
{ {
// after channel 3, the ports wrap and get re-used /* after channel 3, the ports wrap and get re-used */
volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03)); volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03));
int timeout = 266; // conversion takes 266 clock cycles int timeout = 266; /* conversion takes 266 clock cycles */
ADCSR = 0x20 | channel; // start single conversion ADCSR = 0x20 | channel; /* start single conversion */
while (((ADCSR & 0x80) == 0) && (--timeout)); // 6 instructions per round while (((ADCSR & 0x80) == 0) && (--timeout)); /* 6 instructions per round*/
return (timeout == 0) ? -1 : *pResult>>6; return (timeout == 0) ? -1 : *pResult>>6;
} }
#endif #endif
// This function is platform-dependent, /* This function is platform-dependent,
// until I figure out how to distinguish at runtime. * until I figure out how to distinguish at runtime. */
int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed int ButtonPressed(void) /* return 1,2,3 for F1,F2,F3, 0 if none pressed */
{ {
#ifdef USE_ADC #ifdef USE_ADC
int value = ReadADC(CHANNEL); int value = ReadADC(CHANNEL);
if (value >= F1_LOWER && value <= F1_UPPER) // in range if (value >= F1_LOWER && value <= F1_UPPER) /* in range */
return 1; return 1;
else if (value >= F2_LOWER && value <= F2_UPPER) // in range else if (value >= F2_LOWER && value <= F2_UPPER) /* in range */
return 2; return 2;
else if (value >= F3_LOWER && value <= F3_UPPER) // in range else if (value >= F3_LOWER && value <= F3_UPPER) /* in range */
return 3; return 3;
#else #else
int value = PCDR; int value = PCDR;
if (!(value & F1_MASK)) if (!(value & F1_MASK))
return 1; return 1;
else if (!(value & F2_MASK)) else if (!(value & F2_MASK))
@ -294,205 +296,209 @@ int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed
else if (!(value & F3_MASK)) else if (!(value & F3_MASK))
return 3; return 3;
#endif #endif
return 0; return 0;
} }
// Determine the image to be started /* Determine the image to be started */
tImage* GetStartImage(int nPreferred) tImage* GetStartImage(int nPreferred)
{ {
tImage* pImage1; tImage* pImage1;
tImage* pImage2 = NULL; // default to not present tImage* pImage2 = NULL; /* default to not present */
UINT32 pos; UINT32 pos;
UINT32* pFlash = (UINT32*)FLASH_BASE; UINT32* pFlash = (UINT32*)FLASH_BASE;
// 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
pos = (pos + 3) & ~3; // be shure it's 32 bit aligned * = after it */
pos = (pos + 3) & ~3; /* be sure it's 32 bit aligned */
pImage1 = (tImage*)pos; pImage1 = (tImage*)pos;
if (pImage1->size != 0) if (pImage1->size != 0)
{ // check for second image { /* check for second image */
pos = (UINT32)(&pImage1->image) + pImage1->size; pos = (UINT32)(&pImage1->image) + pImage1->size;
pImage2 = (tImage*)pos; pImage2 = (tImage*)pos;
// does it make sense? (not in FF or 00 erazed space) /* does it make sense? (not in FF or 00 erazed space) */
if (pImage2->pDestination == (void*)0xFFFFFFFF if (pImage2->pDestination == (void*)0xFFFFFFFF
|| pImage2->size == 0xFFFFFFFF || pImage2->size == 0xFFFFFFFF
|| pImage2->pExecute == (void*)0xFFFFFFFF || pImage2->pExecute == (void*)0xFFFFFFFF
|| pImage2->flags == 0xFFFFFFFF || pImage2->flags == 0xFFFFFFFF
|| pImage2->pDestination == NULL) // size, execute and flags can legally be 0 || pImage2->pDestination == NULL)
{ /* size, execute and flags can legally be 0 */
pImage2 = NULL; // invalidate {
} pImage2 = NULL; /* invalidate */
} }
}
if (pImage2 == NULL || nPreferred == 1) if (pImage2 == NULL || nPreferred == 1)
{ // no second image or overridden: return the first { /* no second image or overridden: return the first */
return pImage1; return pImage1;
} }
return pImage2; // return second image return pImage2; /* return second image */
} }
// diagnostic functions /* diagnostic functions */
void SetLed(BOOL bOn) void SetLed(BOOL bOn)
{ {
if (bOn) if (bOn)
PBDR |= 0x40; PBDR |= 0x0040;
else else
PBDR &= ~0x40; PBDR &= ~0x0040;
} }
void UartInit(void) void UartInit(void)
{ {
PBIOR &= 0xFBFF; // input: RXD1 remote pin PBIOR &= 0xFBFF; /* input: RXD1 remote pin */
PBCR1 |= 0x00A0; // set PB3+PB2 to UART PBCR1 |= 0x00A0; /* set PB11+PB10 to UART */
PBCR1 &= 0xFFAF; // clear bits 6, 4 -> UART PBCR1 &= 0xFFAF; /* clear bits 6, 4 -> UART */
SMR1 = 0x0000; // async format 8N1, baud generator input is CPU clock SMR1 = 0x00; /* async format 8N1, baud generator input is CPU clock */
SCR1 = 0x0030; // transmit+receive enable SCR1 = 0x30; /* transmit+receive enable */
PBCR1 &= 0x00FF; // set bit 12...15 as GPIO PBCR1 &= 0x00FF; /* set bit 12...15 as GPIO */
SSR1 &= 0x00BF; // clear bit 6 (RDRF, receive data register full) SSR1 &= 0xBF; /* clear bit 6 (RDRF, receive data register full) */
} }
UINT8 UartRead(void) UINT8 UartRead(void)
{ {
UINT8 byte; UINT8 byte;
while (!(SSR1 & SCI_RDRF)); // wait for char to be available while (!(SSR1 & SCI_RDRF)); /* wait for char to be available */
byte = RDR1; byte = RDR1;
SSR1 &= ~SCI_RDRF; SSR1 &= ~SCI_RDRF;
return byte; return byte;
} }
void UartWrite(UINT8 byte) void UartWrite(UINT8 byte)
{ {
while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty while (!(SSR1 & SCI_TDRE)); /* wait for transmit buffer empty */
TDR1 = byte; TDR1 = byte;
SSR1 &= ~SCI_TDRE; SSR1 &= ~SCI_TDRE;
} }
// include the mini monitor as a rescue feature, started with F3 /* include the mini monitor as a rescue feature, started with F3 */
void MiniMon(void) void MiniMon(void)
{ {
UINT8 cmd; UINT8 cmd;
UINT32 addr; UINT32 addr;
UINT32 size; UINT32 size;
UINT32 content; UINT32 content;
volatile UINT8* paddr = NULL; volatile UINT8* paddr = NULL;
volatile UINT8* pflash = NULL; // flash base address volatile UINT8* pflash = NULL; /* flash base address */
UartInit(); UartInit();
while (1) while (1)
{ {
cmd = UartRead(); cmd = UartRead();
switch (cmd) switch (cmd)
{ {
case BAUDRATE: case BAUDRATE:
content = UartRead(); content = UartRead();
UartWrite(cmd); // acknowledge by returning the command value UartWrite(cmd); /* acknowledge by returning the command value */
while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate while (!(SSR1 & SCI_TEND)); /* wait for empty shift register,
BRR1 = content; * before changing baudrate */
break; BRR1 = content;
break;
case ADDRESS: case ADDRESS:
addr = (UartRead() << 24) | (UartRead() << 16) | (UartRead() << 8) | UartRead(); addr = (UartRead() << 24) | (UartRead() << 16)
paddr = (UINT8*)addr; | (UartRead() << 8) | UartRead();
pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align paddr = (UINT8*)addr;
UartWrite(cmd); // acknowledge by returning the command value pflash = (UINT8*)(addr & 0xFFF80000); /* round down to 512k align*/
break; UartWrite(cmd); /* acknowledge by returning the command value */
break;
case BYTE_READ: case BYTE_READ:
content = *paddr++; content = *paddr++;
UartWrite(content); // the content is the ack UartWrite(content); /* the content is the ack */
break; break;
case BYTE_WRITE: case BYTE_WRITE:
content = UartRead(); content = UartRead();
*paddr++ = content; *paddr++ = content;
UartWrite(cmd); // acknowledge by returning the command value UartWrite(cmd); /* acknowledge by returning the command value */
break; break;
case BYTE_READ16: case BYTE_READ16:
size = 16; size = 16;
while (size--) while (size--)
{ {
content = *paddr++; content = *paddr++;
UartWrite(content); // the content is the ack UartWrite(content); /* the content is the ack */
} }
break; break;
case BYTE_WRITE16: case BYTE_WRITE16:
size = 16; size = 16;
while (size--) while (size--)
{ {
content = UartRead(); content = UartRead();
*paddr++ = content; *paddr++ = content;
} }
UartWrite(cmd); // acknowledge by returning the command value UartWrite(cmd); /* acknowledge by returning the command value */
break; break;
case BYTE_FLASH: case BYTE_FLASH:
content = UartRead(); content = UartRead();
pflash[0x5555] = 0xAA; // set flash to command mode pflash[0x5555] = 0xAA; /* set flash to command mode */
pflash[0x2AAA] = 0x55; pflash[0x2AAA] = 0x55;
pflash[0x5555] = 0xA0; // byte program command pflash[0x5555] = 0xA0; /* byte program command */
*paddr++ = content; *paddr++ = content;
UartWrite(cmd); // acknowledge by returning the command value UartWrite(cmd); /* acknowledge by returning the command value */
break; break;
case BYTE_FLASH16: case BYTE_FLASH16:
size = 16; size = 16;
while (size--) while (size--)
{ {
content = UartRead(); content = UartRead();
pflash[0x5555] = 0xAA; // set flash to command mode pflash[0x5555] = 0xAA; /* set flash to command mode */
pflash[0x2AAA] = 0x55; pflash[0x2AAA] = 0x55;
pflash[0x5555] = 0xA0; // byte program command pflash[0x5555] = 0xA0; /* byte program command */
*paddr++ = content; *paddr++ = content;
} }
UartWrite(cmd); // acknowledge by returning the command value UartWrite(cmd); /* acknowledge by returning the command value */
break; break;
case HALFWORD_READ: case HALFWORD_READ:
content = *(UINT16*)paddr; content = *(UINT16*)paddr;
paddr += 2; paddr += 2;
UartWrite(content >> 8); // highbyte UartWrite(content >> 8); /* highbyte */
UartWrite(content & 0xFF); // lowbyte UartWrite(content & 0xFF); /* lowbyte */
break; break;
case HALFWORD_WRITE:
content = UartRead() << 8 | UartRead();
*(UINT16*)paddr = content;
paddr += 2;
UartWrite(cmd); // acknowledge by returning the command value
break;
case EXECUTE:
{
tpFunc pFunc = (tpFunc)paddr;
pFunc();
UartWrite(cmd); // acknowledge by returning the command value
}
break;
case VERSION: case HALFWORD_WRITE:
UartWrite(1); // return our version number content = UartRead() << 8 | UartRead();
break; *(UINT16*)paddr = content;
paddr += 2;
UartWrite(cmd); /* acknowledge by returning the command value */
break;
default: case EXECUTE:
{ {
SetLed(TRUE); tpFunc pFunc = (tpFunc)paddr;
UartWrite(~cmd); // error acknowledge pFunc();
} UartWrite(cmd); /* acknowledge by returning the command value*/
}
break;
} // case case VERSION:
} // while (1) UartWrite(1); /* return our version number */
break;
default:
{
SetLed(TRUE);
UartWrite(~cmd); /* error acknowledge */
}
} /* case */
} /* while (1) */
} }