Flash Programming In System
After last night’s discovery that I need to rethink how I program flash, the solution turned out to be pretty painless.
I modified the flash.c to handle the flash in system. Here is flash.c with a new function, activateFlash(uint8_t cmd, bool doCycle4_5):
1 #include <assert.h>
2 #include "common.h"
3 #include "flash.h"
4 #include "memBank.h"
5
6 // reads the flash and waits for the toggle bit to stop toggling.
7 // returns true if the read byte matched expected. Use 0xff when
8 // erasing
9 bool toggle(volatile uint8_t* vaddr, uint8_t expected)
10 {
11 uint8_t b0 = *vaddr;
12 uint8_t b1 = *vaddr;
13 while (b0 != b1) {
14 b0 = b1;
15 b1 = *vaddr;
16 }
17 return b0 == expected;
18 }
19
20 // Flash activation from within the system requires the following:
21 // 1) program must be running from RAM
22 // 2) to activate the flash, specific bytes must be written to
23 // 2aaa and 5555 of the flash AFTER bank switching. This
24 // means that banks 0 and 1 must be mapped into memory and
25 // 2aaa+offset and 5555+offset be programmed
26 // 3) the bank the user is interested in must be swapped in
27 // before the action address is written.
28 void activateFlash(uint8_t cmd, bool doCycle4_5)
29 {
30 volatile uint8_t* v2aaa = (uint8_t*)(0x2aaa + 0x4000);
31 volatile uint8_t* v5555 = (uint8_t*)(0x5555 + 0x4000);
32 uint8_t oldBanks[4];
33 uint8_t banks[4];
34
35 getBanks(banks);
36 getBanks(oldBanks);
37 banks[1] = 0;
38 banks[2] = 1;
39 setBanks(banks);
40 switchBanks();
41
42 *v5555 = (uint8_t)0xaa;
43 *v2aaa = (uint8_t)0x55;
44 *v5555 = cmd;
45
46 if (doCycle4_5)
47 {
48 *v5555 = (uint8_t)0xaa;
49 *v2aaa = (uint8_t)0x55;
50 }
51
52 setBanks(oldBanks);
53 switchBanks();
54 }
55
56 // Programs a byte to flash. Returns true if the byte matches
57 // when toggling is finished
58 bool flashProgramByte(uint8_t b, uint8_t* addr)
59 {
60 volatile uint8_t* vaddr = addr;
61 activateFlash(0xa0, false);
62 *vaddr = b;
63 return toggle(vaddr, b);
64 }
65
66 // Programs a block to flash. Returns true if all the bytes match
67 // when toggling is finished.
68 bool flashProgramBlock(uint8_t* b, uint16_t count, uint8_t* addr)
69 {
70 uint16_t i;
71 bool ok = true;
72 volatile uint8_t* vaddr = addr;
73 for (i = 0; i < count; i++)
74 {
75 ok = ok && flashProgramByte(b[i], vaddr + i);
76 }
77 return ok;
78 }
79
80 // Erase a 4k sector. Sector must be 0-15
81 bool flashEraseSector(uint8_t sector)
82 {
83 volatile uint8_t* vaddr = (uint8_t*)(sector<<12);
84 assert(sector < 16);
85 activateFlash(0x80, true);
86 *vaddr = (uint8_t)0x30;
87 return toggle(vaddr, 0xff);
88 }
89
90 // Returns true if all bytes in a sector are 0xff
91 bool flashVerifyErased(uint8_t sector)
92 {
93 volatile uint8_t* vaddr = (uint8_t*)(sector << 12);
94 uint16_t i;
95 assert(sector < 16);
96 for (i = 0; i < 0x1000; i++)
97 {
98 if (vaddr[i] != 0xff)
99 {
100 return false;
101 }
102 }
103 return true;
104 }
I added a new function to activate the flash. It gets the current bank setup, swaps in banks 0 and 1 of flash, activates the flash, and restores the banks.
And here is my menu running:
1 Mark Hamann's Z80 Computer
2
3 Version: 0.1 beta
4 Menu
5
6 1) dump text
7 2) dump copy blocktext
8 3) erase bank
9 4) program byte
10 5) write byte
11 6) bank switch
12 > 2
13 This will copy memory to RAM memory.
14 Source (hex)? 0
15 Dest (hex)? 8000
16 Length (hex)? 4000
17 Copied
18 Done!
19
20 Mark Hamann's Z80 Computer
21
22 Version: 0.1 beta
23 Menu
24
25 1) dump text
26 2) dump copy blocktext
27 3) erase bank
28 4) program byte
29 5) write byte
30 6) bank switch
31 > 1
32 Address (hex)? 8000
33 Length (hex)? 20
34 -8000: c3 69 00 ff ff ff ff ff c3 a3 13 ff ff ff ff ff .i...... ........
35 -7ff0: c3 b4 13 ff ff ff ff ff c3 c5 13 ff ff ff ff ff ........ ........
36 Done!
37
38 Mark Hamann's Z80 Computer
39
40 Version: 0.1 beta
41 Menu
42
43 1) dump text
44 2) dump copy blocktext
45 3) erase bank
46 4) program byte
47 5) write byte
48 6) bank switch
49 > 6
50 This allows to switch all 4 banks
51 Only switch bank 0 when
52 Use hex where 0-f are flash and 10-17 are RAM
53 bank #0 [now==00]? 10
54 bank #1 [now==01]? 2
55 bank #2 [now==10]? 2
56 bank #3 [now==11]? 11
57 Switching...
58 Done!
59
60 Mark Hamann's Z80 Computer
61
62 Version: 0.1 beta
63 Menu
64
65 1) dump text
66 2) dump copy blocktext
67 3) erase bank
68 4) program byte
69 5) write byte
70 6) bank switch
71 > 1
72 Address (hex)? 3ff0
73 Length (hex)? 10
74 3ff0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
75 Done!
76
77 Mark Hamann's Z80 Computer
78
79 Version: 0.1 beta
80 Menu
81
82 1) dump text
83 2) dump copy blocktext
84 3) erase bank
85 4) program byte
86 5) write byte
87 6) bank switch
88 > 5
89 This will write a byte.
90 Address (hex)? 3fff
91 Done!
92
93 Mark Hamann's Z80 Computer
94
95 Version: 0.1 beta
96 Menu
97
98 1) dump text
99 2) dump copy blocktext
100 3) erase bank
101 4) program byte
102 5) write byte
103 6) bank switch
104 > 1
105 Address (hex)? 3ff0
106 Length (hex)? 10
107 3ff0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 ........ ........
108 Done!
109
110 Mark Hamann's Z80 Computer
111
112 Version: 0.1 beta
113 Menu
114
115 1) dump text
116 2) dump copy blocktext
117 3) erase bank
118 4) program byte
119 5) write byte
120 6) bank switch
121 > 1
122 Address (hex)? 4000
123 Length (hex)? 10
124 4000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
125 Done!
126
127 Mark Hamann's Z80 Computer
128
129 Version: 0.1 beta
130 Menu
131
132 1) dump text
133 2) dump copy blocktext
134 3) erase bank
135 4) program byte
136 5) write byte
137 6) bank switch
138 > 4
139 This will program a byte.
140 Address (hex)? 4000
141 value (hex)? fe
142 Programmed
143
144 Done!
145
146 Mark Hamann's Z80 Computer
147
148 Version: 0.1 beta
149 Menu
150
151 1) dump text
152 2) dump copy blocktext
153 3) erase bank
154 4) program byte
155 5) write byte
156 6) bank switch
157 > 1
158 Address (hex)? 4000
159 Length (hex)? 10
160 4000: fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
161 Done!
162
163 Mark Hamann's Z80 Computer
164
165 Version: 0.1 beta
166 Menu
167
168 1) dump text
169 2) dump copy blocktext
170 3) erase bank
171 4) program byte
172 5) write byte
173 6) bank switch
174 > 4
175 This will program a byte.
176 Address (hex)? 4001
177 value (hex)? fb
178 Programmed
179
180 Done!
181
182 Mark Hamann's Z80 Computer
183
184 Version: 0.1 beta
185 Menu
186
187 1) dump text
188 2) dump copy blocktext
189 3) erase bank
190 4) program byte
191 5) write byte
192 6) bank switch
193 > 1
194 Address (hex)? 4000
195 Length (hex)? 10
196 4000: fe fb ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
197 Done!
198
199 Mark Hamann's Z80 Computer
200
201 Version: 0.1 beta
202 Menu
203
204 1) dump text
205 2) dump copy blocktext
206 3) erase bank
207 4) program byte
208 5) write byte
209 6) bank switch
210 >
The next step was to see if I could erase it–but that took a couple of code changes first… But here is the result:
1 Mark Hamann's Z80 Computer
2
3 Version: 0.1 beta
4 Menu
5
6 1) dump text
7 2) copy block
8 3) erase sector
9 4) program byte
10 5) write byte
11 6) bank switch
12 > 2
13 This will copy memory to RAM memory.
14 Source (hex)? 0
15 Dest (hex)? 8000
16 Length (hex)? 4000
17 Copied
18 Done!
19
20 Mark Hamann's Z80 Computer
21
22 Version: 0.1 beta
23 Menu
24
25 1) dump text
26 2) copy block
27 3) erase sector
28 4) program byte
29 5) write byte
30 6) bank switch
31 > 6
32 This allows to switch all 4 banks
33 Only switch bank 0 when
34 Use hex where 0-f are flash and 10-17 are RAM
35 bank #0 [now==00]? 10
36 bank #1 [now==01]? 2
37 bank #2 [now==10]? 2
38 bank #3 [now==11]? 11
39 Switching...
40 Done!
41
42 Mark Hamann's Z80 Computer
43
44 Version: 0.1 beta
45 Menu
46
47 1) dump text
48 2) copy block
49 3) erase sector
50 4) program byte
51 5) write byte
52 6) bank switch
53 > 1
54 Address (hex)? 4000
55 Length (hex)? 10
56 4000: fe fb ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
57 Done!
58
59 Mark Hamann's Z80 Computer
60
61 Version: 0.1 beta
62 Menu
63
64 1) dump text
65 2) copy block
66 3) erase sector
67 4) program byte
68 5) write byte
69 6) bank switch
70 > 3
71 This allows erase a sector. Ensure the sector is flash
72 sector (hex: 0-f)? 4
73 Erased and verified
74 Done!
75
76 Mark Hamann's Z80 Computer
77
78 Version: 0.1 beta
79 Menu
80
81 1) dump text
82 2) copy block
83 3) erase sector
84 4) program byte
85 5) write byte
86 6) bank switch
87 > 1
88 Address (hex)? 4000
89 Length (hex)? 10
90 4000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ........
91 Done!
92
93 Mark Hamann's Z80 Computer
94
95 Version: 0.1 beta
96 Menu
97
98 1) dump text
99 2) copy block
100 3) erase sector
101 4) program byte
102 5) write byte
103 6) bank switch
104 >
As you can see, the fe and fb that I programmed into bank 2 were erased. Yay!!!!
With this, I’m closer to having the ihx file uploading. I just need to do a visual inspection of my ihx upload code and then I’ll be ready to load it into my menu. But first, I need a program block menu item that will copy a block into flash.
I also need to handle backspace better. It seems to work on the screen, but my hex conversion returns an error if I use the gets string where backspace happened. Also, the buffer limit for gets isn’t working quite right.