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
 
#ifndef __gpio_H
 
#define __gpio_H
 
 
#include "stm32f3xx_hal.h"
 
 
 
// Define button push
 
#define SW_D_Pin GPIO_PIN_4
 
#define SW_D_GPIO_Port GPIOA
 
#define SW_RIGHT SW_D_GPIO_Port, SW_D_Pin
 
 
#define SW_B_Pin GPIO_PIN_5
 
#define SW_B_GPIO_Port GPIOA
 
#define SW_UP SW_B_GPIO_Port, SW_B_Pin
 
 
#define SW_A_Pin GPIO_PIN_6
 
#define SW_A_GPIO_Port GPIOA
 
#define SW_LEFT SW_A_GPIO_Port, SW_A_Pin
 
 
#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);
 
  SSD_CS_High();
 
}
 
 
// 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
 
    {0x23,0x13,0x08,0x64,0x62},         //   (  5)  % - 0x0025 Percent Sign
 
    {0x36,0x49,0x55,0x22,0x50},         //   (  6)  & - 0x0026 Ampersand
 
    {0x00,0x05,0x03,0x00,0x00},         //   (  7)  ' - 0x0027 Apostrophe
 
    {0x00,0x1C,0x22,0x41,0x00},         //   (  8)  ( - 0x0028 Left Parenthesis
 
    {0x00,0x41,0x22,0x1C,0x00},         //   (  9)  ) - 0x0029 Right Parenthesis
 
    {0x14,0x08,0x3E,0x08,0x14},         //   ( 10)  * - 0x002A Asterisk
 
    {0x08,0x08,0x3E,0x08,0x08},         //   ( 11)  + - 0x002B Plus Sign
 
    {0x00,0x50,0x30,0x00,0x00},         //   ( 12)  , - 0x002C Comma
 
    {0x08,0x08,0x08,0x08,0x08},         //   ( 13)  - - 0x002D Hyphen-Minus
 
    {0x00,0x60,0x60,0x00,0x00},         //   ( 14)  . - 0x002E Full Stop
 
    {0x20,0x10,0x08,0x04,0x02},         //   ( 15)  / - 0x002F Solidus
 
    {0x3E,0x51,0x49,0x45,0x3E},         //   ( 16)  0 - 0x0030 Digit Zero
 
    {0x00,0x42,0x7F,0x40,0x00},         //   ( 17)  1 - 0x0031 Digit One
 
    {0x42,0x61,0x51,0x49,0x46},         //   ( 18)  2 - 0x0032 Digit Two
 
    {0x21,0x41,0x45,0x4B,0x31},         //   ( 19)  3 - 0x0033 Digit Three
 
    {0x18,0x14,0x12,0x7F,0x10},         //   ( 20)  4 - 0x0034 Digit Four
 
    {0x27,0x45,0x45,0x45,0x39},         //   ( 21)  5 - 0x0035 Digit Five
 
    {0x3C,0x4A,0x49,0x49,0x30},         //   ( 22)  6 - 0x0036 Digit Six
 
    {0x01,0x71,0x09,0x05,0x03},         //   ( 23)  7 - 0x0037 Digit Seven
 
    {0x36,0x49,0x49,0x49,0x36},         //   ( 24)  8 - 0x0038 Digit Eight
 
    {0x06,0x49,0x49,0x29,0x1E},         //   ( 25)  9 - 0x0039 Dight Nine
 
    {0x00,0x36,0x36,0x00,0x00},         //   ( 26)  : - 0x003A Colon
 
    {0x00,0x56,0x36,0x00,0x00},         //   ( 27)  ; - 0x003B Semicolon
 
    {0x08,0x14,0x22,0x41,0x00},         //   ( 28)  < - 0x003C Less-Than Sign
 
    {0x14,0x14,0x14,0x14,0x14},         //   ( 29)  = - 0x003D Equals Sign
 
    {0x00,0x41,0x22,0x14,0x08},         //   ( 30)  > - 0x003E Greater-Than Sign
 
    {0x02,0x01,0x51,0x09,0x06},         //   ( 31)  ? - 0x003F Question Mark
 
    {0x32,0x49,0x79,0x41,0x3E},         //   ( 32)  @ - 0x0040 Commercial At
 
    {0x7E,0x11,0x11,0x11,0x7E},         //   ( 33)  A - 0x0041 Latin Capital Letter A
 
    {0x7F,0x49,0x49,0x49,0x36},         //   ( 34)  B - 0x0042 Latin Capital Letter B
 
    {0x3E,0x41,0x41,0x41,0x22},         //   ( 35)  C - 0x0043 Latin Capital Letter C
 
    {0x7F,0x41,0x41,0x22,0x1C},         //   ( 36)  D - 0x0044 Latin Capital Letter D
 
    {0x7F,0x49,0x49,0x49,0x41},         //   ( 37)  E - 0x0045 Latin Capital Letter E
 
    {0x7F,0x09,0x09,0x09,0x01},         //   ( 38)  F - 0x0046 Latin Capital Letter F
 
    {0x3E,0x41,0x49,0x49,0x7A},         //   ( 39)  G - 0x0047 Latin Capital Letter G
 
    {0x7F,0x08,0x08,0x08,0x7F},         //   ( 40)  H - 0x0048 Latin Capital Letter H
 
