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