@@ -7,13 +7,13 @@
#######################################
# user configuration:
# SOURCES: list of sources in the user application
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c gpio.c spi.c ssd1306.c stringhelpers.c display.c bootlib.c storage.c
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c gpio.c spi.c ssd1306.c stringhelpers.c display.c bootlib.c storage.c flash.c
# TARGET: name of the user application
TARGET = main
# BUILD_DIR: directory to place output files in
BUILD_DIR = build
@@ -2,12 +2,13 @@
#include "ssd1306.h"
#include "stringhelpers.h"
#include "display.h"
#include "config.h"
#include "states.h"
#include "bootlib.h"
#include "flash.h"
#include "gpio.h"
uint8_t goto_mode = 2;
// State machine
uint8_t sw_btn_last = 0;
@@ -82,19 +83,27 @@ void display_process(therm_settings_t* s
{
ssd1306_DrawString("-> setup ", 1, 40);
} break;
case 0:
ssd1306_DrawString("-> loader ", 1, 40);
case 3:
ssd1306_DrawString("-> reset ", 1, 40);
}
// Button handler
if(SW_BTN_PRESSED) {
switch(goto_mode) {
status->state = STATE_IDLE;
flash_erase(set);
case 2:
status->state = STATE_PREHEAT_BREW;
break;
case 1:
status->state = STATE_SETP;
@@ -109,13 +118,13 @@ void display_process(therm_settings_t* s
default:
else if(SW_UP_PRESSED && goto_mode < 2) {
else if(SW_UP_PRESSED && goto_mode < 3) {
goto_mode++;
else if(SW_DOWN_PRESSED && goto_mode > 0) {
goto_mode--;
@@ -360,13 +369,13 @@ void display_process(therm_settings_t* s
ssd1306_DrawString(tempstr, 1, 57);
ssd1306_DrawString("Press to accept", 3, 40);
save_settings(&set);
flash_save(&set);
else {
user_input_signed(&set->temp_offset);
new file 100644
#include "stm32f0xx_hal.h"
#include "stm32f0xx_hal_flash.h"
void flash_init(therm_settings_t* tosave)
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;
char tempstr[10];
itoa(flash_adr, tempstr, 10);
ssd1306_DrawString(tempstr, 1, 0);
uint16_t test;
for(i=0;i<size;i++)
test = *flash_ptr;
if(test==0xFF) count++;
ssd1306_DrawString("END LOOP ", 0, 0);
// If blank, do nothing and just use values from RAM
// If not blank, check the checksums
if(count != size)
ssd1306_DrawString("FLASH NOT BLANK", 1, 0);
// Calculate Checksums
uint8_t cksum0=0,cksum1=0;
uint8_t rdSum0=0,rdSum1=0;
flash_adr = END_ADDR - size;
flash_ptr = (uint8_t *)flash_adr;
for(i=1; i < size; i++)
cksum0 += *flash_ptr++;
cksum1 += cksum0;
// Read flash checksums
rdSum0 = *flash_ptr++;
rdSum1 = *flash_ptr;
// Compare Checksums values
if((rdSum1==cksum1)&&(rdSum0==cksum0)) {
ssd1306_DrawString("CHECKSUM OK", 2, 0);
flash_read(tosave);
ssd1306_DrawString("CHECKSUM BAD", 2, 0);
return; // If the checksum is bad, just use vals from RAM
ssd1306_DrawString("FLASH BLANK", 1, 0);
void flash_save(therm_settings_t* tosave)
ssd1306_DrawString("BEGIN SAVE", 2, 0);
HAL_Delay(1500);
flash_erase(tosave);
flash_write(tosave);
flash_checksum(tosave);
ssd1306_DrawString("END SAVE", 2, 0);
void flash_read(therm_settings_t *tosave)
ssd1306_DrawString("READING SAVE", 1, 0);
itoa(sizeof(therm_settings_t), tempstr, 10);
ssd1306_DrawString(tempstr, 2, 0);
uint16_t size = sizeof(therm_settings_t)-1; // in Bytes
uint8_t *flash_ptr = (uint8_t *)flash_adr;
uint8_t *struct_ptr = (uint8_t*)tosave;
uint16_t i;
*struct_ptr++ = *flash_ptr++;
ssd1306_DrawString("READ COMPLETE", 3, 0);
void flash_write(therm_settings_t* tosave)
HAL_FLASH_Unlock();
uint32_t start_address = END_ADDR-size; // write to end of page
uint32_t struct_ptr = (uint32_t*) tosave;
uint16_t length;
if(size%2==0)
length = size/2;
else
length = size/2+1;
for(i=0;i<length;i++)
HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, start_address, struct_ptr);
struct_ptr++;
start_address +=2;
HAL_FLASH_Lock();
void flash_checksum(therm_settings_t* tosave)
uint16_t i,size,checksum;
uint32_t flash_adr;
uint8_t *flash_ptr;
size = sizeof(*tosave)-1; // in Bytes
flash_adr = END_ADDR-size;
checksum = (cksum1<<8) | cksum0;
HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, flash_adr, checksum);
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
// 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);
// vim:softtabstop=4 shiftwidth=4 expandtab
#ifndef FLASH_H
#define FLASH_H
#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);
#endif
@@ -3,8 +3,8 @@
#st-flash write main.bin 0x8000000
#cd ..
# USB DFU:
dfu-util -a 0 -d 0483:df11 -s 0x08000000:leave -D build/main.bin
sleep 1
sleep 2
dfu-util -a 1 -s 0x1FFFF800:8 -D optbytes.dat
#include "spi.h"
#include "storage.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
@@ -49,12 +50,15 @@ int main(void)
MX_USB_DEVICE_Init();
// USB startup delay
HAL_Delay(1000);
HAL_GPIO_WritePin(LED_POWER, 1);
if(!HAL_GPIO_ReadPin(SW_UP))
bootloader_enter(); // Resets into bootloader
// TODO: Awesome pwm of power LED
// Configure 1ms SysTick (change if more temporal resolution needed)
//RCC_ClocksTypeDef RCC_Clocks;
//RCC_GetClocksFreq(&RCC_Clocks);
//SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
@@ -94,12 +98,16 @@ int main(void)
// Startup screen
ssd1306_DrawString("therm v0.2", 1, 40);
ssd1306_DrawString("protofusion.org/therm", 3, 0);
flash_init(&set);
ssd1306_clearscreen();
// Main loop
while(1)
// Process sensor inputs
Status change: