Mercurial > ~darius > hgwebdir.cgi > stm32temp
comparison flash.c @ 25:a9cc07caa801
Add stream read/write commands.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 17 Nov 2012 12:18:24 +1030 |
parents | bd8e2cf04034 |
children | 74efdb21ae5d |
comparison
equal
deleted
inserted
replaced
24:1e2fa7396f98 | 25:a9cc07caa801 |
---|---|
1 #include <stdio.h> | 1 #include <stdio.h> |
2 #include <stdint.h> | 2 #include <stdint.h> |
3 #include <string.h> | 3 #include <string.h> |
4 #include <stdlib.h> | 4 #include <stdlib.h> |
5 #include <assert.h> | |
5 | 6 |
6 #include "stm32f10x.h" | 7 #include "stm32f10x.h" |
7 #include "spi.h" | 8 #include "spi.h" |
8 #include "flash.h" | 9 #include "flash.h" |
9 | 10 |
18 "BP2", | 19 "BP2", |
19 "BP3", | 20 "BP3", |
20 "AAI", | 21 "AAI", |
21 "BPL" | 22 "BPL" |
22 }; | 23 }; |
23 | 24 |
25 #define RW_IDLE 0 | |
26 #define RW_RUNNING 1 | |
27 #define RW_IDLE 0 | |
28 | |
29 static int writestate = RW_IDLE; | |
30 static int readstate = RW_IDLE; | |
31 | |
24 void | 32 void |
25 flashcmd(char **argv, int argc) { | 33 flashcmd(char **argv, int argc) { |
26 uint8_t status, tmp; | 34 uint8_t status, tmp; |
27 | 35 |
28 if (argc == 0) { | 36 if (argc == 0) { |
61 fputs("Incorrect number of arguments\r\n", stdout); | 69 fputs("Incorrect number of arguments\r\n", stdout); |
62 return; | 70 return; |
63 } | 71 } |
64 tmp = atoi(argv[1]); | 72 tmp = atoi(argv[1]); |
65 | 73 |
74 flashstartread(tmp); | |
75 | |
66 for (int i = 0; i < 16; i++) | 76 for (int i = 0; i < 16; i++) |
67 printf("Read 0x%02x from 0x%06x\r\n", flashread(tmp + i), tmp + i); | 77 printf("Read 0x%02x from 0x%06x\r\n", flashreadbyte(), tmp + i); |
78 flashstopread(); | |
79 | |
68 fputs("\r\n", stdout); | 80 fputs("\r\n", stdout); |
69 } else if (!strcmp(argv[0], "wr")) { | 81 } else if (!strcmp(argv[0], "wr")) { |
70 if (argc != 2) { | 82 if (argc != 2) { |
71 fputs("Incorrect number of arguments\r\n", stdout); | 83 fputs("Incorrect number of arguments\r\n", stdout); |
72 return; | 84 return; |
73 } | 85 } |
74 | 86 |
75 tmp = atoi(argv[1]); | 87 tmp = atoi(argv[1]); |
76 | 88 |
77 for (int i = 0; i < 16; i++) { | 89 for (int i = 0; i < 16; i += 2) { |
78 printf("Writing 0x%02x to 0x%06x\r\n", tmp + i, i); | 90 uint16_t data; |
79 flashwrite(tmp + i, i); | 91 data = ((i + 1) << 8) | i; |
80 } | 92 printf("Writing 0x%04x to 0x%06x\r\n", data, tmp + i); |
81 | 93 |
94 if (i == 0) | |
95 flashstartwrite(tmp, data); | |
96 else | |
97 flashwriteword(data); | |
98 } | |
99 flashstopwrite(); | |
82 } else if (!strcmp(argv[0], "id")) { | 100 } else if (!strcmp(argv[0], "id")) { |
83 printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid()); | 101 printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid()); |
84 } else { | 102 } else { |
85 fputs("Unknown sub command\r\n", stdout); | 103 fputs("Unknown sub command\r\n", stdout); |
86 return; | 104 return; |
87 } | 105 } |
88 } | 106 } |
89 | 107 |
90 void | 108 void |
91 flash4kerase(uint32_t addr) { | 109 flash4kerase(uint32_t addr) { |
110 flashenablewrite(); /* Enable writing */ | |
111 | |
112 FL_SELECT(); /* Select device */ | |
113 | |
114 SPI_WriteByte(FL_4KERASE); /* Send command */ | |
115 SPI_WriteByte(addr >> 16); /* Send address */ | |
116 SPI_WriteByte(addr >> 8); | |
117 SPI_WriteByte(addr); | |
118 | |
119 FL_DESELECT(); | |
120 | |
121 flashwait(); | |
122 } | |
123 | |
124 void | |
125 flashwait(void) { | |
92 uint8_t cnt; | 126 uint8_t cnt; |
93 | |
94 flashenablewrite(); /* Enable writing */ | |
95 | |
96 FL_SELECT(); /* Select device */ | |
97 | |
98 SPI_WriteByte(FL_4KERASE); /* Send command */ | |
99 SPI_WriteByte((addr & 0x00ff0000) >> 16); | |
100 SPI_WriteByte((addr & 0x0000ff00) >> 8); | |
101 SPI_WriteByte((addr & 0x000000ff)); /* Send address */ | |
102 | |
103 FL_DESELECT(); | |
104 | 127 |
105 /* Wait for not BUSY */ | 128 /* Wait for not BUSY */ |
106 for (cnt = 0; (flashreadstatus() & FL_BUSY) != 0; cnt++) | 129 for (cnt = 0; (flashreadstatus() & FL_BUSY) != 0; cnt++) |
107 ; | 130 ; |
108 | 131 |
171 uint8_t data; | 194 uint8_t data; |
172 | 195 |
173 FL_SELECT(); /* Select device */ | 196 FL_SELECT(); /* Select device */ |
174 | 197 |
175 SPI_WriteByte(FL_READ); /* Send command */ | 198 SPI_WriteByte(FL_READ); /* Send command */ |
176 SPI_WriteByte((addr & 0x00ff0000) >> 16); | 199 SPI_WriteByte(addr >> 16); /* Send address */ |
177 SPI_WriteByte((addr & 0x0000ff00) >> 8); | 200 SPI_WriteByte(addr >> 8); |
178 SPI_WriteByte((addr & 0x000000ff)); /* Send address */ | 201 SPI_WriteByte(addr); |
179 data = SPI_WriteByte(0x00); /* Read data */ | 202 data = SPI_WriteByte(0x00); /* Read data */ |
180 | 203 |
181 FL_DESELECT(); /* De-select device */ | 204 FL_DESELECT(); /* De-select device */ |
182 | 205 |
183 return data; | 206 return data; |
188 flashenablewrite(); /* Enable writes */ | 211 flashenablewrite(); /* Enable writes */ |
189 | 212 |
190 FL_SELECT(); /* Select device */ | 213 FL_SELECT(); /* Select device */ |
191 | 214 |
192 SPI_WriteByte(FL_BYTEPROG); /* Send command */ | 215 SPI_WriteByte(FL_BYTEPROG); /* Send command */ |
193 SPI_WriteByte((addr & 0x00ff0000) >> 16); | 216 SPI_WriteByte(addr >> 16); /* Send address */ |
194 SPI_WriteByte((addr & 0x0000ff00) >> 8); | 217 SPI_WriteByte(addr >> 8); |
195 SPI_WriteByte((addr & 0x000000ff)); /* Send address */ | 218 SPI_WriteByte(addr); |
196 SPI_WriteByte(data); /* Write data */ | 219 SPI_WriteByte(data); /* Write data */ |
197 | 220 |
198 FL_DESELECT(); /* De-select device */ | 221 FL_DESELECT(); /* De-select device */ |
199 } | 222 |
223 } | |
224 | |
225 /* | |
226 * fStream reading looks like so | |
227 * | |
228 */ | |
229 | |
230 void | |
231 flashstartread(uint32_t addr) { | |
232 assert(readstate == RW_IDLE); | |
233 | |
234 FL_SELECT(); /* Select device */ | |
235 | |
236 SPI_WriteByte(FL_READ); /* Send command */ | |
237 SPI_WriteByte(addr >> 16); /* Send address */ | |
238 SPI_WriteByte(addr >> 8); | |
239 SPI_WriteByte(addr); | |
240 | |
241 readstate = RW_RUNNING; | |
242 } | |
243 | |
244 uint8_t | |
245 flashreadbyte(void) { | |
246 assert(readstate == RW_RUNNING); | |
247 return SPI_WriteByte(0x00); /* Read data */ | |
248 } | |
249 | |
250 void | |
251 flashstopread(void) { | |
252 assert(readstate == RW_RUNNING); | |
253 | |
254 FL_DESELECT(); | |
255 | |
256 readstate = RW_IDLE; | |
257 } | |
258 | |
259 /* | |
260 * Auto increment writing looks like so | |
261 * | |
262 * Enable writing CS, WREN, nCS | |
263 * Send start address & first data word CS, AAI + addr + data, nCS | |
264 * Send subsequent words wait for nBUSY, CS, AAI + data, nCS | |
265 * ... | |
266 * Disable writing CS, WRDI, nCS | |
267 * | |
268 * XXX: EBSY command links SO to flash busy state, I don't think the | |
269 * STM32 could sample it without switching out of SPI mode. | |
270 */ | |
271 void | |
272 flashstartwrite(uint32_t addr, uint16_t data) { | |
273 assert(writestate == RW_IDLE); | |
274 | |
275 flashenablewrite(); /* Enable writes */ | |
276 | |
277 FL_SELECT(); /* Select device */ | |
278 | |
279 SPI_WriteByte(FL_AAIWP); /* Send command */ | |
280 SPI_WriteByte(addr >> 16); | |
281 SPI_WriteByte(addr >> 8); | |
282 SPI_WriteByte(addr & 0xff); /* Send address */ | |
283 | |
284 SPI_WriteByte(data & 0xff); /* Write LSB */ | |
285 SPI_WriteByte(data >> 8); /* Write MSB */ | |
286 | |
287 FL_DESELECT(); | |
288 | |
289 writestate = RW_RUNNING; | |
290 } | |
291 | |
292 void | |
293 flashwriteword(uint16_t data) { | |
294 assert(writestate == RW_RUNNING); | |
295 | |
296 flashwait(); /* Wait until not busy */ | |
297 | |
298 FL_SELECT(); /* Select device */ | |
299 | |
300 SPI_WriteByte(FL_AAIWP); /* Send command */ | |
301 SPI_WriteByte(data & 0xff); /* Write LSB */ | |
302 SPI_WriteByte(data >> 8); /* Write MSB */ | |
303 | |
304 FL_DESELECT(); /* De-select device */ | |
305 } | |
306 | |
307 void | |
308 flashstopwrite(void) { | |
309 assert(writestate == RW_RUNNING); | |
310 | |
311 flashwait(); /* Wait until not busy */ | |
312 | |
313 FL_SELECT(); /* Select device */ | |
314 | |
315 SPI_WriteByte(FL_WRDI); /* Send command */ | |
316 | |
317 FL_DESELECT(); /* Deselect device */ | |
318 | |
319 flashwait(); /* Wait until not busy */ | |
320 | |
321 writestate = RW_IDLE; | |
322 } | |
323 |