diff --git a/inc/config.h b/inc/config.h --- a/inc/config.h +++ b/inc/config.h @@ -2,18 +2,17 @@ #define CONFIG_H +////////////////////////////////////////////////////// +// Sensor Type +////////////////////////////////////////////////////// +//#define MAX31855_TC_SENSOR +//#define MAX31865_RTD_SENSOR +#define MAX_WHATEVERTHENEWONEIS + ////////////////////////////////////////////////////// -// Watchdog Settings +// USB ////////////////////////////////////////////////////// -//#define WATCHDOG_ENABLE - - - -// Temperature sensor type -#define MAX31855_TC_SENSOR -//#define MAX31865_RTD_SENSOR - // Virtual serial port transmit rate #define VCP_TX_FREQ 1000 @@ -25,18 +24,18 @@ #define PID_PERIOD 120 - -// Pin settings -#define LED_POWER GPIOF,GPIO_PIN_0 -#define MAX_CS GPIOA,GPIO_PIN_15 - -#define SSR_PIN GPIOA, GPIO_PIN_1 - +////////////////////////////////////////////////////// +// Other settings +////////////////////////////////////////////////////// // Add bootloader option to top of idle screen menu #define BOOTLOADER_SHORTCUT +////////////////////////////////////////////////////// +// Default Settings +////////////////////////////////////////////////////// + #define DEFAULT_BOOT_TO_BREW 0 #define DEFAULT_TEMP_UNITS TEMP_UNITS_FAHRENHEIT #define DEFAULT_WINDUP_GUARD 10 @@ -50,6 +49,12 @@ #define DEFAULT_HYSTERESIS 1 +////////////////////////////////////////////////////// +// Watchdog Settings +////////////////////////////////////////////////////// +//#define WATCHDOG_ENABLE + + // Internal macros #define hal_init HAL_Init diff --git a/inc/display.h b/inc/display.h --- a/inc/display.h +++ b/inc/display.h @@ -8,6 +8,6 @@ #endif void display_startup_screen(); -void display_process(therm_settings_t* set, therm_status_t* status); +void display_process(therm_status_t* status); #endif diff --git a/inc/system/flash.h b/inc/system/flash.h --- a/inc/system/flash.h +++ b/inc/system/flash.h @@ -1,23 +1,16 @@ #ifndef flash_h #define flash_h +#include "states.h" + #define FLASH_MAGIC_LOC 511 #define FLASH_MAGIC_VALUE 0xbeef -typedef union -{ - struct _values { - uint16_t can_id; - uint16_t tx_period; - } values; - - uint16_t data[128]; -} settings_t; void flash_init(void); void flash_savesettings(void); void flash_restoresettings(void); -settings_t* flash_getsettings(void); +therm_settings_t* flash_getsettings(void); #endif // flash_h diff --git a/inc/system/gpio.h b/inc/system/gpio.h --- a/inc/system/gpio.h +++ b/inc/system/gpio.h @@ -29,6 +29,7 @@ #define LED_GPIO_Port GPIOB #define LED LED_GPIO_Port, LED_PIN +/// SSR PIN ???/// void user_input(uint16_t* to_modify); void user_input_signed(int32_t* to_modify); diff --git a/inc/stm32f3xx_hal_conf.h b/inc/system/stm32f3xx_hal_conf.h rename from inc/stm32f3xx_hal_conf.h rename to inc/system/stm32f3xx_hal_conf.h diff --git a/lib/ssd1306/ssd1306.c b/lib/ssd1306/ssd1306.c --- a/lib/ssd1306/ssd1306.c +++ b/lib/ssd1306/ssd1306.c @@ -5,7 +5,7 @@ SPI_HandleTypeDef hspi1; - +// SPI handle accessor SPI_HandleTypeDef* spi_get() { return &hspi1; @@ -33,80 +33,79 @@ static void WriteData(unsigned char data // Initialize OLED void ssd1306_init(void) { - __SPI3_CLK_ENABLE(); - __GPIOA_CLK_ENABLE(); - __GPIOB_CLK_ENABLE(); - GPIO_InitTypeDef GPIO_InitStruct; + __SPI3_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitTypeDef GPIO_InitStruct; - /*Configure GPIO pins : OLED_CS_Pin OLED_RESET_Pin OLED_DC_Pin */ - GPIO_InitStruct.Pin = OLED_CS_Pin|OLED_RESET_Pin|OLED_DC_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(OLED_DC_GPIO_Port, &GPIO_InitStruct); + /*Configure GPIO pins : OLED_CS_Pin OLED_RESET_Pin OLED_DC_Pin */ + GPIO_InitStruct.Pin = OLED_CS_Pin|OLED_RESET_Pin|OLED_DC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(OLED_DC_GPIO_Port, &GPIO_InitStruct); // Set up MOSI/MISO/SCK - GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Set up SPI port for OLED - hspi1.Instance = SPI3; - hspi1.Init.Mode = SPI_MODE_MASTER; - hspi1.Init.Direction = SPI_DIRECTION_2LINES; - hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi1.Init.TIMode = SPI_TIMODE_DISABLED; - hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLED; - HAL_SPI_Init(&hspi1); - + hspi1.Instance = SPI3; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLED; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLED; + HAL_SPI_Init(&hspi1); - /* Generate a reset */ - SSD_Reset_Low(); - uint32_t i; - for(i=5000; i>1; i--) - SSD_Reset_High(); + // Generate a reset + SSD_Reset_Low(); + uint32_t i; + for(i=5000; i>1; i--) + SSD_Reset_High(); - WriteCommand(0xAE); - WriteCommand(0xD5); - WriteCommand(0x80); - WriteCommand(0xA8); - WriteCommand(0x1F); - WriteCommand(0xD3); - WriteCommand(0x00); - WriteCommand(0x40 | 0x00); // line #0 - WriteCommand(0x8D); - WriteCommand(0x14); //10 or 14 if not externalvcc - WriteCommand(0x20); - WriteCommand(0x00); -// WriteCommand(0xA0 | 0x1); // segremap (normal) - WriteCommand(0xA0); // segremap (flip) -// WriteCommand(0xC8); // comscandec (normal) - WriteCommand(0xC0); // comscandec (flip) - WriteCommand(0xDA); // setcompins - WriteCommand(0x02); - WriteCommand(0x81); // contrast - WriteCommand(0x0F); // contrast value. 8f is a good one. - WriteCommand(0xD9); - WriteCommand(0xF1); //22 or F1 if not externalvcc - WriteCommand(0xDB); - WriteCommand(0x40); - WriteCommand(0xA4); // dispalyallon_resume - WriteCommand(0xA6); // normaldisplay + WriteCommand(0xAE); + WriteCommand(0xD5); + WriteCommand(0x80); + WriteCommand(0xA8); + WriteCommand(0x1F); + WriteCommand(0xD3); + WriteCommand(0x00); + WriteCommand(0x40 | 0x00); // line #0 + WriteCommand(0x8D); + WriteCommand(0x14); //10 or 14 if not externalvcc + WriteCommand(0x20); + WriteCommand(0x00); + // WriteCommand(0xA0 | 0x1); // segremap (normal) + WriteCommand(0xA0); // segremap (flip) + // WriteCommand(0xC8); // comscandec (normal) + WriteCommand(0xC0); // comscandec (flip) + WriteCommand(0xDA); // setcompins + WriteCommand(0x02); + WriteCommand(0x81); // contrast + WriteCommand(0x0F); // contrast value. 8f is a good one. + WriteCommand(0xD9); + WriteCommand(0xF1); //22 or F1 if not externalvcc + WriteCommand(0xDB); + WriteCommand(0x40); + WriteCommand(0xA4); // dispalyallon_resume + WriteCommand(0xA6); // normaldisplay - WriteCommand(0xAF); // display on + WriteCommand(0xAF); // display on } @@ -228,12 +227,15 @@ static const char fontData[][5] = }; +// Set start page static void setStartPage(unsigned char d) { WriteCommand(0xB0|d); // Set Page Start Address for Page Addressing Mode // Default => 0xB0 (0x00) } -/* Below are functions used to configure the OLED */ + + +// Set start column static void setStartColumn(unsigned char d) { WriteCommand(0x00+d%16); // Set Lower Column Start Address for Page Addressing Mode @@ -242,6 +244,7 @@ static void setStartColumn(unsigned char } +// Therm logo const uint8_t row[4][32] = { {0x00,0x00,0x01,0x03,0x07,0x0F,0x1E,0x3C,0x3C,0x7C,0x7C,0x7C,0xFC,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFF,0x7F,0x7F,0x7F,0x3C,0x3C,0x1C,0x0C,0x06,0x03,0x01,0x00,0x00}, @@ -254,6 +257,8 @@ const uint8_t row[4][32] = { }; + +// Clear the screen void ssd1306_clearscreen() { uint8_t i = 0; @@ -270,6 +275,8 @@ void ssd1306_clearscreen() WriteData(0x00); } + +// Draw the therm logo on the left side of the OLED void ssd1306_drawlogo() { uint8_t i = 0; @@ -307,7 +314,8 @@ void ssd1306_drawlogo() WriteData(0x00); } -/* Print a single character from font.cpp */ + +// Print a single character void ssd1306_drawchar(char ascii, unsigned char row, unsigned char xPos) { const char *srcPointer = (char*)-1; @@ -325,6 +333,8 @@ void ssd1306_drawchar(char ascii, unsign WriteData(0x00); } + +// Print a single large character void ssd1306_drawcharbig(char ascii, unsigned char row, unsigned char xPos) { const char *srcPointer = (char*)-1; @@ -387,6 +397,8 @@ void ssd1306_drawcharbig(char ascii, uns } + +// Print a string to the display void ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos) { char *srcPointer; @@ -404,6 +416,7 @@ void ssd1306_drawstring(const char *data } +// Print a string to the display, big font void ssd1306_drawstringbig(const char *dataPtr, unsigned char row, unsigned char xPos) { char *srcPointer; diff --git a/src/display.c b/src/display.c --- a/src/display.c +++ b/src/display.c @@ -1,3 +1,7 @@ +// +// Display: render menus on OLED display +// + #include "display.h" #include "gpio.h" #include "ssd1306/ssd1306.h" @@ -35,8 +39,9 @@ static uint8_t reset_mode = RESET_REBOOT // Display state machine -void display_process(therm_settings_t* set, therm_status_t* status) +void display_process(therm_status_t* status) { + therm_settings_t* set = flash_getsettings(); uint8_t state_changed = status->state != last_state; last_state = status->state; diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,6 @@ #include "interrupts.h" -therm_settings_t set; therm_status_t status; pid_state_t pid_state; @@ -38,15 +37,7 @@ int main(void) ssd1306_drawlogo(); - watchdog_init(); - //just some example code for getting flash values -// flash_getsettings()->values.can_id = 67; -// -// if(flash_getsettings()->values.can_id == 12); - -// ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos) -// ssd1306_drawstring("[ ProtoFuse ]", 0, 0); // Default status status.temp = 0; @@ -59,15 +50,10 @@ int main(void) pid_init(&pid_state); flash_init(); + watchdog_init(); - float temp_counter = 0; - - // Software timers - uint32_t last_screen_update_time = HAL_GetTick(); - - - // Soft timers + // Soft timers uint32_t last_ssr_on = 0; uint32_t last_vcp_tx = 0; uint32_t last_led = 0; @@ -80,7 +66,7 @@ int main(void) while (1) { - if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_pid > PID_PERIOD)) + if(flash_getsettings()->val.control_mode == MODE_PID && (HAL_GetTick() - last_pid > PID_PERIOD)) { // #ifdef MAX31865_RTD_SENSOR @@ -93,9 +79,9 @@ int main(void) if(status.pid_enabled) { // Get ssr output for next time - int16_t power_percent = pid_update(&set, &status, &pid_state); + int16_t power_percent = pid_update(flash_getsettings(), &status, &pid_state); - if(set.val.plant_type == PLANT_HEATER) + if(flash_getsettings()->val.plant_type == PLANT_HEATER) power_percent *= -1; //power-percent is 0-1000? @@ -144,7 +130,7 @@ int main(void) // Thermostatic control - if(set.val.control_mode == MODE_THERMOSTAT && HAL_GetTick() - last_thermostat > SSR_PERIOD) + if(flash_getsettings()->val.control_mode == MODE_THERMOSTAT && HAL_GetTick() - last_thermostat > SSR_PERIOD) { // #ifdef MAX31865_RTD_SENSOR @@ -160,14 +146,14 @@ int main(void) // EMZ FIXME: This could be way simpler - if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 < temp - set.val.hysteresis * 10) + if(flash_getsettings()->val.plant_type == PLANT_HEATER && status.setpoint * 10 < temp - flash_getsettings()->val.hysteresis * 10) thermostat_plant_on = 1; - else if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 > temp + set.val.hysteresis * 10) + else if(flash_getsettings()->val.plant_type == PLANT_HEATER && status.setpoint * 10 > temp + flash_getsettings()->val.hysteresis * 10) thermostat_plant_on = 0; - if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 > temp + set.val.hysteresis * 10) + if(flash_getsettings()->val.plant_type == PLANT_COOLER && status.setpoint * 10 > temp + flash_getsettings()->val.hysteresis * 10) thermostat_plant_on = 1; - else if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 < temp - set.val.hysteresis * 10) + else if(flash_getsettings()->val.plant_type == PLANT_COOLER && status.setpoint * 10 < temp - flash_getsettings()->val.hysteresis * 10) thermostat_plant_on = 0; // EMZ: TODO: Refactor to output_enabled or something @@ -182,13 +168,13 @@ int main(void) - HAL_GPIO_WritePin(SSR_PIN, 1); - HAL_GPIO_WritePin(LED_POWER, 1); +// HAL_GPIO_WritePin(SSR_PIN, 1); + HAL_GPIO_WritePin(LED, 1); } else { - HAL_GPIO_WritePin(SSR_PIN, 0); - HAL_GPIO_WritePin(LED_POWER, 0); +// HAL_GPIO_WritePin(SSR_PIN, 0); + HAL_GPIO_WritePin(LED, 0); } last_thermostat = HAL_GetTick(); @@ -213,7 +199,7 @@ int main(void) // } // Run state machine - display_process(&set, &status); + display_process(&status); watchdog_feed(); } diff --git a/src/pid.c b/src/pid.c --- a/src/pid.c +++ b/src/pid.c @@ -1,3 +1,7 @@ +// +// PID: proportional/integral/derivative controller +// + #include "pid.h" // PID implementation diff --git a/src/system/flash.c b/src/system/flash.c --- a/src/system/flash.c +++ b/src/system/flash.c @@ -8,8 +8,8 @@ // Takes up 1 page (1k size) static __attribute__((__section__(".eeprom"))) uint16_t eeprom_emulation[512]; -settings_t settings; +therm_settings_t settings; // Initialize flash and restore settings void flash_init(void) @@ -19,7 +19,7 @@ void flash_init(void) // Save settings to flash memory -void flash_savesettings(void) +void flash_savesettings() { // Unlock flash memory HAL_FLASH_Unlock(); @@ -68,13 +68,13 @@ void flash_restoresettings(void) // No data in flash! Set defaults here else { - settings.values.can_id = 22; + //torestore.values.can_id = 22; } } // Accessor to retrieve settings structure -inline settings_t* flash_getsettings(void) +inline therm_settings_t* flash_getsettings(void) { return &settings; }