comparison flash.c @ 27:5c9d2e3d6591

Add flashread/writeblock commands which read/write a block of data to flash with a CRC.
author Daniel O'Connor <darius@dons.net.au>
date Tue, 20 Nov 2012 21:54:06 +1030
parents 74efdb21ae5d
children 03592ca4d37e
comparison
equal deleted inserted replaced
26:74efdb21ae5d 27:5c9d2e3d6591
22 "BPL" 22 "BPL"
23 }; 23 };
24 24
25 #define RW_IDLE 0 25 #define RW_IDLE 0
26 #define RW_RUNNING 1 26 #define RW_RUNNING 1
27 #define RW_IDLE 0 27
28 28 /* Holds all the settings needed */
29 typedef struct {
30 uint8_t fermenter_ROM[8];
31 uint8_t fridge_ROM[8];
32 uint8_t ambient_ROM[8];
33 int16_t target_temp;
34 uint16_t hysteresis;
35 /* How much to under/overshoot on heating/cooling */
36 int16_t minheatovershoot;
37 int16_t mincoolovershoot;
38
39 /* Minimum time the cooler can be on/off */
40 int16_t mincoolontime;
41 int16_t mincoolofftime;
42
43 /* Minimum time the heater can be on/off */
44 int16_t minheatontime;
45 int16_t minheatofftime;
46
47 #define TC_MODE_AUTO 'a' /* Automatic control */
48 #define TC_MODE_HEAT 'h' /* Force heating */
49 #define TC_MODE_COOL 'c' /* Force cooling */
50 #define TC_MODE_IDLE 'i' /* Force idle */
51 #define TC_MODE_NOTHING 'n' /* Do nothing (like idle but log nothing) */
52 char mode;
53
54 /* Bit patterns for various modes */
55 uint8_t coolbits;
56 uint8_t heatbits;
57 uint8_t idlebits;
58
59 /* Check/stale times */
60 int16_t check_interval;
61 int16_t stale_factor;
62
63 /* Beep if stale */
64 int8_t dobeep;
65
66 /* Pad to 4 bytes */
67 uint8_t pad[1];
68
69 } __attribute__((packed, aligned(4))) settings_t;
70
71 const settings_t default_settings = {
72 .fermenter_ROM = { 0x10, 0x4c, 0x7d, 0x53, 0x01, 0x08, 0x00, 0xff },
73 .fridge_ROM = { 0x10, 0x6f, 0x40, 0x53, 0x01, 0x08, 0x00, 0x16 },
74 .ambient_ROM = { 0x10, 0x76, 0x05, 0x53, 0x01, 0x08, 0x00, 0x8c },
75 .target_temp = 1000,
76 .hysteresis = 100,
77 .minheatovershoot = 50,
78 .mincoolovershoot = -50,
79 .mincoolontime = 300,
80 .mincoolofftime = 600,
81 .minheatontime = 60,
82 .minheatofftime = 60,
83 .mode = TC_MODE_AUTO,
84 .coolbits = 1 << 6,
85 .heatbits = 1<< 7,
86 .idlebits = 0x00,
87 .check_interval = 10,
88 .stale_factor = 3,
89 .dobeep = 0
90 };
91
92 /* RAM copy of setting */
93 static settings_t ram_settings;
94
29 static int writestate = RW_IDLE; 95 static int writestate = RW_IDLE;
30 static int readstate = RW_IDLE; 96 static int readstate = RW_IDLE;
31 97
32 void 98 void
33 flashcmd(char **argv, int argc) { 99 flashcmd(char **argv, int argc) {
34 uint8_t status, tmp; 100 uint8_t status, tmp, len;
35 uint32_t addr; 101 uint32_t addr;
36 102
37 if (argc == 0) { 103 if (argc == 0) {
38 fputs("No command specified\r\n", stdout); 104 fputs("No command specified\r\n", stdout);
39 return; 105 return;
64 } 130 }
65 addr = atoi(argv[1]); 131 addr = atoi(argv[1]);
66 flash4kerase(addr); 132 flash4kerase(addr);
67 printf("Erased 0x%x\r\n", (unsigned int)addr); 133 printf("Erased 0x%x\r\n", (unsigned int)addr);
68 } else if (!strcmp(argv[0], "rd")) { 134 } else if (!strcmp(argv[0], "rd")) {
69 if (argc != 2) { 135 if (argc < 2) {
70 fputs("Incorrect number of arguments\r\n", stdout); 136 fputs("Incorrect number of arguments\r\n", stdout);
71 return; 137 return;
72 } 138 }
73 139
74 addr = atoi(argv[1]); 140 addr = atoi(argv[1]);
75 141
142 if (argc > 2)
143 len = atoi(argv[2]);
144 else
145 len = 16;
146
76 flashstartread(addr); 147 flashstartread(addr);
77 148
78 for (int i = 0; i < 16; i++) 149 for (uint32_t i = 0; i < len; i++)
79 printf("Read 0x%02x from 0x%06x\r\n", flashreadbyte(), (unsigned int)(addr + i)); 150 printf("Read 0x%02x from 0x%06x\r\n", flashreadbyte(), (unsigned int)(addr + i));
80 flashstopread(); 151 flashstopread();
81 152
82 fputs("\r\n", stdout); 153 fputs("\r\n", stdout);
83 } else if (!strcmp(argv[0], "wr")) { 154 } else if (!strcmp(argv[0], "wr")) {
84 if (argc != 2) { 155 if (argc < 2) {
85 fputs("Incorrect number of arguments\r\n", stdout); 156 fputs("Incorrect number of arguments\r\n", stdout);
86 return; 157 return;
87 } 158 }
88 159
89 addr = atoi(argv[1]); 160 addr = atoi(argv[1]);
161
162 if (argc > 2)
163 len = atoi(argv[2]);
164 else
165 len = 16;
90 166
91 for (int i = 0; i < 16; i += 2) { 167 for (int i = 0; i < 16; i += 2) {
92 uint16_t data; 168 uint16_t data;
93 data = ((i + 1) << 8) | i; 169 data = ((i + 1) << 8) | i;
94 printf("Writing 0x%04x to 0x%06x\r\n", data, (unsigned int)(addr + i)); 170 printf("Writing 0x%04x to 0x%06x\r\n", data, (unsigned int)(addr + i));
97 flashstartwrite(addr, data); 173 flashstartwrite(addr, data);
98 else 174 else
99 flashwriteword(data); 175 flashwriteword(data);
100 } 176 }
101 flashstopwrite(); 177 flashstopwrite();
178 } else if (!strcmp(argv[0], "tw")) {
179 /* Copy default to RAM */
180 bcopy(&default_settings, &ram_settings, sizeof(default_settings));
181
182 /* Write RAM copy into flash */
183 flashwriteblock(0, sizeof(ram_settings), &ram_settings);
184 } else if (!strcmp(argv[0], "tr")) {
185 int crcok;
186
187 /* Read flash copy to RAM */
188 crcok = flashreadblock(0, sizeof(ram_settings), &ram_settings);
189
190 printf("CRC is %s\r\n", crcok ? "OK" : "bad");
102 } else if (!strcmp(argv[0], "id")) { 191 } else if (!strcmp(argv[0], "id")) {
103 printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid()); 192 printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid());
104 } else { 193 } else {
105 fputs("Unknown sub command\r\n", stdout); 194 fputs("Unknown sub command\r\n", stdout);
106 return; 195 return;
118 SPI_WriteByte(addr >> 8); 207 SPI_WriteByte(addr >> 8);
119 SPI_WriteByte(addr); 208 SPI_WriteByte(addr);
120 209
121 FL_DESELECT(); 210 FL_DESELECT();
122 211
212 //fputs("4k erase ", stdout);
123 flashwait(); 213 flashwait();
124 } 214 }
125 215
126 void 216 void
127 flashwait(void) { 217 flashwait(void) {
208 return data; 298 return data;
209 } 299 }
210 300
211 void 301 void
212 flashwrite(uint32_t addr, uint8_t data) { 302 flashwrite(uint32_t addr, uint8_t data) {
303 flashwait();
213 flashenablewrite(); /* Enable writes */ 304 flashenablewrite(); /* Enable writes */
214 305
215 FL_SELECT(); /* Select device */ 306 FL_SELECT(); /* Select device */
216 307
217 SPI_WriteByte(FL_BYTEPROG); /* Send command */ 308 SPI_WriteByte(FL_BYTEPROG); /* Send command */
293 384
294 void 385 void
295 flashwriteword(uint16_t data) { 386 flashwriteword(uint16_t data) {
296 assert(writestate == RW_RUNNING); 387 assert(writestate == RW_RUNNING);
297 388
389 //fputs("write word ", stdout);
298 flashwait(); /* Wait until not busy */ 390 flashwait(); /* Wait until not busy */
299 391
300 FL_SELECT(); /* Select device */ 392 FL_SELECT(); /* Select device */
301 393
302 SPI_WriteByte(FL_AAIWP); /* Send command */ 394 SPI_WriteByte(FL_AAIWP); /* Send command */
308 400
309 void 401 void
310 flashstopwrite(void) { 402 flashstopwrite(void) {
311 assert(writestate == RW_RUNNING); 403 assert(writestate == RW_RUNNING);
312 404
405 //fputs("flash stop write start ", stdout);
313 flashwait(); /* Wait until not busy */ 406 flashwait(); /* Wait until not busy */
314 407
315 FL_SELECT(); /* Select device */ 408 FL_SELECT(); /* Select device */
316 409
317 SPI_WriteByte(FL_WRDI); /* Send command */ 410 SPI_WriteByte(FL_WRDI); /* Send command */
318 411
319 FL_DESELECT(); /* Deselect device */ 412 FL_DESELECT(); /* Deselect device */
320 413
414 //fputs("flash stop write end ", stdout);
321 flashwait(); /* Wait until not busy */ 415 flashwait(); /* Wait until not busy */
322 416
323 writestate = RW_IDLE; 417 writestate = RW_IDLE;
324 } 418 }
325 419
420 int
421 flashreadblock(uint32_t addr, uint32_t len, void *_data) {
422 uint8_t *data = _data;
423 uint32_t flashcrc, ramcrc;
424
425 /* Must be a multiple of 4 due to CRC check */
426 assert(len % 4 == 0);
427
428 flashstartread(addr);
429 for (int i = len; i > 0; i--) {
430 *data = flashreadbyte();
431 data++;
432 }
433
434 flashcrc = flashreadbyte();
435 flashcrc |= flashreadbyte() << 8;
436 flashcrc |= flashreadbyte() << 16;
437 flashcrc |= flashreadbyte() << 24;
438
439 flashstopread();
440
441 /* Calculate CRC */
442 CRC_ResetDR();
443 ramcrc = CRC_CalcBlockCRC((uint32_t *)_data, len / 4);
444
445 printf("RAM CRC 0x%08x Flash CRC 0x%08x\r\n", (uint)ramcrc, (uint)flashcrc);
446
447 if (ramcrc == flashcrc)
448 return 1;
449 else
450 return 0;
451 }
452
453 void
454 flashwriteblock(uint32_t addr, uint32_t len, void *_data) {
455 uint16_t *data = _data;
456 uint32_t crc;
457
458 printf("Writing %u bytes to 0x%06x\r\n", (uint)len, (uint)addr);
459
460 /* Ensure data is
461 * - 16 bit aligned
462 * - a multiple of 32 bits in length (for CRCs, the flash only need 16 bits)
463 * - not longer than a sector
464 */
465 assert(addr % 2 == 0);
466 assert(len % 4 == 0);
467 assert(len <= 4096);
468
469 /* Disable write protect */
470 flashwritestatus(0x00);
471
472 /* Erase sector */
473 flash4kerase(addr);
474
475 /* Write data */
476 for (uint i = 0; i < len / 2; i++) {
477 if (i == 0)
478 flashstartwrite(addr, *data);
479 else
480 flashwriteword(*data);
481 data++;
482 }
483
484 /* Calculate CRC */
485 CRC_ResetDR();
486 crc = CRC_CalcBlockCRC((uint32_t *)_data, len / 4);
487
488 printf("CRC is 0x%08x\r\n", (uint)crc);
489
490 /* Write CRC */
491 flashwriteword(crc);
492 flashwriteword(crc >> 16);
493
494 flashstopwrite();
495 }