@@ -183,242 +182,256 @@ static const char fontData[][5] =
 
    {0x7F,0x48,0x44,0x44,0x38},         //   ( 66)  b - 0x0062 Latin Small Letter B
 
    {0x38,0x44,0x44,0x44,0x20},         //   ( 67)  c - 0x0063 Latin Small Letter C
 
    {0x38,0x44,0x44,0x48,0x7F},         //   ( 68)  d - 0x0064 Latin Small Letter D
 
    {0x38,0x54,0x54,0x54,0x18},         //   ( 69)  e - 0x0065 Latin Small Letter E
 
    {0x08,0x7E,0x09,0x01,0x02},         //   ( 70)  f - 0x0066 Latin Small Letter F
 
    {0x06,0x49,0x49,0x49,0x3F},         //   ( 71)  g - 0x0067 Latin Small Letter G
 
    {0x7F,0x08,0x04,0x04,0x78},         //   ( 72)  h - 0x0068 Latin Small Letter H
 
    {0x00,0x44,0x7D,0x40,0x00},         //   ( 73)  i - 0x0069 Latin Small Letter I
 
    {0x20,0x40,0x44,0x3D,0x00},         //   ( 74)  j - 0x006A Latin Small Letter J
 
    {0x7F,0x10,0x28,0x44,0x00},         //   ( 75)  k - 0x006B Latin Small Letter K
 
    {0x00,0x41,0x7F,0x40,0x00},         //   ( 76)  l - 0x006C Latin Small Letter L
 
    {0x7C,0x04,0x18,0x04,0x7C},         //   ( 77)  m - 0x006D Latin Small Letter M
 
    {0x7C,0x08,0x04,0x04,0x78},         //   ( 78)  n - 0x006E Latin Small Letter N
 
    {0x38,0x44,0x44,0x44,0x38},         //   ( 79)  o - 0x006F Latin Small Letter O
 
    {0x7C,0x14,0x14,0x14,0x08},         //   ( 80)  p - 0x0070 Latin Small Letter P
 
    {0x08,0x14,0x14,0x18,0x7C},         //   ( 81)  q - 0x0071 Latin Small Letter Q
 
    {0x7C,0x08,0x04,0x04,0x08},         //   ( 82)  r - 0x0072 Latin Small Letter R
 
    {0x48,0x54,0x54,0x54,0x20},         //   ( 83)  s - 0x0073 Latin Small Letter S
 
    {0x04,0x3F,0x44,0x40,0x20},         //   ( 84)  t - 0x0074 Latin Small Letter T
 
    {0x3C,0x40,0x40,0x20,0x7C},         //   ( 85)  u - 0x0075 Latin Small Letter U
 
    {0x1C,0x20,0x40,0x20,0x1C},         //   ( 86)  v - 0x0076 Latin Small Letter V
 
    {0x3C,0x40,0x30,0x40,0x3C},         //   ( 87)  w - 0x0077 Latin Small Letter W
 
    {0x44,0x28,0x10,0x28,0x44},         //   ( 88)  x - 0x0078 Latin Small Letter X
 
    {0x0C,0x50,0x50,0x50,0x3C},         //   ( 89)  y - 0x0079 Latin Small Letter Y
 
    {0x44,0x64,0x54,0x4C,0x44},         //   ( 90)  z - 0x007A Latin Small Letter Z
 
    {0x00,0x08,0x36,0x41,0x00},         //   ( 91)  { - 0x007B Left Curly Bracket
 
    {0x00,0x00,0x7F,0x00,0x00},         //   ( 92)  | - 0x007C Vertical Line
 
    {0x00,0x41,0x36,0x08,0x00},         //   ( 93)  } - 0x007D Right Curly Bracket
 
    {0x02,0x01,0x02,0x04,0x02},         //   ( 94)  ~ - 0x007E Tilde
 
    {0x08,0x14,0x2A,0x14,0x22},         //   ( 95) << - 0x00AB Left-Pointing Double Angle Quotation Mark
 
    {0x00,0x02,0x05,0x02,0x00},         //   ( 96)    - 0x00B0 Degree Sign
 
