diff options
author | Jens Arnold <amiconn@rockbox.org> | 2004-12-03 21:43:21 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2004-12-03 21:43:21 +0000 |
commit | 4b3501f2f6ad19b6422561f94926cc90fecfa0bd (patch) | |
tree | 4b922f1355e647f70ef0816f1b525f46d5ba6106 /flash/bootloader/bootloader.c | |
parent | 059ada52d0784c31ec34e651b846e78134f93f61 (diff) |
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
Diffstat (limited to 'flash/bootloader/bootloader.c')
-rw-r--r-- | flash/bootloader/bootloader.c | 744 |
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) */ } |