summaryrefslogtreecommitdiff
path: root/flash/minimon/minimon.c
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
commit6a4e4c87c24455e18bbd77565cb3e993ee350618 (patch)
tree6f2ceac4da97aa63ff8deef939bd3cc2d56d3466 /flash/minimon/minimon.c
parent014c4fa1f8d56850cfd504a90221c293e4a158f6 (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.c156
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;
+}