diff options
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 @@ | |||
1 | // minimalistic monitor | ||
2 | // to be loaded with the UART boot feature | ||
3 | // capable of reading and writing bytes, commanded by UART | ||
4 | |||
5 | #include "sh7034.h" | ||
6 | #include "minimon.h" | ||
7 | |||
8 | // scalar types | ||
9 | typedef unsigned char UINT8; | ||
10 | typedef unsigned short UINT16; | ||
11 | typedef unsigned long UINT32; | ||
12 | |||
13 | typedef void(*tpFunc)(void); // type for exec | ||
14 | typedef int(*tpMain)(void); // type for start vector to main() | ||
15 | |||
16 | |||
17 | // prototypes | ||
18 | int main(void); | ||
19 | |||
20 | // our binary has to start with a vector to the entry point | ||
21 | tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main}; | ||
22 | |||
23 | |||
24 | UINT8 uart_read(void) | ||
25 | { | ||
26 | UINT8 byte; | ||
27 | while (!(SSR1 & SCI_RDRF)); // wait for char to be available | ||
28 | byte = RDR1; | ||
29 | SSR1 &= ~SCI_RDRF; | ||
30 | return byte; | ||
31 | } | ||
32 | |||
33 | |||
34 | void uart_write(UINT8 byte) | ||
35 | { | ||
36 | while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty | ||
37 | TDR1 = byte; | ||
38 | SSR1 &= ~SCI_TDRE; | ||
39 | } | ||
40 | |||
41 | |||
42 | int main(void) | ||
43 | { | ||
44 | UINT8 cmd; | ||
45 | UINT32 addr; | ||
46 | UINT32 size; | ||
47 | UINT32 content; | ||
48 | volatile UINT8* paddr = 0; | ||
49 | volatile UINT8* pflash; // flash base address | ||
50 | |||
51 | while (1) | ||
52 | { | ||
53 | cmd = uart_read(); | ||
54 | switch (cmd) | ||
55 | { | ||
56 | case BAUDRATE: | ||
57 | content = uart_read(); | ||
58 | uart_write(cmd); // acknowledge by returning the command value | ||
59 | while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate | ||
60 | BRR1 = content; | ||
61 | break; | ||
62 | |||
63 | case ADDRESS: | ||
64 | addr = (uart_read() << 24) | (uart_read() << 16) | (uart_read() << 8) | uart_read(); | ||
65 | paddr = (UINT8*)addr; | ||
66 | pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align | ||
67 | uart_write(cmd); // acknowledge by returning the command value | ||
68 | break; | ||
69 | |||
70 | case BYTE_READ: | ||
71 | content = *paddr++; | ||
72 | uart_write(content); // the content is the ack | ||
73 | break; | ||
74 | |||
75 | case BYTE_WRITE: | ||
76 | content = uart_read(); | ||
77 | *paddr++ = content; | ||
78 | uart_write(cmd); // acknowledge by returning the command value | ||
79 | break; | ||
80 | |||
81 | case BYTE_READ16: | ||
82 | size = 16; | ||
83 | while (size--) | ||
84 | { | ||
85 | content = *paddr++; | ||
86 | uart_write(content); // the content is the ack | ||
87 | } | ||
88 | break; | ||
89 | |||
90 | case BYTE_WRITE16: | ||
91 | size = 16; | ||
92 | while (size--) | ||
93 | { | ||
94 | content = uart_read(); | ||
95 | *paddr++ = content; | ||
96 | } | ||
97 | uart_write(cmd); // acknowledge by returning the command value | ||
98 | break; | ||
99 | |||
100 | case BYTE_FLASH: | ||
101 | content = uart_read(); | ||
102 | pflash[0x5555] = 0xAA; // set flash to command mode | ||
103 | pflash[0x2AAA] = 0x55; | ||
104 | pflash[0x5555] = 0xA0; // byte program command | ||
105 | *paddr++ = content; | ||
106 | uart_write(cmd); // acknowledge by returning the command value | ||
107 | break; | ||
108 | |||
109 | case BYTE_FLASH16: | ||
110 | size = 16; | ||
111 | while (size--) | ||
112 | { | ||
113 | content = uart_read(); | ||
114 | pflash[0x5555] = 0xAA; // set flash to command mode | ||
115 | pflash[0x2AAA] = 0x55; | ||
116 | pflash[0x5555] = 0xA0; // byte program command | ||
117 | *paddr++ = content; | ||
118 | } | ||
119 | uart_write(cmd); // acknowledge by returning the command value | ||
120 | break; | ||
121 | |||
122 | case HALFWORD_READ: | ||
123 | content = *(UINT16*)paddr; | ||
124 | paddr += 2; | ||
125 | uart_write(content >> 8); // highbyte | ||
126 | uart_write(content & 0xFF); // lowbyte | ||
127 | break; | ||
128 | |||
129 | case HALFWORD_WRITE: | ||
130 | content = uart_read() << 8 | uart_read(); | ||
131 | *(UINT16*)paddr = content; | ||
132 | paddr += 2; | ||
133 | uart_write(cmd); // acknowledge by returning the command value | ||
134 | break; | ||
135 | |||
136 | case EXECUTE: | ||
137 | { | ||
138 | tpFunc pFunc = (tpFunc)paddr; | ||
139 | pFunc(); | ||
140 | uart_write(cmd); // acknowledge by returning the command value | ||
141 | } | ||
142 | break; | ||
143 | |||
144 | |||
145 | default: | ||
146 | { | ||
147 | volatile UINT16* pPortB = (UINT16*)0x05FFFFC2; | ||
148 | *pPortB |= 1 << 6; // bit 6 is red LED on | ||
149 | uart_write(~cmd); // error acknowledge | ||
150 | } | ||
151 | |||
152 | } // case | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||