/* * display.c * * Created on: May 31, 2017 * Author: wn */ #include #include "stm32f1xx_hal.h" #include "alarm.h" #include #include "oled.h" #include "eeprom.h" #include "thermometer.h" const uint32_t STORAGE_MAGIC = 0xaffe000a; const uint8_t COLD_COUNT_THRESHOLD = 40; volatile tDisplay display = { .toggle = 0, .setModeTemperature = 0, .setModeTime = 0, .timerState = IDLE, .thermometerEngineState = TE_IDLE, .toggleModeState = 1, .targetTemperature = 80, .currentTemperature = 75, .targetTime = 120, .currentTime = 0, .overrunTime = 0 }; typedef struct { uint32_t magic; uint32_t savedTemperature; uint32_t savedTime; } tStorage; tStorage storage; void updateDisplay(void *handle) { tDisplay *lDisplay = (tDisplay*) handle; lDisplay->toggle ^= 0x01; char buf[32]; sprintf(buf, "ThermometerTeaTimer"); LED_P6x8Str(0, 0, buf); if (lDisplay->setModeTemperature && lDisplay->toggle) { sprintf(buf, " %3d'C", lDisplay->currentTemperature); } else { sprintf(buf, "%3d'C %3d'C", lDisplay->targetTemperature, lDisplay->currentTemperature); } LED_P8x16Str(0, 2, buf); if (lDisplay->setModeTime && lDisplay->toggle) { sprintf(buf, " %3ds", lDisplay->currentTime); } else { sprintf(buf, "%3ds %3ds", lDisplay->targetTime, lDisplay->currentTime); } LED_P8x16Str(0, 4, buf); sprintf(buf, " %5ds", lDisplay->overrunTime); // static uint32_t h = 0; // static uint32_t c = 0; // uint32_t i = HAL_GetTick(); // sprintf(buf, "%d %d %d", c, i, i-h); // h = i; // c++; LED_P8x16Str(0, 6, buf); } void thermometerEngine(void *handle) { tDisplay *lDisplay = (tDisplay*) handle; lDisplay->currentTemperature = thermometerGetValue(); switch (lDisplay->thermometerEngineState) { case TE_IDLE: if (lDisplay->currentTemperature > lDisplay->targetTemperature) { lDisplay->thermometerEngineState = TE_HOT; lDisplay->coldCount = 0; } break; case TE_HOT: if (lDisplay->currentTemperature <= lDisplay->targetTemperature) { lDisplay->coldCount += 1; } if (lDisplay->coldCount >= COLD_COUNT_THRESHOLD) { lDisplay->thermometerEngineState = TE_COLD; } break; case TE_COLD: enableAlarm(TEMPERATURE_ALARM); lDisplay->thermometerEngineState = TE_UNCONFIRMED; break; case TE_UNCONFIRMED: break; case TE_CONFIRMED: disableAlarm(); lDisplay->thermometerEngineState = TE_IDLE; break; default: lDisplay->thermometerEngineState = TE_IDLE; } } void thermometerEngineConfirmAlarm() { if (display.thermometerEngineState == TE_UNCONFIRMED) { display.thermometerEngineState = TE_CONFIRMED; } } void hmiInit() { eepromRead(STORAGE_ADDRESS, &storage, sizeof(storage)); if (storage.magic == STORAGE_MAGIC) { display.targetTemperature = storage.savedTemperature; display.targetTime = storage.savedTime; } else { storage.magic = STORAGE_MAGIC; storage.savedTemperature = 80; storage.savedTime = 90; eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage)); // eepromRead(STORAGE_ADDRESS, &storage, sizeof(storage)); display.targetTemperature = storage.savedTemperature; display.targetTime = storage.savedTime; } schAdd(thermometerEngine, &display, 0, 250); schAdd(updateDisplay, &display, 10, 250); } void clearSetMode(void *handle) { tDisplay *lDisplay = (tDisplay*) handle; lDisplay->setModeTemperature = 0; lDisplay->setModeTime = 0; lDisplay->toggleModeState = 1; } static void disableSetModeTimer() { schDel(clearSetMode, (void*)&display); } static void reEnableSetModeTimer() { schDel(clearSetMode, (void*)&display); schAdd(clearSetMode, (void*)&display, 10000, 0); } static void toggleSetMode() { switch (display.toggleModeState) { default: case 0: disableSetModeTimer(); display.setModeTemperature = 0; display.setModeTime = 0; display.toggleModeState = 1; break; case 1: reEnableSetModeTimer(); display.setModeTemperature = 1; display.setModeTime = 0; display.toggleModeState = 2; break; case 2: reEnableSetModeTimer(); display.setModeTemperature = 0; display.setModeTime = 1; display.toggleModeState = 0; break; } } void displayIncValue() { if (display.setModeTemperature == 1) { reEnableSetModeTimer(); if (display.targetTemperature < 100) { display.targetTemperature++; storage.savedTemperature = display.targetTemperature; eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage)); } } if (display.setModeTime == 1) { reEnableSetModeTimer(); if (display.targetTime < 999) { display.targetTime += 10; storage.savedTime = display.targetTime; eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage)); } } } void displayDecValue() { if (display.setModeTemperature == 1) { reEnableSetModeTimer(); if (display.targetTemperature > 0) { display.targetTemperature--; storage.savedTemperature = display.targetTemperature; eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage)); } } if (display.setModeTime == 1) { reEnableSetModeTimer(); if (display.targetTime >= 10) { display.targetTime -= 10; storage.savedTime = display.targetTime; eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage)); } } } void buttonShort() { if (display.setModeTemperature == 1 || display.setModeTime == 1) { toggleSetMode(); } else if (display.timerState == IDLE) { startTimer(); thermometerEngineConfirmAlarm(); } else if (display.timerState == RUNNING || display.timerState == OVERRUN) { stopTimer(); disableAlarm(); } } void buttonLong() { if (display.timerState == IDLE) { toggleSetMode(); } }