//    {0x44,0x44,0x5F,0x44,0x44},         //   ( 97) +- - 0x00B1 Plus-Minus Sign
 
//    {0x7E,0x20,0x20,0x10,0x3E},         //   ( 98)  u - 0x00B5 Micro Sign
 
//    {0x22,0x14,0x2A,0x14,0x08},         //   ( 99) >> - 0x00BB Right-Pointing Double Angle Quotation Mark
 
//    {0x30,0x48,0x45,0x40,0x20},         //   (100)  ? - 0x00BF Inverted Question Mark
 
//    {0x22,0x14,0x08,0x14,0x22},         //   (101)  x - 0x00D7 Multiplcation Sign
 
//    {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);
 
 
    setStartPage(2);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[1][i]);
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(1);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[2][i]);
 
    }
 
    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++)
 
    {
 
        uint8_t data = 0;
 
        data |= ((*srcPointer) & 0b1000) << 4; // get top 4 bits
 
        data |= ((*srcPointer) & 0b1000) << 3; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0100) << 3; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0100) << 2; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0010) << 2; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0010) << 1; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0001) << 1; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0001); // get top 4 bits
 
 
        WriteData(data);
 
        WriteData(data);
 
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
 
    srcPointer -= 5;
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    // Write second row
 
    for(uint8_t i = 0; i < 5; i++)
 
    {
 
        uint8_t data = 0;
 
        data |=  (*srcPointer) & 0b10000000; // get top 4 bits
 
        data |= ((*srcPointer) & 0b10000000) >> 1; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b01000000) >> 1; // get top 4 bits
 
        data |= ((*srcPointer) & 0b01000000) >> 2; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b00100000) >> 2; // get top 4 bits
 
        data |= ((*srcPointer) & 0b00100000) >> 3; // get top 4 bits
 
 
        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;
 
        if(*srcPointer == 0) break;
 
    }
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
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;
 
static uint8_t sw_up_last = 0;
 
static uint8_t sw_down_last = 0;
 
static uint8_t sw_left_last = 0;
 
static uint8_t sw_right_last = 0;
 

	
 

	
 
// Buttonpress macros
 
#define SW_BTN_PRESSED (sw_btn_last == 0 && sw_btn == 1) // rising edge on buttonpress
 
#define SW_UP_PRESSED (sw_up_last == 0 && sw_up == 1)
 
#define SW_DOWN_PRESSED (sw_down_last == 0 && sw_down == 1)
 
#define SW_LEFT_PRESSED (sw_left_last == 0 && sw_left == 1)
 
#define SW_RIGHT_PRESSED (sw_right_last == 0 && sw_right == 1)
 

	
 

	
 
