diff --git a/display.c b/display.c --- a/display.c +++ b/display.c @@ -103,7 +103,7 @@ void display_process(therm_settings_t* s break; case 0: status->state = STATE_IDLE; - flash_erase(set); + //flash_erase(); NVIC_SystemReset(); break; @@ -133,7 +133,7 @@ void display_process(therm_settings_t* s ssd1306_drawlogo(); char tempstr[6]; - itoa(set->k_p, tempstr, 10); + itoa(set->val.k_p, tempstr, 10); ssd1306_DrawString("P=", 1, 45); ssd1306_DrawString(" ", 1, 57); ssd1306_DrawString(tempstr, 1, 57); @@ -145,7 +145,7 @@ void display_process(therm_settings_t* s status->state = STATE_SETI; } else { - user_input(&set->k_p); + user_input(&set->val.k_p); } // Event Handler @@ -162,7 +162,7 @@ void display_process(therm_settings_t* s ssd1306_drawlogo(); char tempstr[6]; - itoa(set->k_i, tempstr, 10); + itoa(set->val.k_i, tempstr, 10); ssd1306_DrawString("I=", 1, 45); ssd1306_DrawString(" ", 1, 57); ssd1306_DrawString(tempstr, 1, 57); @@ -174,7 +174,7 @@ void display_process(therm_settings_t* s status->state = STATE_SETD; } else { - user_input(&set->k_i); + user_input(&set->val.k_i); } // Event Handler @@ -191,7 +191,7 @@ void display_process(therm_settings_t* s ssd1306_drawlogo(); char tempstr[6]; - itoa(set->k_d, tempstr, 10); + itoa(set->val.k_d, tempstr, 10); ssd1306_DrawString("D=", 1, 45); ssd1306_DrawString(" ", 1, 57); ssd1306_DrawString(tempstr, 1, 57); @@ -203,7 +203,7 @@ void display_process(therm_settings_t* s status->state = STATE_SETWINDUP; } else { - user_input(&set->k_d); + user_input(&set->val.k_d); } // Event Handler @@ -220,7 +220,7 @@ void display_process(therm_settings_t* s ssd1306_drawlogo(); char tempstr[6]; - itoa(set->windup_guard, tempstr, 10); + itoa(set->val.windup_guard, tempstr, 10); ssd1306_DrawString("G=", 1, 45); ssd1306_DrawString(" ", 1, 57); ssd1306_DrawString(tempstr, 1, 57); @@ -232,7 +232,7 @@ void display_process(therm_settings_t* s status->state = STATE_SETBOOTTOBREW; } else { - user_input(&set->windup_guard); + user_input(&set->val.windup_guard); } // Event Handler @@ -250,7 +250,7 @@ void display_process(therm_settings_t* s ssd1306_DrawString("sob=", 1, 45); - if(set->boottobrew) + if(set->val.boottobrew) ssd1306_DrawString("Enabled ", 1, 70); else ssd1306_DrawString("Disabled", 1, 70); @@ -262,10 +262,10 @@ void display_process(therm_settings_t* s status->state = STATE_SETUNITS; } else if(!HAL_GPIO_ReadPin(SW_UP)) { - set->boottobrew = 1; + set->val.boottobrew = 1; } else if(!HAL_GPIO_ReadPin(SW_DOWN)) { - set->boottobrew = 0; + set->val.boottobrew = 0; } // Event Handler @@ -281,7 +281,7 @@ void display_process(therm_settings_t* s ssd1306_DrawString("Units: ", 0, 40); ssd1306_drawlogo(); - if(set->temp_units == TEMP_UNITS_FAHRENHEIT) + if(set->val.temp_units == TEMP_UNITS_FAHRENHEIT) ssd1306_DrawString("Fahrenheit", 1, 60); else ssd1306_DrawString("Celsius ", 1, 60); @@ -293,10 +293,10 @@ void display_process(therm_settings_t* s status->state = STATE_SETTEMPOFFSET; } else if(!HAL_GPIO_ReadPin(SW_UP)) { - set->temp_units = TEMP_UNITS_FAHRENHEIT; + set->val.temp_units = TEMP_UNITS_FAHRENHEIT; } else if(!HAL_GPIO_ReadPin(SW_DOWN)) { - set->temp_units = TEMP_UNITS_CELSIUS; + set->val.temp_units = TEMP_UNITS_CELSIUS; } // Event Handler @@ -314,7 +314,7 @@ void display_process(therm_settings_t* s ssd1306_drawlogo(); char tempstr[6]; - itoa(set->temp_offset, tempstr, 10); + itoa(set->val.temp_offset, tempstr, 10); ssd1306_DrawString("O=", 1, 45); ssd1306_DrawString(" ", 1, 57); ssd1306_DrawString(tempstr, 1, 57); @@ -327,7 +327,7 @@ void display_process(therm_settings_t* s status->state = STATE_IDLE; } else { - user_input_signed(&set->temp_offset); + user_input_signed(&set->val.temp_offset); } // Event Handler @@ -346,7 +346,7 @@ void display_process(therm_settings_t* s draw_setpoint(status); status->pid_enabled = 1; - status->setpoint = set->setpoint_brew; + status->setpoint = set->val.setpoint_brew; // Button handler if(SW_BTN_PRESSED) { @@ -354,7 +354,7 @@ void display_process(therm_settings_t* s status->state = STATE_IDLE; } else { - user_input(&set->setpoint_brew); + user_input(&set->val.setpoint_brew); } // Event Handler @@ -373,7 +373,7 @@ void display_process(therm_settings_t* s //ssd1306_drawlogo(); draw_setpoint(status); status->pid_enabled = 1; - status->setpoint = set->setpoint_brew; + status->setpoint = set->val.setpoint_brew; // Button handler if(SW_BTN_PRESSED) { @@ -381,7 +381,7 @@ void display_process(therm_settings_t* s status->state = STATE_IDLE; } else { - user_input(&set->setpoint_brew); + user_input(&set->val.setpoint_brew); } // Event Handler @@ -398,7 +398,7 @@ void display_process(therm_settings_t* s //ssd1306_drawlogo(); draw_setpoint(status); status->pid_enabled = 1; - status->setpoint = set->setpoint_steam; + status->setpoint = set->val.setpoint_steam; // Button handler if(SW_BTN_PRESSED) { @@ -406,7 +406,7 @@ void display_process(therm_settings_t* s save_setpoints(&set); // TODO: Check for mod } else { - user_input(&set->setpoint_steam); + user_input(&set->val.setpoint_steam); } // Event Handler @@ -425,7 +425,7 @@ void display_process(therm_settings_t* s //ssd1306_drawlogo(); draw_setpoint(status); status->pid_enabled = 1; - status->setpoint = set->setpoint_steam; + status->setpoint = set->val.setpoint_steam; // Button handler if(SW_BTN_PRESSED) { @@ -433,7 +433,7 @@ void display_process(therm_settings_t* s save_setpoints(&set); // TODO: Check for mod } else { - user_input(&set->setpoint_steam); + user_input(&set->val.setpoint_steam); } // Event Handler @@ -470,7 +470,7 @@ void display_process(therm_settings_t* s status->state = STATE_IDLE; } else if(SW_RIGHT_PRESSED) { - set->ignore_tc_error = 1; + set->val.ignore_tc_error = 1; status->state = STATE_IDLE; } // Event Handler diff --git a/flash.c b/flash.c --- a/flash.c +++ b/flash.c @@ -3,182 +3,76 @@ #include "stm32f0xx_hal_flash.h" #include "flash.h" -void flash_init(therm_settings_t* tosave) -{ - ssd1306_clearscreen(); - uint16_t size = sizeof(therm_settings_t)-1; - uint32_t flash_adr = END_ADDR - size; - flash_adr -= 2; - uint8_t* flash_ptr = (uint8_t *)flash_adr; - - // Check if flash is blank - uint16_t i = 0; - uint16_t count = 0; +__attribute__((__section__(".eeprom"))) uint16_t eeprom[512]; - char tempstr[10]; - itoa(flash_adr, tempstr, 10); - ssd1306_DrawString(tempstr, 1, 0); - - uint16_t test; - for(i=0;idata[i] = *(eeprom+i); + ssd1306_DrawString("READ COMPLETE", 3, 0); } -void flash_write(therm_settings_t* tosave) +static void __flash_write(therm_settings_t* tosave) { + // Erase mem HAL_FLASH_Unlock(); - uint16_t size = sizeof(therm_settings_t)-1; // in Bytes - uint32_t start_address = END_ADDR-size; // write to end of page - uint32_t struct_ptr = (uint32_t*) tosave; + // Erase the FLASH pages + FLASH_EraseInitTypeDef erase; + erase.TypeErase = TYPEERASE_PAGES; + erase.PageAddress = eeprom; + erase.NbPages = 1; + uint32_t SectorError = 0; + HAL_FLASHEx_Erase(&erase, &SectorError); - uint16_t length; - if(size%2==0) - length = size/2; - else - length = size/2+1; + CLEAR_BIT(FLASH->CR, FLASH_CR_PER); uint16_t i; - for(i=0;idata[i]); + // } + HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, eeprom + EEPROM_MAGIC_INDEX, EEPROM_MAGIC_VALUE); HAL_FLASH_Lock(); } -void flash_checksum(therm_settings_t* tosave) -{ - uint8_t cksum0=0,cksum1=0; - uint16_t i,size,checksum; - uint32_t flash_adr; - uint8_t *flash_ptr; - - HAL_FLASH_Unlock(); - - size = sizeof(*tosave)-1; // in Bytes - flash_adr = END_ADDR-size; - flash_ptr = (uint8_t *)flash_adr; - - for(i=1; i < size; i++) - { - cksum0 += *flash_ptr++; - cksum1 += cksum0; - } - checksum = (cksum1<<8) | cksum0; - flash_adr -= 2; - HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, flash_adr, checksum); - - HAL_FLASH_Lock(); -} - - -void flash_erase(therm_settings_t* tosave) -{ - uint8_t FLASHStatus = 1; // FLASH_COMPLETE=1 - uint32_t end_addr = END_ADDR; - uint32_t NbrOfPage = abs( (sizeof(*tosave)-1)/0x400 )+1; // Number of pages to be erased, most definitely 1 but hey, we might as well try to calculate it. - uint32_t StartAddr = (end_addr+1) - (0x400*NbrOfPage); // Starting address to be erased - - HAL_FLASH_Unlock(); - - // Clear All pending flags - //FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); - - // Erase the FLASH pages - FLASH_EraseInitTypeDef erase; - erase.TypeErase = TYPEERASE_PAGES; - erase.PageAddress = StartAddr; - erase.NbPages = NbrOfPage; - uint32_t SectorError = 0; - FLASHStatus = HAL_FLASHEx_Erase(&erase, &SectorError); - - HAL_FLASH_Lock(); -} // vim:softtabstop=4 shiftwidth=4 expandtab diff --git a/flash.h b/flash.h --- a/flash.h +++ b/flash.h @@ -6,12 +6,9 @@ #define PAGE_SIZE ((uint16_t)0x400) #define END_ADDR 0x08007FFF -void flash_init(therm_settings_t* tosave); void flash_save(therm_settings_t* tosave); -void flash_read(therm_settings_t *tosave); -void flash_write(therm_settings_t* tosave); -void flash_checksum(therm_settings_t* tosave); -void flash_erase(therm_settings_t* tosave); +void flash_restore(therm_settings_t *tosave); +void flash_erase(void); #endif diff --git a/main.c b/main.c --- a/main.c +++ b/main.c @@ -49,7 +49,7 @@ int main(void) // Init USB (TODO: Handle plugged/unplugged with external power) MX_USB_DEVICE_Init(); -// set.usb_plugged = +// set.val.usb_plugged = // USB startup delay HAL_Delay(1000); @@ -67,15 +67,15 @@ int main(void) ssd1306_clearscreen(); // Default settings - set.boottobrew = 0; - set.temp_units = TEMP_UNITS_CELSIUS; - set.windup_guard = 1; - set.k_p = 1; - set.k_i = 1; - set.k_d = 1; - set.ignore_tc_error = 0; - set.setpoint_brew = 0; - set.setpoint_steam = 0; + set.val.boottobrew = 0; + set.val.temp_units = TEMP_UNITS_CELSIUS; + set.val.windup_guard = 1; + set.val.k_p = 1; + set.val.k_i = 1; + set.val.k_d = 1; + set.val.ignore_tc_error = 0; + set.val.setpoint_brew = 0; + set.val.setpoint_steam = 0; // Default status status.temp = 0; @@ -89,7 +89,7 @@ int main(void) restore_settings(&set); // Go to brew instead of idle if configured thusly - if(set.boottobrew) + if(set.val.boottobrew) status.state = STATE_PREHEAT_BREW; // Startup screen @@ -98,7 +98,7 @@ int main(void) HAL_Delay(1500); - flash_init(&set); + flash_restore(&set); HAL_Delay(1500); ssd1306_clearscreen(); @@ -138,7 +138,7 @@ int16_t update_pid(uint16_t k_p, uint16_ // it cant help be cold despite its best efforts) // not necessary, but this makes windup guard values // relative to the current iGain - int32_t windup_guard_res = set.windup_guard / k_i; + int32_t windup_guard_res = set.val.windup_guard / k_i; // Calculate integral term with windup guard if (i_state > windup_guard_res) @@ -201,7 +201,7 @@ void process() if(status.pid_enabled) { // Get ssr output for next time - int16_t power_percent = update_pid(set.k_p, set.k_i, set.k_d, status.temp, status.temp_frac, status.setpoint); + int16_t power_percent = update_pid(set.val.k_p, set.val.k_i, set.val.k_d, status.temp, status.temp_frac, status.setpoint); //power-percent is 0-1000 ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000; } @@ -244,7 +244,7 @@ void process() tempstr[numlen] = '\r'; tempstr[numlen+1] = '\n'; -// if(set.usb_plugged) +// if(set.val.usb_plugged) // CDC_Transmit_FS(tempstr, numlen+2); // while(CDC_Transmit_FS("\r\n", 2) == USBD_BUSY); diff --git a/max31855.c b/max31855.c --- a/max31855.c +++ b/max31855.c @@ -31,7 +31,7 @@ void max31855_readtemp(SPI_HandleTypeDef status.temp = 0; status.temp_frac = 0; } */ - if(temp_pre & 0b001 && !set->ignore_tc_error) { + if(temp_pre & 0b001 && !set->val.ignore_tc_error) { status->tc_errno = 1; HAL_Delay(400); // FIXME: remove? status->state_resume = status->state; @@ -72,21 +72,21 @@ void max31855_readtemp(SPI_HandleTypeDef } // Convert to Fahrenheit - if(set->temp_units == TEMP_UNITS_FAHRENHEIT) + if(set->val.temp_units == TEMP_UNITS_FAHRENHEIT) { status->temp = signint * ((temp_pre*100) + status->temp_frac); status->temp = status->temp * 1.8; status->temp += 3200; status->temp_frac = status->temp % 100; status->temp /= 100; - status->temp += set->temp_offset; + status->temp += set->val.temp_offset; } // Use Celsius values else { status->temp = temp_pre * signint; - status->temp += set->temp_offset; + status->temp += set->val.temp_offset; } } } diff --git a/max31865.c b/max31865.c --- a/max31865.c +++ b/max31865.c @@ -61,7 +61,7 @@ void max31865_readtemp(SPI_HandleTypeDef // Assemble data array into one var uint16_t temp_pre = rxdatal[0] | (rxdatah[0]<<8); - if(temp_pre & 0b001 && !set->ignore_tc_error) { + if(temp_pre & 0b001 && !set->val.ignore_tc_error) { status->tc_errno = 1; HAL_Delay(400); // FIXME: remove? status->state_resume = status->state; @@ -87,21 +87,21 @@ void max31865_readtemp(SPI_HandleTypeDef } // Convert to Fahrenheit - if(set->temp_units == TEMP_UNITS_FAHRENHEIT) + if(set->val.temp_units == TEMP_UNITS_FAHRENHEIT) { status->temp = signint * ((temp_pre*100) + status->temp_frac); status->temp = status->temp * 1.8; status->temp += 3200; status->temp_frac = status->temp % 100; status->temp /= 100; - status->temp += set->temp_offset; + status->temp += set->val.temp_offset; } // Use Celsius values else { status->temp = temp_pre * signint; - status->temp += set->temp_offset; + status->temp += set->val.temp_offset; } } } diff --git a/states.h b/states.h --- a/states.h +++ b/states.h @@ -11,21 +11,24 @@ typedef struct { uint8_t tc_errno; } therm_status_t; -typedef struct { - uint8_t boottobrew; - uint8_t temp_units; - uint16_t windup_guard; - uint16_t k_p; - uint16_t k_i; - uint16_t k_d; - int16_t temp_offset; - uint8_t ignore_tc_error; - int16_t setpoint_brew; - int16_t setpoint_steam; +typedef union +{ + struct { + uint32_t boottobrew; + uint32_t temp_units; + uint32_t windup_guard; + uint32_t k_p; + uint32_t k_i; + uint32_t k_d; + int32_t temp_offset; + uint32_t ignore_tc_error; + int32_t setpoint_brew; + int32_t setpoint_steam; + } val; + + uint16_t data[128]; } therm_settings_t; - - enum tempunits { TEMP_UNITS_CELSIUS = 0, TEMP_UNITS_FAHRENHEIT, diff --git a/stm32f042c6_flash.ld b/stm32f042c6_flash.ld --- a/stm32f042c6_flash.ld +++ b/stm32f042c6_flash.ld @@ -11,7 +11,8 @@ ENTRY(Reset_Handler) /* Specify the memory areas */ MEMORY { -FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 30K +EEPROM (xrw) : ORIGIN = 0x8007C00, LENGTH = 1K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 6K } @@ -96,6 +97,7 @@ SECTIONS } >RAM AT> FLASH + /* Uninitialized data section */ . = ALIGN(4); .bss : @@ -123,7 +125,13 @@ SECTIONS . = ALIGN(4); } >RAM - + .eeprom : + { + . = ALIGN(4); + *(.eeprom) + . = ALIGN(4); + } >EEPROM + /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/syslib.c b/syslib.c --- a/syslib.c +++ b/syslib.c @@ -69,10 +69,14 @@ void systemclock_config(void) RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + // Enable HSI48 for main system clock + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI14; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSI14State = RCC_HSI14_ON; + RCC_OscInitStruct.HSI14CalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&RCC_OscInitStruct); + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;