Changeset - 72630eaa8151
[Not reviewed]
default
1 9 1
Ethan Zonca - 8 years ago 2017-06-23 12:52:54
ezonca@sealandaire.com
Refactor settings a bit, move stuff around
10 files changed with 133 insertions and 126 deletions:
0 comments (0 inline, 0 general)
inc/config.h
Show inline comments
 
#ifndef CONFIG_H
 
#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
 
 
// Solid-state relay maximum on-time
 
#define SSR_PERIOD 200
 
 
// Interval of PID calculations
 
#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
 
#define DEFAULT_K_P 10
 
#define DEFAULT_K_I 1
 
#define DEFAULT_K_D 1
 
#define DEFAULT_TEMP_OFFSET 0
 
#define DEFAULT_IGNORE_ERROR 0
 
#define DEFAULT_SETPOINT_BREW 70
 
#define DEFAULT_SETPOINT_STEAM 70
 
#define DEFAULT_HYSTERESIS 1
 
 
 
//////////////////////////////////////////////////////
 
// Watchdog Settings
 
//////////////////////////////////////////////////////
 
//#define WATCHDOG_ENABLE
 
 
 
 
// Internal macros
 
#define hal_init HAL_Init
 
#define MAKE32(by3,by2,by1,by0) ((uint32_t)((((((by3<<8)+by2)<<8)+by1)<<8)+by0))
 
 
#endif
 
 
 
 
 
 
inc/display.h
Show inline comments
 
#ifndef DISPLAY_H
 
#define DISPLAY_H
 

	
 
#include "states.h"
 

	
 
#ifdef MAX31865_RTD_SENSOR
 
#include "max31865.h"
 
#endif
 

	
 
void display_startup_screen();
 
void display_process(therm_settings_t* set, therm_status_t* status);
 
void display_process(therm_status_t* status);
 

	
 
#endif
inc/system/flash.h
Show inline comments
 
#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
inc/system/gpio.h
Show inline comments
 
@@ -20,20 +20,21 @@
 
#define SW_C_Pin GPIO_PIN_7
 
#define SW_C_GPIO_Port GPIOA
 
#define SW_DOWN SW_C_GPIO_Port, SW_C_Pin
 
 
#define SW_BTN_Pin GPIO_PIN_0
 
#define SW_BTN_GPIO_Port GPIOB
 
#define SW_BTN SW_BTN_GPIO_Port , SW_BTN_Pin
 
 
#define LED_PIN GPIO_PIN_6
 
#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);
 
 
void gpio_init(void);
 
void gpio_led_blueblink(uint8_t num_blinks);
 
 
#endif
inc/system/stm32f3xx_hal_conf.h
Show inline comments
 
file renamed from inc/stm32f3xx_hal_conf.h to inc/system/stm32f3xx_hal_conf.h
lib/ssd1306/ssd1306.c
Show inline comments
 
#include "stm32f3xx_hal.h"
 
#include "ssd1306.h"
 
 
 
SPI_HandleTypeDef hspi1;
 
 
 
 
// SPI handle accessor
 
SPI_HandleTypeDef* spi_get()
 
{
 
    return &hspi1;
 
}
 
 
 
// Write command to OLED
 
static void WriteCommand(unsigned char command)
 
