blob: e7981f2d090271637cd0f064c548b4780d9e163e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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;
}
|