diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-11-30 11:37:43 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-11-30 11:37:43 +0000 |
commit | 6a4e4c87c24455e18bbd77565cb3e993ee350618 (patch) | |
tree | 6f2ceac4da97aa63ff8deef939bd3cc2d56d3466 /flash/minimon/minimon.c | |
parent | 014c4fa1f8d56850cfd504a90221c293e4a158f6 (diff) |
source code for all my flash stuff, now finally in cvs
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4083 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'flash/minimon/minimon.c')
-rw-r--r-- | flash/minimon/minimon.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/flash/minimon/minimon.c b/flash/minimon/minimon.c new file mode 100644 index 0000000000..e7981f2d09 --- /dev/null +++ b/flash/minimon/minimon.c @@ -0,0 +1,156 @@ +// minimalistic monitor +// to be loaded with the UART boot feature +// capable of reading and writing bytes, commanded by UART + +#include "sh7034.h" +#include "minimon.h" + +// scalar types +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned long UINT32; + +typedef void(*tpFunc)(void); // type for exec +typedef int(*tpMain)(void); // type for start vector to main() + + +// prototypes +int main(void); + +// our binary has to start with a vector to the entry point +tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main}; + + +UINT8 uart_read(void) +{ + UINT8 byte; + while (!(SSR1 & SCI_RDRF)); // wait for char to be available + byte = RDR1; + SSR1 &= ~SCI_RDRF; + return byte; +} + + +void uart_write(UINT8 byte) +{ + while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty + TDR1 = byte; + SSR1 &= ~SCI_TDRE; +} + + +int main(void) +{ + UINT8 cmd; + UINT32 addr; + UINT32 size; + UINT32 content; + volatile UINT8* paddr = 0; + volatile UINT8* pflash; // flash base address + + while (1) + { + cmd = uart_read(); + switch (cmd) + { + case BAUDRATE: + content = uart_read(); + uart_write(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 = (uart_read() << 24) | (uart_read() << 16) | (uart_read() << 8) | uart_read(); + paddr = (UINT8*)addr; + pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align + uart_write(cmd); // acknowledge by returning the command value + break; + + case BYTE_READ: + content = *paddr++; + uart_write(content); // the content is the ack + break; + + case BYTE_WRITE: + content = uart_read(); + *paddr++ = content; + uart_write(cmd); // acknowledge by returning the command value + break; + + case BYTE_READ16: + size = 16; + while (size--) + { + content = *paddr++; + uart_write(content); // the content is the ack + } + break; + + case BYTE_WRITE16: + size = 16; + while (size--) + { + content = uart_read(); + *paddr++ = content; + } + uart_write(cmd); // acknowledge by returning the command value + break; + + case BYTE_FLASH: + content = uart_read(); + pflash[0x5555] = 0xAA; // set flash to command mode + pflash[0x2AAA] = 0x55; + pflash[0x5555] = 0xA0; // byte program command + *paddr++ = content; + uart_write(cmd); // acknowledge by returning the command value + break; + + case BYTE_FLASH16: + size = 16; + while (size--) + { + content = uart_read(); + pflash[0x5555] = 0xAA; // set flash to command mode + pflash[0x2AAA] = 0x55; + pflash[0x5555] = 0xA0; // byte program command + *paddr++ = content; + } + uart_write(cmd); // acknowledge by returning the command value + break; + + case HALFWORD_READ: + content = *(UINT16*)paddr; + paddr += 2; + uart_write(content >> 8); // highbyte + uart_write(content & 0xFF); // lowbyte + break; + + case HALFWORD_WRITE: + content = uart_read() << 8 | uart_read(); + *(UINT16*)paddr = content; + paddr += 2; + uart_write(cmd); // acknowledge by returning the command value + break; + + case EXECUTE: + { + tpFunc pFunc = (tpFunc)paddr; + pFunc(); + uart_write(cmd); // acknowledge by returning the command value + } + break; + + + default: + { + volatile UINT16* pPortB = (UINT16*)0x05FFFFC2; + *pPortB |= 1 << 6; // bit 6 is red LED on + uart_write(~cmd); // error acknowledge + } + + } // case + } + + return 0; +} |