{
 
  SSD_CS_Low();
 
  SSD_A0_Low();
 
  SPI_SendByte(command);
 
@@ -24,98 +24,97 @@ static void WriteCommand(unsigned char c
 
// Write data to OLED
 
static void WriteData(unsigned char data)
 
{
 
  SSD_CS_Low();
 
  SSD_A0_High();
 
  SPI_SendByte(data);
 
  SSD_CS_High();
 
}
 
 
// 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
 
}
 
 
 
// Times New Roman font
 
static const char fontData[][5] =
 
{                                       // Refer to "Times New Roman" Font Database
 
                                        //   Basic Characters
 
    {0x00,0x00,0x00,0x00,0x00},         //   (  0)    - 0x0020 No-Break Space
 
    {0x00,0x00,0x4F,0x00,0x00},         //   (  1)  ! - 0x0021 Exclamation Mark
 
    {0x00,0x07,0x00,0x07,0x00},         //   (  2)  " - 0x0022 Quotation Mark
 
    {0x14,0x7F,0x14,0x7F,0x14},         //   (  3)  # - 0x0023 Number Sign
 
    {0x24,0x2A,0x7F,0x2A,0x12},         //   (  4)  $ - 0x0024 Dollar Sign
 
@@ -219,66 +218,74 @@ static const char fontData[][5] =
 
//    {0x08,0x08,0x2A,0x08,0x08},         //   (102)  + - 0x00F7 Division Sign
 
//    {0x18,0x14,0x08,0x14,0x0C},         //   (103)    - 0x221E Infinity
 
//    {0x44,0x4A,0x4A,0x51,0x51},         //   (104)  < - 0x2264 Less-Than or Equal to
 
//    {0x51,0x51,0x4A,0x4A,0x44},         //   (105)  > - 0x2265 Greater-Than or Equal to
 
//    {0x54,0x14,0x64,0x08,0x70},         //   (106)  .: - RF Symbol
 
//    {0x70,0x7C,0x72,0x7C,0x70},         //   (107)  ^ - Lock symbol
 
//    {0x70,0x5C,0x52,0x54,0x70},         //   (108)  / - Unlock symbol
 
//    {0x0C,0x1E,0x3C,0x1E,0x0C},         //   (109)  <3 - Heart Symbol
 
//    {0x18,0x22,0xFF,0x12,0x0C},         //   (110)  U - USB Symbol
 
};
 
 
 
// 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
 
    WriteCommand(0x10+d/16);    // Set Higher Column Start Address for Page Addressing Mode
 
                                // Default => 0x10
 
}
 
 
 
// 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},
 
 
	{0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x3F,0x3F,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7F,0x0F},
 
 
	{0xF0,0xFE,0xFF,0xFF,0xFF,0xC7,0x00,0x00,0x00,0x00,0x87,0xC7,0xC7,0xFF,0xFF,0x00,0x00,0x00,0x00,0x87,0x87,0xC7,0xC3,0x03,0x07,0x07,0x0F,0x7F,0xFF,0xFF,0xFE,0xF0},
 
 
	{0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFC,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0x1F,0x1F,0x1F,0x1F,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00},
 
 
};
 
 
 
// Clear the screen
 
void ssd1306_clearscreen()
 
{
 
    uint8_t i = 0;
 
    uint8_t page = 0;
 
    for(page = 0; page<4; page++)
 
    {
 
        setStartPage(page);
 
        setStartColumn(0);
 
        for(i = 0; i<128; i++)
 
        {
 
            WriteData(0x00);
 
        }
 
    }
 
    WriteData(0x00);
 
}
 
 
 
// Draw the therm logo on the left side of the OLED
 
void ssd1306_drawlogo()
 
{
 
    uint8_t i = 0;
 
    setStartPage(3);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[0][i]);
 
    }
 
 
    WriteData(0x00);
 
 
@@ -298,42 +305,45 @@ void ssd1306_drawlogo()
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(0);
 
    setStartColumn(0);
 
    for(i = 0; i < 32; i++)
 
    {
 
        WriteData(row[3][i]);
 
    }
 
    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;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    for(uint8_t i = 0; i < 5; i++)
 
    {
 
        WriteData(*srcPointer);
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
}
 
 
 
// Print a single large character
 
void ssd1306_drawcharbig(char ascii, unsigned char row, unsigned char xPos)
 