// 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);
 

	
 
    switch(status->state)
 
    {
 
        // Idle state
 
        case STATE_IDLE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: idle ]
 
            ssd1306_drawstring("therm :: idle ", 0, 40);
 
            status->pid_enabled = 0;
 

	
 
            if(temp_changed || state_changed) {
 
                char tempstr[6];
 
                itoa_fp(status->temp, status->temp_frac, tempstr);
 
                ssd1306_drawstring("Temp: ", 3, 40);
 
                ssd1306_drawstring("    ", 3, 72);
 
                ssd1306_drawstring(tempstr, 3, 72);
 
            }
 

	
 
            if (state_changed) {
 
            	ssd1306_drawlogo();
 
            }
 

	
 
            switch(goto_mode) {
 

	
 
                case MODE_HEAT:
 
                {
 
                    if(set->val.plant_type == PLANT_HEATER)
 
                        ssd1306_drawstring("-> heat     ", 1, 40);
 
                    else
 
                        ssd1306_drawstring("-> cool     ", 1, 40);
 
                } break;
 

	
 
                case MODE_SETUP:
 
                {
 
                    ssd1306_drawstring("-> setup    ", 1, 40);
src/main.c
Show inline comments
 
//
 
// Therm Firmware
 
// Copyright 2017 Ethan Zonca
 
// Author(s): Ethan Zonca
 
//
 
 
#include "stm32f3xx_hal.h"
 
#include "config.h"
 
 
#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);
 
            }
 
            else
 
            {
 
                ssr_output = 0;
 
            }
 
 
            last_pid = HAL_GetTick();
 
        }
 
 
//        // Kill SSR once the desired on-time has elapsed
 
//        if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_ssr_on > ssr_output || ssr_output <= 0))
 
//        {
 
//            HAL_GPIO_WritePin(SSR_PIN, 0);
 
//            HAL_GPIO_WritePin(LED_POWER, 0);
 
//        }
 
//
 
//
 
//        // Every 200ms, set the SSR on unless output is 0
 
//        if(set.val.control_mode == MODE_PID && HAL_GetTick() - last_ssr_on > SSR_PERIOD)
 
//        {
 
//            // Heat or cool, if we need to
 
//            if(ssr_output > 0)
 
//            {
 
//                HAL_GPIO_WritePin(SSR_PIN, 1);
 
//                HAL_GPIO_WritePin(LED_POWER, 1);
 
//                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)
 
{
 

	
 
  // Convert temperature to fixed point number with 1/10th resolution
 
  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;
 

	
 
  // Calculate instantaneous error
 
  int16_t error = status->setpoint * 10 - temp; // TODO: Use fixed point fraction
 

	
 
  // Proportional component
 
  int32_t p_term = set->val.k_p * error;
 

	
 
  // Error accumulator (integrator)
 
  state->i_state += error;
 

	
 
  // to prevent the iTerm getting huge from lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // 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->val.windup_guard * 10) / set->val.k_i;
 

	
 
  // Calculate integral term with windup guard 
 
  if (state->i_state > windup_guard_res)
 
	  state->i_state = windup_guard_res;
 
  else if (state->i_state < -windup_guard_res)
 
	  state->i_state = -windup_guard_res;
 

	
 
  int32_t i_term = set->val.k_i * state->i_state;
 

	
 
  // Calculate differential term (slope since last iteration)
 
  int32_t d_term = (set->val.k_d * (temp - state->last_pid_temp));
 

	
 
  // Save temperature for next iteration
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;
 
 
	// Erase flash page
 
	HAL_FLASHEx_Erase(&eraser, &errvar);
 
 
	// Write new flash data
 
	uint16_t writectr;
 
	for(writectr = 0; writectr < 128; writectr++)// 128 bytes data
 
	{
 
		HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, eeprom_emulation+writectr,settings.data[writectr]);
 
	}
 
 
	// Write magic value to flash
 
	HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, eeprom_emulation+FLASH_MAGIC_LOC,FLASH_MAGIC_VALUE);
 
 
	// Lock flash memory
 
	HAL_FLASH_Lock();
 
	HAL_Delay(2);
 
}
 
 
 
// Restore configuration from flash memory, if any was previously saved
 
void flash_restoresettings(void)
 
{
 
	// Check for magic flash value
 
	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)