diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -85,7 +85,7 @@ CDEFS+=-DHSE_VALUE=8000000 #EMZ Optimized: -MCUFLAGS=-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections +MCUFLAGS=-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -mfloat-abi=soft # Default: MCUFLAGS=-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections diff --git a/eeprom_min.h b/eeprom_min.h --- a/eeprom_min.h +++ b/eeprom_min.h @@ -13,6 +13,8 @@ #define EEPROM_ADDR_BREWTEMP 0x0030 #define EEPROM_ADDR_STEAMTEMP 0x0034 +#define EEPROM_ADDR_UNITS 0x0038 + void Minimal_EEPROM_Unlock(void); void Minimal_EEPROM_Lock(void); diff --git a/main.c b/main.c --- a/main.c +++ b/main.c @@ -23,13 +23,21 @@ uint8_t Send_Buffer[64]; uint32_t packet_sent=1; uint32_t packet_receive=1; +enum tempunits { + TEMP_UNITS_CELSIUS = 0, + TEMP_UNITS_FAHRENHEIT, +}; + // Globalish setting vars uint8_t boottobrew = 0; +uint8_t temp_units = TEMP_UNITS_CELSIUS; uint16_t windup_guard = 1; uint16_t k_p = 1; uint16_t k_i = 1; uint16_t k_d = 1; +uint8_t ignore_tc_error = 0; + // ISR ticks var volatile uint32_t ticks = 0; @@ -43,13 +51,17 @@ enum state { STATE_SETP, STATE_SETI, STATE_SETD, + STATE_SETSTEPS, STATE_SETWINDUP, STATE_SETBOOTTOBREW, + STATE_SETUNITS, STATE_PREHEAT_BREW, STATE_MAINTAIN_BREW, STATE_PREHEAT_STEAM, STATE_MAINTAIN_STEAM, + + STATE_TC_ERROR }; uint8_t state = STATE_IDLE; @@ -130,8 +142,9 @@ int main(void) } // Read temperature and update global temp vars -int16_t temp = 0; +int32_t temp = 0; uint8_t temp_frac = 0; +uint8_t state_resume = 0; void update_temp() { // Assert CS @@ -144,15 +157,23 @@ void update_temp() { uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2); if(temp_pre & 0b0000000000000010) { - ssd1306_DrawString("Fatal Error", 2, 35); + ssd1306_DrawString("Fatal Error", 3, 35); + state = STATE_TC_ERROR; } - else if(temp_pre & 0b0000000000000001) { - ssd1306_DrawString("Error: No TC", 2, 40); + else if(temp_pre & 0b0000000000000001 && !ignore_tc_error) { + state_resume = state; + state = STATE_TC_ERROR; temp = 0; temp_frac = 0; } else { + if(state == STATE_TC_ERROR) + { + state = state_resume; + ssd1306_clearscreen(); + } + uint8_t sign = temp >> 15;// top bit is sign temp_pre = temp_pre >> 2; // Drop 2 lowest bits @@ -166,6 +187,18 @@ void update_temp() { else { temp = temp_pre; } + + if(temp_units == TEMP_UNITS_FAHRENHEIT) { + temp *= 9; // fixed point mul by 1.8 + temp /= 5; + temp += 32; + + temp_frac *= 9; + temp_frac /= 5; + temp_frac += 32; + temp += temp_frac/100; // add overflow to above + temp_frac %= 100; + } } // Deassert CS @@ -316,6 +349,7 @@ void save_settings() Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_P, k_p); Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_I, k_i); Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_D, k_d); + Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS, temp_units); Minimal_EEPROM_Lock(); } @@ -353,12 +387,28 @@ void restore_settings() while(Minimal_FLASH_GetStatus()==FLASH_BUSY); setpoint_steam = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_STEAMTEMP)); - + while(Minimal_FLASH_GetStatus()==FLASH_BUSY); + temp_units = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS)); + Minimal_EEPROM_Lock(); } int16_t last_temp = 21245; + +/////////////////////////////////////////////////////////////////////////////////////// +/// freaking multiple setpoint support /// +uint8_t step_duration[10] = {0,0,0,0,0,0,0,0,0,0}; +int16_t step_setpoint[10] = {0,0,0,0,0,0,0,0,0,0}; +uint8_t final_setpoint = 0; + +// Multiple screens to set setpoint and duration on each screen +// press center to go to the next one, and press left or right or something to confirm + +// When executing, complete on time AND(?) temperature. Maybe allow switching to OR via settings + +//////////////////////////////////////////////////////////////////////////////////////////////// + void machine() { uint8_t last_state = state; @@ -395,7 +445,7 @@ void machine() switch(goto_mode) { case 2: { - ssd1306_DrawString("-> brew ", 1, 40); + ssd1306_DrawString("-> heat ", 1, 40); } break; case 1: @@ -525,6 +575,45 @@ void machine() } break; + case STATE_SETSTEPS: + { + // Write text to OLED + // [ step #1:: Duration: ### ] + // [ Setpoint: ### ] + char tempstr[6]; + + itoa(final_setpoint, tempstr); + ssd1306_DrawString("Step #", 0, 0); + ssd1306_DrawString(tempstr, 0, 40); + + ssd1306_DrawString("Duration: ", 0, 5); + itoa(step_duration[final_setpoint], tempstr); + ssd1306_DrawString(tempstr, 0, 70); + + ssd1306_DrawString("Setpoint: ", 0, 0); + itoa(step_setpoint[final_setpoint], tempstr); + ssd1306_DrawString(tempstr, 0, 70); + + ssd1306_DrawString("Press to accept", 3, 40); + + // Button handler - TODO: increment max_step if pressed + // return and go to next state otherwise + if(SW_BTN_PRESSED) { + state = STATE_SETSTEPS; + final_setpoint++; + } + // else if(SW_LEFT_PRESSED) { + // state++; // go to next state or something + // } + else { + user_input(&k_p); + } + + // Event Handler + // N/A + + } break; + case STATE_SETWINDUP: { // Write text to OLED @@ -559,10 +648,10 @@ void machine() // Write text to OLED // [ therm :: set windup ] // [ g = 12 ] - ssd1306_DrawString("Boot to Brew", 0, 40); + ssd1306_DrawString("Start on Boot", 0, 40); ssd1306_drawlogo(); - ssd1306_DrawString("btb=", 1, 45); + ssd1306_DrawString("sob=", 1, 45); if(boottobrew) ssd1306_DrawString("Enabled ", 1, 70); @@ -573,8 +662,7 @@ void machine() // Button handler if(SW_BTN_PRESSED) { - save_settings(); - state = STATE_IDLE; + state = STATE_SETUNITS; } else if(!GPIO_ReadInputDataBit(SW_UP)) { boottobrew = 1; @@ -588,6 +676,39 @@ void machine() } break; + case STATE_SETUNITS: + { + // Write text to OLED + // [ therm :: set windup ] + // [ g = 12 ] + ssd1306_DrawString("Units: ", 0, 40); + ssd1306_drawlogo(); + + if(temp_units == TEMP_UNITS_FAHRENHEIT) + ssd1306_DrawString("Fahrenheit", 1, 60); + else + ssd1306_DrawString("Celsius ", 1, 60); + + ssd1306_DrawString("Press to accept", 3, 40); + + // Button handler + if(SW_BTN_PRESSED) { + save_settings(); + state = STATE_IDLE; + } + else if(!GPIO_ReadInputDataBit(SW_UP)) { + temp_units = TEMP_UNITS_FAHRENHEIT; + } + else if(!GPIO_ReadInputDataBit(SW_DOWN)) { + temp_units = TEMP_UNITS_CELSIUS; + } + + // Event Handler + // N/A + + } break; + + case STATE_PREHEAT_BREW: { // Write text to OLED @@ -692,6 +813,29 @@ void machine() } break; + case STATE_TC_ERROR: + { + // Write text to OLED + // [ therm : ready to steam ] + // [ 30 => 120 C ] + ssd1306_DrawString("Error:", 0, 0); + ssd1306_DrawString("Connect thermocouple", 1, 0); + ssd1306_DrawString("Press -> to ignore", 3, 0); + + // Button handler + if(SW_BTN_PRESSED) { + state = STATE_IDLE; + } + else if(SW_RIGHT_PRESSED) { + ignore_tc_error = 1; + state = STATE_IDLE; + } + // Event Handler + // Maybe handle if TC is plugged in + // N/A + + } break; + // Something is terribly wrong default: {