{
 
    const char *srcPointer = (char*)-1;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
 
    setStartPage(row-1);
 
    setStartColumn(xPos);
 
 
    // Write first row
 
    for(uint8_t i = 0; i < 5; i++)
 
    {
 
@@ -378,41 +388,44 @@ void ssd1306_drawcharbig(char ascii, uns
 
        data |= ((*srcPointer) & 0b00010000) >> 3; // get top 4 bits
 
        data |= ((*srcPointer) & 0b00010000) >> 4; // get top 4 bits
 
 
        WriteData(data);
 
        WriteData(data);
 
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
 
}
 
 
 
// Print a string to the display
 
void ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer;
 
 
    srcPointer = (char*)dataPtr;
 
    ssd1306_drawchar(' ',row,xPos); // NBSP must be written first before the string start
 
 
    while(1)
 
    {
 
        ssd1306_drawchar(*srcPointer,row,xPos);
 
        srcPointer++;
 
        xPos+=6;
 
        if(*srcPointer == 0) break;
 
    }
 
}
 
 
 
// Print a string to the display, big font
 
void ssd1306_drawstringbig(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer;
 
 
    srcPointer = (char*)dataPtr;
 
    ssd1306_drawcharbig(' ',row,xPos); // NBSP must be written first before the string start
 
 
    while(1)
 
    {
 
        ssd1306_drawcharbig(*srcPointer,row,xPos);
 
        srcPointer++;
 
        xPos+=12;
src/display.c
Show inline comments
 
//
 
// Display: render menus on OLED display
 
//
 

	
 
#include "display.h"
 
#include "gpio.h"
 
#include "ssd1306/ssd1306.h"
 
#include "system/stringhelpers.h"
 
#include "flash.h"
 

	
 
// Private function prototypes
 
static void draw_setpoint(therm_status_t* status);
 

	
 

	
 
// Button transition variables
 
static uint8_t sw_btn_last = 0;
 
@@ -26,26 +30,27 @@ static uint8_t sw_right_last = 0;
 

	
 
// States
 
static uint8_t trigger_drawsetpoint = 1;
 
static int16_t last_temp = 21245;
 
static int16_t last_temp_frac = 21245;
 
static int16_t last_state = 123;
 
static uint8_t goto_mode = MODE_HEAT;
 
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;
 
    
 
    uint8_t temp_changed = status->temp != last_temp || status->temp_frac != last_temp_frac;
 
    last_temp = status->temp;
 
    last_temp_frac = status->temp_frac;
 

	
 
    uint8_t sw_btn = !HAL_GPIO_ReadPin(SW_BTN);
 
    uint8_t sw_up = !HAL_GPIO_ReadPin(SW_UP);
 
    uint8_t sw_down = !HAL_GPIO_ReadPin(SW_DOWN);
 
    uint8_t sw_left = !HAL_GPIO_ReadPin(SW_LEFT);
 
    uint8_t sw_right = !HAL_GPIO_ReadPin(SW_RIGHT);
src/main.c
Show inline comments
 
@@ -9,102 +9,88 @@
 
 
#include "watchdog.h"
 
#include "system.h"
 
#include "display.h"
 
#include "gpio.h"
 
#include "pid.h"
 
#include "error.h"
 
#include "flash.h"
 
#include "ssd1306/ssd1306.h"
 
#include "interrupts.h"
 
 
 
therm_settings_t set;
 
therm_status_t status;
 
pid_state_t pid_state;
 
 
 
int main(void)
 
{
 
	sysclock_init();
 
	hal_init();
 
	gpio_init();
 
 
 
	ssd1306_init();
 
 
	// Startup screen
 
    display_startup_screen();
 
    HAL_Delay(2000);
 
 
	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;
 
    status.temp_frac = 0;
 
    status.state_resume = 0;
 
    status.state = STATE_IDLE;
 
    status.setpoint = 70;
 
    status.pid_enabled = 0;
 
 
    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;
 
    uint32_t last_pid = 0;
 
    uint32_t last_thermostat = 0;
 
    int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD
 
    uint8_t thermostat_plant_on = 0;
 
 
 
	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
 
//            max31865_readtemp(spi_get(), &set, &status);
 
//			#else
 
//			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
 
//			#endif
 
 
 
            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?
 
                ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000;
 
 
 
            	// put ssr output on display
 
                ssd1306_drawstring("      ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
 
                char tempstr[6];
 
                itoa(ssr_output, tempstr, 10);
 
                ssd1306_drawstring(tempstr, 0, 90);
 
            }
 
@@ -135,88 +121,88 @@ int main(void)
 
//                last_ssr_on = HAL_GetTick();
 
//            }
 
//            else {
 
//                // Make sure everything is off
 
//                HAL_GPIO_WritePin(SSR_PIN, 0);
 
//                HAL_GPIO_WritePin(LED_POWER, 0);
 
//            }
 
//
 
//        }
 
 
 
        // 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
 
//            max31865_readtemp(spi_get(), &set, &status);
 
//			#else
 
//			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
 
//			#endif
 
 
            // TODO: Migrate this FxP conversion to the readtemp code or similar
 
            int8_t temp_frac = status.temp_frac > 9 ? status.temp_frac / 10 : status.temp_frac;
 
            temp_frac = status.temp > 0 ? temp_frac : temp_frac * -1;
 
            int32_t temp = (status.temp * 10) + temp_frac;
 
 
 
            // 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
 
            if(status.pid_enabled && thermostat_plant_on)
 
            {
 
                // EMZ TODO: functionalize this
 
            	// put ssr output on display
 
                ssd1306_drawstring("      ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
 
                char tempstr[6];
 
                itoa(ssr_output, tempstr, 10);
 
                ssd1306_drawstring(tempstr, 0, 90);
 
 
 
 
                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();
 
        }
 
 
 
//        // Transmit temperature over USB-CDC on a regular basis
 
//        if(HAL_GetTick() - last_vcp_tx > VCP_TX_FREQ)
 
//        {
 
//            // Print temp to cdc
 
//            char tempstr[16];
 
//            itoa_fp(status.temp, status.temp_frac, tempstr);
 
//            uint8_t numlen = strlen(tempstr);
 
//            tempstr[numlen] = '\r';
 
//            tempstr[numlen+1] = '\n';
 
//
 
//    //        if(set.val.usb_plugged)
 
//    //            CDC_Transmit_FS(tempstr, numlen+2);
 
//           // while(CDC_Transmit_FS("\r\n", 2) == USBD_BUSY);
 
//
 
//            last_vcp_tx = HAL_GetTick();
 
//        }
 
 
        // Run state machine
 
        display_process(&set, &status);
 
        display_process(&status);
 
 
		watchdog_feed();
 
	}
 
}
 
 
src/pid.c
Show inline comments
 
//
 
// PID: proportional/integral/derivative controller
 
//
 

	
 
#include "pid.h"
 

	
 
// PID implementation
 

	
 
void pid_init(pid_state_t* state)
 
{
 
	state->i_state = 0;
 
	state->last_pid_temp = 0;
 
	state->last_pid_temp_frac = 0;
 
}
 

	
 
int16_t pid_update(therm_settings_t* set, therm_status_t* status, pid_state_t *state)
src/system/flash.c
Show inline comments
 
//
 
// Flash: Nonvolatile storage for settings / etc
 
//
 
 
#include "stm32f3xx_hal.h"
 
#include "flash.h"
 
#include "config.h"
 
 
// 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)
 
{
 
	flash_restoresettings();
 
}
 
 
 
// Save settings to flash memory
 
void flash_savesettings(void)
 
void flash_savesettings()
 
{
 
	// Unlock flash memory
 
	HAL_FLASH_Unlock();
 
 
	// Initialize eraser to erase one page of flash
 
	FLASH_EraseInitTypeDef eraser =
 
	{
 
			.TypeErase = TYPEERASE_PAGES,
 
			.PageAddress = eeprom_emulation,
 
			.NbPages = 1,
 
	};
 
	uint32_t errvar = 0;
 
@@ -59,22 +59,22 @@ void flash_restoresettings(void)
 
	if(eeprom_emulation[FLASH_MAGIC_LOC] == FLASH_MAGIC_VALUE)
 
	{
 
		// Read page of flash into settings structure
 
		uint16_t readctr = 0;
 
		for(readctr = 0; readctr < 128; readctr++)
 
		{
 
			settings.data[readctr] = eeprom_emulation[readctr];
 
		}
 
	}
 
	// 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;
 
}
0 comments (0 inline, 0 general)