Mercurial > ~darius > hgwebdir.cgi > stm32temp
comparison tempctrl.c @ 66:0916bfe3f418
Rename settings to tc_settings as it's global.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sun, 14 Apr 2013 14:28:14 +0930 |
parents | 9c5db7fee912 |
children | aaf0603d7f88 |
comparison
equal
deleted
inserted
replaced
65:662e7f01c991 | 66:0916bfe3f418 |
---|---|
39 #include "1wire.h" | 39 #include "1wire.h" |
40 #include "ff.h" | 40 #include "ff.h" |
41 #include "flash.h" | 41 #include "flash.h" |
42 #include "tempctrl.h" | 42 #include "tempctrl.h" |
43 | 43 |
44 #define TEMPCTRL_FLASH_ADDRESS 0 /* First sector */ | |
45 | |
44 /* Holds all the settings needed */ | 46 /* Holds all the settings needed */ |
45 typedef struct { | 47 typedef struct { |
46 uint8_t fermenter_ROM[8]; | 48 uint8_t fermenter_ROM[8]; |
47 uint8_t fridge_ROM[8]; | 49 uint8_t fridge_ROM[8]; |
48 uint8_t ambient_ROM[8]; | 50 uint8_t ambient_ROM[8]; |
81 int16_t stale_factor; | 83 int16_t stale_factor; |
82 | 84 |
83 char logfilefmt[64]; | 85 char logfilefmt[64]; |
84 | 86 |
85 uint8_t pad[1]; /* Pad to multiple of 4 bytes */ | 87 uint8_t pad[1]; /* Pad to multiple of 4 bytes */ |
86 } settings_t; | 88 } tc_settings_t; |
87 | 89 |
88 /* Current settings in RAM */ | 90 /* Current settings in RAM */ |
89 static settings_t settings; | 91 static tc_settings_t tc_settings; |
90 | 92 |
91 /* Defaults that are shoved into SPI flash if it isn't inited */ | 93 /* Defaults that are shoved into SPI flash if it isn't inited */ |
92 const settings_t default_settings = { | 94 const tc_settings_t default_tc_settings = { |
93 .fermenter_ROM = { 0x10, 0x4c, 0x7d, 0x53, 0x01, 0x08, 0x00, 0xff }, | 95 .fermenter_ROM = { 0x10, 0x4c, 0x7d, 0x53, 0x01, 0x08, 0x00, 0xff }, |
94 .fridge_ROM = { 0x10, 0x6d, 0x40, 0x53, 0x01, 0x08, 0x00, 0x16 }, | 96 .fridge_ROM = { 0x10, 0x6d, 0x40, 0x53, 0x01, 0x08, 0x00, 0x16 }, |
95 .ambient_ROM = { 0x10, 0x76, 0x05, 0x53, 0x01, 0x08, 0x00, 0x8e }, | 97 .ambient_ROM = { 0x10, 0x76, 0x05, 0x53, 0x01, 0x08, 0x00, 0x8e }, |
96 .target_temp = 1000, | 98 .target_temp = 1000, |
97 .hysteresis = 100, | 99 .hysteresis = 100, |
177 | 179 |
178 /* Time to check temperatures? */ | 180 /* Time to check temperatures? */ |
179 if (t < checktime) | 181 if (t < checktime) |
180 return; | 182 return; |
181 | 183 |
182 checktime = t + settings.check_interval; | 184 checktime = t + tc_settings.check_interval; |
183 | 185 |
184 /* Don't do any logging, just force idle and leave */ | 186 /* Don't do any logging, just force idle and leave */ |
185 if (settings.mode == TC_MODE_NOTHING) { | 187 if (tc_settings.mode == TC_MODE_NOTHING) { |
186 nextstate = 'i'; | 188 nextstate = 'i'; |
187 goto skip; | 189 goto skip; |
188 } | 190 } |
189 | 191 |
190 /* Update our temperatures | 192 /* Update our temperatures |
191 * Can take a while (800ms each!) | 193 * Can take a while (800ms each!) |
192 */ | 194 */ |
193 tempt = OWGetTemp(settings.fermenter_ROM); | 195 tempt = OWGetTemp(tc_settings.fermenter_ROM); |
194 fridge_temp = OWGetTemp(settings.fridge_ROM); | 196 fridge_temp = OWGetTemp(tc_settings.fridge_ROM); |
195 ambient_temp = OWGetTemp(settings.ambient_ROM); | 197 ambient_temp = OWGetTemp(tc_settings.ambient_ROM); |
196 | 198 |
197 /* We only care about this one, only update the value we decide on | 199 /* We only care about this one, only update the value we decide on |
198 * only if it is valid | 200 * only if it is valid |
199 */ | 201 */ |
200 if (tempt > OW_TEMP_BADVAL) { | 202 if (tempt > OW_TEMP_BADVAL) { |
201 fermenter_temp = tempt; | 203 fermenter_temp = tempt; |
202 lastdata = t; | 204 lastdata = t; |
203 } | 205 } |
204 | 206 |
205 /* Check for stale data */ | 207 /* Check for stale data */ |
206 if (lastdata + (settings.check_interval * settings.stale_factor) < t) | 208 if (lastdata + (tc_settings.check_interval * tc_settings.stale_factor) < t) |
207 stale = 1; | 209 stale = 1; |
208 | 210 |
209 /* Default to remaining as we are */ | 211 /* Default to remaining as we are */ |
210 nextstate = '-'; | 212 nextstate = '-'; |
211 | 213 |
212 /* Temperature diff, -ve => too cold, +ve => too warm */ | 214 /* Temperature diff, -ve => too cold, +ve => too warm */ |
213 diff = fermenter_temp - settings.target_temp; | 215 diff = fermenter_temp - tc_settings.target_temp; |
214 | 216 |
215 switch (currstate) { | 217 switch (currstate) { |
216 case 'i': | 218 case 'i': |
217 /* If we're idle then only heat or cool if the temperate difference is out of the | 219 /* If we're idle then only heat or cool if the temperate difference is out of the |
218 * hysteresis band and the heater/cooler have been off long enough | 220 * hysteresis band and the heater/cooler have been off long enough |
219 */ | 221 */ |
220 if (abs(diff) > settings.hysteresis) { | 222 if (abs(diff) > tc_settings.hysteresis) { |
221 if (diff < 0 && settings.minheatofftime + lastheatoff < t) | 223 if (diff < 0 && tc_settings.minheatofftime + lastheatoff < t) |
222 nextstate = 'h'; | 224 nextstate = 'h'; |
223 else if (diff > 0 && settings.mincoolofftime + lastcooloff < t) | 225 else if (diff > 0 && tc_settings.mincoolofftime + lastcooloff < t) |
224 nextstate = 'c'; | 226 nextstate = 'c'; |
225 } | 227 } |
226 break; | 228 break; |
227 | 229 |
228 case 'c': | 230 case 'c': |
229 /* Work out if we should go idle (based on min on time & overshoot) */ | 231 /* Work out if we should go idle (based on min on time & overshoot) */ |
230 if (diff + settings.mincoolovershoot < 0 && | 232 if (diff + tc_settings.mincoolovershoot < 0 && |
231 settings.mincoolontime + lastcoolon < t) | 233 tc_settings.mincoolontime + lastcoolon < t) |
232 nextstate = 'i'; | 234 nextstate = 'i'; |
233 break; | 235 break; |
234 | 236 |
235 case 'h': | 237 case 'h': |
236 if (diff - settings.minheatovershoot > 0 && | 238 if (diff - tc_settings.minheatovershoot > 0 && |
237 settings.minheatontime + lastheaton < t) | 239 tc_settings.minheatontime + lastheaton < t) |
238 nextstate = 'i'; | 240 nextstate = 'i'; |
239 break; | 241 break; |
240 | 242 |
241 default: | 243 default: |
242 printf("\nUnknown state %c, going to idle\n", currstate); | 244 printf("\nUnknown state %c, going to idle\n", currstate); |
247 /* Override if we have stale data */ | 249 /* Override if we have stale data */ |
248 if (stale) | 250 if (stale) |
249 nextstate = 'i'; | 251 nextstate = 'i'; |
250 | 252 |
251 /* Handle state forcing */ | 253 /* Handle state forcing */ |
252 if (settings.mode != TC_MODE_AUTO) | 254 if (tc_settings.mode != TC_MODE_AUTO) |
253 forced = 1; | 255 forced = 1; |
254 else | 256 else |
255 forced = 0; | 257 forced = 0; |
256 | 258 |
257 if (settings.mode == TC_MODE_IDLE) | 259 if (tc_settings.mode == TC_MODE_IDLE) |
258 nextstate = 'i'; | 260 nextstate = 'i'; |
259 else if (settings.mode == TC_MODE_HEAT) | 261 else if (tc_settings.mode == TC_MODE_HEAT) |
260 nextstate = 'h'; | 262 nextstate = 'h'; |
261 else if (settings.mode == TC_MODE_COOL) | 263 else if (tc_settings.mode == TC_MODE_COOL) |
262 nextstate = 'c'; | 264 nextstate = 'c'; |
263 | 265 |
264 /* Keep track of when we last turned things on or off */ | 266 /* Keep track of when we last turned things on or off */ |
265 skip: | 267 skip: |
266 switch (nextstate) { | 268 switch (nextstate) { |
285 | 287 |
286 if (nextstate != '-') | 288 if (nextstate != '-') |
287 currstate = nextstate; | 289 currstate = nextstate; |
288 | 290 |
289 | 291 |
290 if (settings.mode != TC_MODE_NOTHING) { | 292 if (tc_settings.mode != TC_MODE_NOTHING) { |
291 localtime_r(&t, &tm); | 293 localtime_r(&t, &tm); |
292 p = linebuf; | 294 p = linebuf; |
293 p += strftime(p, sizeof(linebuf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm); | 295 p += strftime(p, sizeof(linebuf) - 1, "%Y/%m/%d %H:%M:%S: ", &tm); |
294 p += fmttemp(p, "Tr", settings.target_temp, ", "); | 296 p += fmttemp(p, "Tr", tc_settings.target_temp, ", "); |
295 p += fmttemp(p, "Fm", tempt, ", "); | 297 p += fmttemp(p, "Fm", tempt, ", "); |
296 p += fmttemp(p, "Fr", fridge_temp, ", "); | 298 p += fmttemp(p, "Fr", fridge_temp, ", "); |
297 p += fmttemp(p, "Am", ambient_temp, ", "); | 299 p += fmttemp(p, "Am", ambient_temp, ", "); |
298 sprintf(p, "St: %s, Fl: %s%s\n", state2long(currstate), | 300 sprintf(p, "St: %s, Fl: %s%s\n", state2long(currstate), |
299 forced ? "F" : "", | 301 forced ? "F" : "", |
300 stale ? "S" : ""); | 302 stale ? "S" : ""); |
301 fputs(linebuf, stdout); | 303 fputs(linebuf, stdout); |
302 if (settings.logfilefmt[0] != '\0') { | 304 if (tc_settings.logfilefmt[0] != '\0') { |
303 strftime(fbuf, sizeof(fbuf) - 1, settings.logfilefmt, &tm); | 305 strftime(fbuf, sizeof(fbuf) - 1, tc_settings.logfilefmt, &tm); |
304 | 306 |
305 if ((fserr = f_open(&f, fbuf, FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) { | 307 if ((fserr = f_open(&f, fbuf, FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) { |
306 printf("Failed to open file: %d\n", fserr); | 308 printf("Failed to open file: %d\n", fserr); |
307 goto openerr; | 309 goto openerr; |
308 } | 310 } |
335 /* Read the settings from SPI flash | 337 /* Read the settings from SPI flash |
336 * If the CRC fails then reload from onboard flash | 338 * If the CRC fails then reload from onboard flash |
337 */ | 339 */ |
338 static void | 340 static void |
339 tempctrl_load_or_init_settings(void) { | 341 tempctrl_load_or_init_settings(void) { |
340 /* XXX: todo */ | 342 if (!flashreadblock(TEMPCTRL_FLASH_ADDRESS, sizeof(tc_settings), &tc_settings)) { |
341 if (!flashreadblock(0, sizeof(settings), &settings)) { | |
342 fputs("CRC fails, loading defaults\n", stdout); | 343 fputs("CRC fails, loading defaults\n", stdout); |
343 tempctrl_default_settings(); | 344 tempctrl_default_settings(); |
344 tempctrl_write_settings(); | 345 tempctrl_write_settings(); |
345 } | 346 } |
346 } | 347 } |
347 | 348 |
348 /* Load in the defaults from flash */ | 349 /* Load in the defaults from flash */ |
349 static void | 350 static void |
350 tempctrl_default_settings(void) { | 351 tempctrl_default_settings(void) { |
351 memcpy(&settings, &default_settings, sizeof(settings_t)); | 352 memcpy(&tc_settings, &default_tc_settings, sizeof(tc_settings_t)); |
352 } | 353 } |
353 | 354 |
354 /* Write the current settings out to SPI flash */ | 355 /* Write the current settings out to SPI flash */ |
355 static void | 356 static void |
356 tempctrl_write_settings(void) { | 357 tempctrl_write_settings(void) { |
357 flashwriteblock(0, sizeof(settings), &settings); | 358 flashwriteblock(TEMPCTRL_FLASH_ADDRESS, sizeof(tc_settings), &tc_settings); |
358 } | 359 } |
359 | 360 |
360 /* Set the relays to match the desired state */ | 361 /* Set the relays to match the desired state */ |
361 static void | 362 static void |
362 setstate(char state) { | 363 setstate(char state) { |
381 cool = 0; | 382 cool = 0; |
382 heat = 0; | 383 heat = 0; |
383 break; | 384 break; |
384 } | 385 } |
385 | 386 |
386 if (cool ^ settings.coolinv) | 387 if (cool ^ tc_settings.coolinv) |
387 GPIO_SetBits(char2port(settings.coolport), 1 << settings.coolpin); | 388 GPIO_SetBits(char2port(tc_settings.coolport), 1 << tc_settings.coolpin); |
388 else | 389 else |
389 GPIO_ResetBits(char2port(settings.coolport), 1 << settings.coolpin); | 390 GPIO_ResetBits(char2port(tc_settings.coolport), 1 << tc_settings.coolpin); |
390 | 391 |
391 if (heat ^ settings.heatinv) | 392 if (heat ^ tc_settings.heatinv) |
392 GPIO_SetBits(char2port(settings.heatport), 1 << settings.heatpin); | 393 GPIO_SetBits(char2port(tc_settings.heatport), 1 << tc_settings.heatpin); |
393 else | 394 else |
394 GPIO_ResetBits(char2port(settings.heatport), 1 << settings.heatpin); | 395 GPIO_ResetBits(char2port(tc_settings.heatport), 1 << tc_settings.heatpin); |
395 } | 396 } |
396 | 397 |
397 /* Handle user command | 398 /* Handle user command |
398 * | 399 * |
399 */ | 400 */ |
458 "Min heat overshoot - %d, Min cool overshoot - %d\n" | 459 "Min heat overshoot - %d, Min cool overshoot - %d\n" |
459 "Min cool on time - %d, Min cool off time - %d\n" | 460 "Min cool on time - %d, Min cool off time - %d\n" |
460 "Min heat on time - %d, Min heat off time - %d\n" | 461 "Min heat on time - %d, Min heat off time - %d\n" |
461 "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\n" | 462 "Cool: Port %c Pin %d Inv %d, Heat: Port %c Pin %d Inv %d\n" |
462 "Log format: %s\n", | 463 "Log format: %s\n", |
463 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], | 464 tc_settings.fermenter_ROM[0], tc_settings.fermenter_ROM[1], tc_settings.fermenter_ROM[2], tc_settings.fermenter_ROM[3], |
464 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], | 465 tc_settings.fermenter_ROM[4], tc_settings.fermenter_ROM[5], tc_settings.fermenter_ROM[6], tc_settings.fermenter_ROM[7], |
465 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], | 466 tc_settings.fridge_ROM[0], tc_settings.fridge_ROM[1], tc_settings.fridge_ROM[2], tc_settings.fridge_ROM[3], |
466 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], | 467 tc_settings.fridge_ROM[4], tc_settings.fridge_ROM[5], tc_settings.fridge_ROM[6], tc_settings.fridge_ROM[7], |
467 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], | 468 tc_settings.ambient_ROM[0], tc_settings.ambient_ROM[1], tc_settings.ambient_ROM[2], tc_settings.ambient_ROM[3], |
468 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], | 469 tc_settings.ambient_ROM[4], tc_settings.ambient_ROM[5], tc_settings.ambient_ROM[6], tc_settings.ambient_ROM[7], |
469 settings.mode, settings.target_temp, settings.hysteresis, | 470 tc_settings.mode, tc_settings.target_temp, tc_settings.hysteresis, |
470 settings.minheatovershoot, settings.mincoolovershoot, | 471 tc_settings.minheatovershoot, tc_settings.mincoolovershoot, |
471 settings.mincoolontime, settings.minheatontime, | 472 tc_settings.mincoolontime, tc_settings.minheatontime, |
472 settings.minheatontime, settings.minheatofftime, | 473 tc_settings.minheatontime, tc_settings.minheatofftime, |
473 settings.coolport, settings.coolpin, settings.coolinv, | 474 tc_settings.coolport, tc_settings.coolpin, tc_settings.coolinv, |
474 settings.heatport, settings.heatpin, settings.heatinv, | 475 tc_settings.heatport, tc_settings.heatpin, tc_settings.heatinv, |
475 settings.logfilefmt[0] == '\0' ? "none" : settings.logfilefmt | 476 tc_settings.logfilefmt[0] == '\0' ? "none" : tc_settings.logfilefmt |
476 ); | 477 ); |
477 return; | 478 return; |
478 } | 479 } |
479 if (!strcasecmp(argv[0], "mode")) { | 480 if (!strcasecmp(argv[0], "mode")) { |
480 if (argc < 2) { | 481 if (argc < 2) { |
486 case TC_MODE_AUTO: | 487 case TC_MODE_AUTO: |
487 case TC_MODE_HEAT: | 488 case TC_MODE_HEAT: |
488 case TC_MODE_COOL: | 489 case TC_MODE_COOL: |
489 case TC_MODE_IDLE: | 490 case TC_MODE_IDLE: |
490 case TC_MODE_NOTHING: | 491 case TC_MODE_NOTHING: |
491 settings.mode = argv[1][0]; | 492 tc_settings.mode = argv[1][0]; |
492 break; | 493 break; |
493 | 494 |
494 default: | 495 default: |
495 printf("Unknown mode character '%c'\n", argv[1][0]); | 496 printf("Unknown mode character '%c'\n", argv[1][0]); |
496 break; | 497 break; |
509 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | 510 &ROM[0], &ROM[1], &ROM[2], &ROM[3], |
510 &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { | 511 &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { |
511 printf("Unable to parse ROM ID\n"); | 512 printf("Unable to parse ROM ID\n"); |
512 } else { | 513 } else { |
513 if (!strcasecmp(argv[0], "ferm")) | 514 if (!strcasecmp(argv[0], "ferm")) |
514 memcpy(&settings.fermenter_ROM, ROM, sizeof(ROM)); | 515 memcpy(&tc_settings.fermenter_ROM, ROM, sizeof(ROM)); |
515 if (!strcasecmp(argv[0], "frg")) | 516 if (!strcasecmp(argv[0], "frg")) |
516 memcpy(&settings.fridge_ROM, ROM, sizeof(ROM)); | 517 memcpy(&tc_settings.fridge_ROM, ROM, sizeof(ROM)); |
517 if (!strcasecmp(argv[0], "amb")) | 518 if (!strcasecmp(argv[0], "amb")) |
518 memcpy(&settings.ambient_ROM, ROM, sizeof(ROM)); | 519 memcpy(&tc_settings.ambient_ROM, ROM, sizeof(ROM)); |
519 } | 520 } |
520 return; | 521 return; |
521 } | 522 } |
522 if (!strcasecmp(argv[0], "log")) { | 523 if (!strcasecmp(argv[0], "log")) { |
523 if (argc == 1) | 524 if (argc == 1) |
524 bzero(settings.logfilefmt, sizeof(settings.logfilefmt)); | 525 bzero(tc_settings.logfilefmt, sizeof(tc_settings.logfilefmt)); |
525 else { | 526 else { |
526 if (strlen(argv[1]) > sizeof(settings.logfilefmt) - 1) | 527 if (strlen(argv[1]) > sizeof(tc_settings.logfilefmt) - 1) |
527 printf("New path too log (%d > %d)\n", strlen(argv[1]), sizeof(settings.logfilefmt)); | 528 printf("New path too log (%d > %d)\n", strlen(argv[1]), sizeof(tc_settings.logfilefmt)); |
528 else | 529 else |
529 strcpy(settings.logfilefmt, argv[1]); | 530 strcpy(tc_settings.logfilefmt, argv[1]); |
530 } | 531 } |
531 return; | 532 return; |
532 } | 533 } |
533 | 534 |
534 /* Handle setting the multitude of variables | 535 /* Handle setting the multitude of variables |
542 printf("Unable to parse value for variable\n"); | 543 printf("Unable to parse value for variable\n"); |
543 return; | 544 return; |
544 } | 545 } |
545 | 546 |
546 if (!strcasecmp(argv[1], "targ")) { | 547 if (!strcasecmp(argv[1], "targ")) { |
547 settings.target_temp = data; | 548 tc_settings.target_temp = data; |
548 } else if (!strcasecmp(argv[1], "hys")) { | 549 } else if (!strcasecmp(argv[1], "hys")) { |
549 settings.hysteresis = data; | 550 tc_settings.hysteresis = data; |
550 } else if (!strcasecmp(argv[1], "mhov")) { | 551 } else if (!strcasecmp(argv[1], "mhov")) { |
551 settings.minheatovershoot = data; | 552 tc_settings.minheatovershoot = data; |
552 } else if (!strcasecmp(argv[1], "mcov")) { | 553 } else if (!strcasecmp(argv[1], "mcov")) { |
553 settings.mincoolovershoot = data; | 554 tc_settings.mincoolovershoot = data; |
554 } else if (!strcasecmp(argv[1], "mcon")) { | 555 } else if (!strcasecmp(argv[1], "mcon")) { |
555 settings.mincoolontime = data; | 556 tc_settings.mincoolontime = data; |
556 } else if (!strcasecmp(argv[1], "mcoff")) { | 557 } else if (!strcasecmp(argv[1], "mcoff")) { |
557 settings.mincoolofftime = data; | 558 tc_settings.mincoolofftime = data; |
558 } else if (!strcasecmp(argv[1], "mhon")) { | 559 } else if (!strcasecmp(argv[1], "mhon")) { |
559 settings.minheatontime = data; | 560 tc_settings.minheatontime = data; |
560 } else if (!strcasecmp(argv[1], "mhoff")) { | 561 } else if (!strcasecmp(argv[1], "mhoff")) { |
561 settings.minheatofftime = data; | 562 tc_settings.minheatofftime = data; |
562 } else { | 563 } else { |
563 printf("Unknown setting\n"); | 564 printf("Unknown setting\n"); |
564 } | 565 } |
565 } | 566 } |
566 | 567 |