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