Changeset - 574fd84a2bf8
[Not reviewed]
default
0 19 0
matthewreed - 6 years ago 2018-12-30 14:46:34

Added options for number of setpoints and aux input enable
19 files changed with 244 insertions and 68 deletions:
0 comments (0 inline, 0 general)
.cproject
Show inline comments
 
@@ -17,42 +17,43 @@
 
				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1538442532" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug">
 
					<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1538442532." name="/" resourcePath="">
 
						<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1849706153" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1898847267" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.size" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1803427167" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1920457501" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.321897226" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1782401255" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.407850642" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.485776751" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.1154107227" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1932872609" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.747789546" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.747789546" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" useByScannerDiscovery="true" value="false" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding.1360639253" name="Assume freestanding environment (-ffreestanding)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants.1265121449" name="Disable loop invariant move (-fno-move-loop-invariants)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants" useByScannerDiscovery="true" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto.2018930176" name="Link-time optimizer (-flto)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto" useByScannerDiscovery="true" value="false" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.149408563" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.929516986" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.1562917164" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.392227972" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.2121007191" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1652498155" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.544972784" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1005994348" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.1204092853" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.894265291" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.886060440" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.153446908" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.2133363735" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.737083294" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.448560515" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" value="1287942917" valueType="string"/>
 
							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1641379360" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
 
							<builder buildPath="${workspace_loc:/S3467-MiniBuoy-BT-Sensor-Software}/Debug" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1145700756" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder">
 
								<outputEntries>
 
									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="Debug"/>
 
									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="Release"/>
 
								</outputEntries>
 
							</builder>
 
							<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1885536253" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
 
								<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1335843010" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
 
								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.119815874" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" useByScannerDiscovery="false" valueType="includePath">
 
									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers/CMSIS/Include}&quot;"/>
 
									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
 
@@ -309,25 +310,25 @@
 
			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259" moduleId="org.eclipse.cdt.core.settings" name="Release">
 
				<externalSettings/>
 
				<extensions>
 
					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
 
					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
 
					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
 
					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
 
					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
 
					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
 
				</extensions>
 
			</storageModule>
 
			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
 
				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259" name="Release" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
 
				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259" name="Release" optionalBuildProperties="" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
 
					<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259." name="/" resourcePath="">
 
						<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release.1940851783" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release">
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1030714269" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.size" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.469443515" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1777050695" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.1554193511" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.307845611" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.546843660" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1211709354" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.186907121" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.2061227767" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
 
							<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.2101851135" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" value="true" valueType="boolean"/>
.settings/language.settings.xml
Show inline comments
 
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
<project>
 
	<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1538442532" name="Debug">
 
		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
 
			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 
			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1132583679889893188" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-372386926437939920" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
				<language-scope id="org.eclipse.cdt.core.gcc"/>
 
				<language-scope id="org.eclipse.cdt.core.g++"/>
 
			</provider>
 
		</extension>
 
	</configuration>
 
	<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259" name="Release">
 
		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
 
			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 
			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1087856943379293210" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-352937073990100134" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
				<language-scope id="org.eclipse.cdt.core.gcc"/>
 
				<language-scope id="org.eclipse.cdt.core.g++"/>
 
			</provider>
 
		</extension>
 
	</configuration>
 
</project>
inc/config.h
Show inline comments
 
@@ -14,48 +14,51 @@
 
// USB
 
//////////////////////////////////////////////////////
 
 
// 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
 
 
#define MAX_SETPOINTS 10
 
 
//////////////////////////////////////////////////////
 
// Other settings
 
//////////////////////////////////////////////////////
 
 
// Add bootloader option to top of idle screen menu
 
#define BOOTLOADER_SHORTCUT
 
 
 
//////////////////////////////////////////////////////
 
// Default Settings
 
//////////////////////////////////////////////////////
 
 
//TODO: add defaults for all 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_WINDUP_GUARD 300
 
#define DEFAULT_K_P 100
 
#define DEFAULT_K_I 2
 
#define DEFAULT_K_D 0
 
#define DEFAULT_TEMP_OFFSET 0
 
#define DEFAULT_IGNORE_ERROR 0
 
#define DEFAULT_SETPOINT_BREW 70
 
#define DEFAULT_SETPOINT_STEAM 70
 
#define DEFAULT_SETPOINT 70
 
#define DEFAULT_HYSTERESIS 1
 
#define DEFAULT_SETPOINT_COUNT 1
 
#define DEFAULT_SETPOINT_AUX_SELECT_ENABLE 0
 
 
 
//////////////////////////////////////////////////////
 
// 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))
inc/display.h
Show inline comments
 
#ifndef DISPLAY_H
 
#define DISPLAY_H
 

	
 
#include "states.h"
 
#include "gpio.h"
 
#include "ssd1306/ssd1306.h"
 
#include "system/stringhelpers.h"
 
#include "flash.h"
 
#include "stdlib.h"
 

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

	
 
void display_startup_screen(void);
 
void display_1hz(void);
 
void display_process(void);
 

	
 
#endif
inc/pid.h
Show inline comments
 
#ifndef PIDS_H
 
#define PIDS_H
 

	
 
#include "stm32f3xx_hal.h"
 
#include "states.h"
 
#include "flash.h"
 
#include "display.h"
 

	
 
typedef struct {
 
	int16_t last_pid_temp;
 
	uint8_t last_pid_temp_frac;
 
	int32_t i_state;
 
} pid_state_t;
 

	
 
void pid_init(void);
 
float pid_process(void);
 
int16_t pid_update(void);
 

	
 
#endif
inc/pwmout.h
Show inline comments
 
#ifndef PWMOUT_H
 
#define PWMOUT_H
 

	
 
#include "stm32f3xx_hal.h"
 
#include "gpio.h"
 
#include "flash.h"
 
#include "error.h"
 

	
 
#define SSR_PIN GPIO_PIN_7
 
#define SSR_GPIO_Port GPIOB
 
#define SSR SSR_GPIO_Port, SSR_PIN
 

	
 

	
 

	
 
void pwmout_init(void);
 
void pwmout_process(int16_t duty);
 
TIM_HandleTypeDef* pwmout_get_tim(void);
 

	
 
#endif
inc/states.h
Show inline comments
 
#ifndef STATES_H
 
#define STATES_H
 

	
 
#include "stm32f3xx_hal.h"
 
#include "config.h"
 

	
 
typedef struct {
 
    float temp;
 
    uint8_t state_resume;
 
    uint8_t state;
 
    float setpoint;
 
    int32_t setpoint;
 
    uint8_t pid_enabled;
 
    uint8_t error_code;
 
    uint8_t setpoint_index;
 
} therm_status_t;
 

	
 
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;
 
        int32_t temp_offset; //TODO: convert to float
 
        uint32_t ignore_error;
 
        int32_t setpoint_brew;
 
        int32_t setpoint_steam;
 
        int32_t setpoints[MAX_SETPOINTS];
 
        uint32_t control_mode;
 
        uint32_t sensor_type;
 
        uint32_t plant_type;
 
        uint32_t hysteresis;
 
        uint32_t setpoint_count;
 
        uint32_t setpoint_aux_select_enable;
 
    } val;
 

	
 
    uint16_t data[128];
 
} therm_settings_t;
 

	
 
enum tempunits {
 
    TEMP_UNITS_CELSIUS = 0,
 
    TEMP_UNITS_FAHRENHEIT,
 
};
 

	
 
enum state {
 
    STATE_IDLE = 0,
 

	
 
	STATE_SETSENSORTYPE,
 
    STATE_SETMODE,
 
    STATE_SETPLANTTYPE,
 
    STATE_SETSETPOINTCOUNT,
 
    STATE_SETSETPOINTAUXSELECTENABLE,
 
    STATE_SETHYSTERESIS,
 
    STATE_SETP,
 
    STATE_SETI,
 
    STATE_SETD,
 
    STATE_SETSTEPS,
 
    STATE_SETWINDUP,
 
    STATE_SETBOOTTOBREW,
 
    STATE_SETUNITS,
 
    STATE_SETTEMPOFFSET,
 

	
 
    STATE_PREHEAT,
 
    STATE_MAINTAIN,
 
@@ -64,24 +68,29 @@ enum state {
 
};
 

	
 
enum control_mode {
 
    MODE_PID = 0,
 
    MODE_THERMOSTAT,
 
};
 

	
 
enum plant_type {
 
    PLANT_HEATER = 0,
 
    PLANT_COOLER,
 
};
 

	
 
enum aux_select {
 
    AUX_DISABLE = 0,
 
    AUX_ENABLE,
 
};
 

	
 
enum GOTO_MODE {
 
	#ifdef BOOTLOADER_SHORTCUT
 
	MODE_BOOTLOADER,
 
	#endif
 
	MODE_HEAT,
 
	MODE_SETUP,
 
	MODE_RESET,
 
	MODE_SIZE,
 
};
 

	
 
enum RESET_MODE {
 
	RESET_REBOOT = 0,
inc/system/gpio.h
Show inline comments
 
@@ -26,20 +26,29 @@
 
#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
 
 
#define AUX_INPUT_Pin GPIO_PIN_10
 
#define AUX_INPUT_GPIO_Port GPIOA
 
#define AUX_INPUT AUX_INPUT_GPIO_Port , AUX_INPUT_Pin
 
 
#define AUX_RETURN_Pin GPIO_PIN_9
 
#define AUX_RETURN_GPIO_Port GPIOA
 
#define AUX_RETURN AUX_RETURN_GPIO_Port , AUX_RETURN_Pin
 
 
 
void user_input(uint16_t* to_modify);
 
void user_input_min_max(uint16_t* to_modify, uint16_t min, uint16_t max);
 
void user_input_signed(int32_t* to_modify);
 
 
void gpio_init(void);
 
void gpio_led_blueblink(uint8_t num_blinks);
 
 
#endif
inc/thermostat.h
Show inline comments
 
#ifndef THERMOSTAT_H
 
#define THERMOSTAT_H
 

	
 
#include "stm32f3xx_hal.h"
 
#include "flash.h"
 
#include "gpio.h"
 
#include "stdlib.h"
 
#include "display.h"
 

	
 

	
 
float thermostat_process(void);
 

	
 

	
 
#endif
lib/ssd1306/ssd1306.c
Show inline comments
 
@@ -317,27 +317,27 @@ void ssd1306_drawlogo()
 
    setStartColumn(0);
 
    for(i = 0; i < 32; i++)
 
    {
 
        WriteData(row[3][i]);
 
    }
 
    WriteData(0x00);
 
}
 
 
 
// Print a single character
 
void ssd1306_drawchar(unsigned char ascii, unsigned char row, unsigned char xPos)
 
{
 
    const unsigned char *srcPointer = (char*)-1;
 
    const unsigned char *srcPointer = (unsigned char*)-1;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
    srcPointer = (unsigned char*)&fontData[(ascii-32)][0];
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    for(uint8_t i = 0; i < 5; i++)
 
    {
 
        WriteData(*srcPointer);
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
}
 
 
@@ -398,43 +398,43 @@ void ssd1306_drawcharbig(unsigned char a
 
 
        WriteData(data);
 
        WriteData(data);
 
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
 
}
 
 
 
// Print a string to the display
 
void ssd1306_drawstring(const unsigned char *dataPtr, unsigned char row, unsigned char xPos)
 
void ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    unsigned char *srcPointer;
 
 
    srcPointer = (unsigned 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 unsigned char *dataPtr, unsigned char row, unsigned char xPos)
 
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;
lib/ssd1306/ssd1306.h
Show inline comments
 
@@ -27,20 +27,20 @@
 
#define   SPI_SendByte(data)  HAL_SPI_Transmit(spi_get(), &data, 1, 100)
 
//#define SPI_SendByte(data)
 
#define SPI_Wait()
 
 
//#define   SPI_SendByte(data)  SPI_I2S_SendData(SPI1,data)
 
//#define   SPI_Wait()       while(!(SPI1->SR&SPI_FLAG_TXE));while(SPI1->SR&SPI_FLAG_BSY);
 
 
SPI_HandleTypeDef* spi_get();
 
 
void ssd1306_init(void);
 
void ssd1306_drawchar(unsigned char ascii, unsigned char row, unsigned char xPos);
 
void ssd1306_drawcharbig(unsigned char ascii, unsigned char row, unsigned char xPos);
 
void ssd1306_drawstring(const unsigned char *dataPtr, unsigned char row, unsigned char xPos);
 
void ssd1306_drawstringbig(const unsigned char *dataPtr, unsigned char row, unsigned char xPos);
 
void ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos);
 
void ssd1306_drawstringbig(const char *dataPtr, unsigned char row, unsigned char xPos);
 
void ssd1306_drawlogo();
 
void ssd1306_clearscreen();
 
 
#endif
 
 
// 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 float last_temp = 21245;
 
static int16_t last_state = STATE_RESET;
 
static uint8_t goto_mode = MODE_HEAT;
 
static uint8_t reset_mode = RESET_REBOOT;
 

	
 
static char* sensor_lookup[] = {"NTC", "K  ", "E  ", "N  ", "R  ", "S  ", "T  "};
 

	
 
static uint8_t toggle = 0;
 

	
 
void display_1hz(void)
 
{
 
    toggle = !toggle;
 
}
 

	
 
@@ -63,24 +58,26 @@ void display_process(void)
 
    uint8_t state_changed = status->state != last_state;
 
    last_state = status->state;
 

	
 
    uint8_t temp_changed = status->temp != last_temp;
 
    last_temp = status->temp;
 

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

	
 
    uint8_t aux_input = !HAL_GPIO_ReadPin(AUX_INPUT);
 

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

	
 
            if(temp_changed || state_changed) {
 
                char tempstr[16];
 
@@ -106,67 +103,66 @@ void display_process(void)
 
                } break;
 

	
 
                case MODE_SETUP:
 
                {
 
                    ssd1306_drawstring("\x83 setup    ", 1, 40);
 
                } break;
 

	
 
                case MODE_RESET:
 
                {
 
                    ssd1306_drawstring("\x83 reset    ", 1, 40);
 
                } break;
 

	
 
#ifdef BOOTLOADER_SHORTCUT
 
                #ifdef BOOTLOADER_SHORTCUT
 
                case MODE_BOOTLOADER:
 
                {
 
                    ssd1306_drawstring("\x83 dfu      ", 1, 40);
 
                }
 
#endif
 
                #endif
 
            }
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                switch(goto_mode) {
 
                    case MODE_HEAT:
 
                        status->state = STATE_PREHEAT;
 
                        break;
 
                    case MODE_SETUP:
 
                        status->state = STATE_SETSENSORTYPE;
 
                        break;
 
                    case MODE_RESET:
 
                        status->state = STATE_RESET;
 
                        reset_mode = RESET_REBOOT;
 
                        break;
 
#ifdef BOOTLOADER_SHORTCUT
 
                    #ifdef BOOTLOADER_SHORTCUT
 
                    case MODE_BOOTLOADER:
 
                        ssd1306_clearscreen();
 
                        ssd1306_drawstring("Bootloader Entered", 0, 0);
 
                        ssd1306_drawstring("Device won't boot", 2, 0);
 
                        ssd1306_drawstring("until reflashed!", 3, 0);
 
                        //                        bootloader_enter(); // Resets into bootloader
 
                        status->state = STATE_RESET; // Just in case
 
                        break;
 
#endif
 
                    #endif
 
                    default:
 
                        status->state = STATE_PREHEAT;
 
                }
 
            }
 
            else if(SW_DOWN_PRESSED && goto_mode < (MODE_SIZE - 1)) {
 
                goto_mode++;
 
            }
 
            else if(SW_UP_PRESSED && goto_mode > 0) {
 
                goto_mode--;
 
            }
 

	
 

	
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

	
 

	
 

	
 
        case STATE_SETSENSORTYPE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set mode ]
 
            // [ m =          ]
 
@@ -237,55 +233,132 @@ void display_process(void)
 

	
 
            ssd1306_drawchar(updown(), 1, 52	);
 

	
 
            if(set->val.plant_type == PLANT_HEATER)
 
                ssd1306_drawstring("Heater", 1, 60);
 
            else
 
                ssd1306_drawstring("Cooler", 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                if(set->val.control_mode == MODE_PID)
 
                    status->state = STATE_SETP;
 
                else
 
                    status->state = STATE_SETHYSTERESIS;
 
                status->state = STATE_SETSETPOINTCOUNT;
 
            }
 
            else if (!HAL_GPIO_ReadPin(SW_UP)) {
 
                set->val.plant_type = PLANT_COOLER;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                set->val.plant_type = PLANT_HEATER;
 
            }
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

	
 

	
 
        case STATE_SETSETPOINTCOUNT:
 
        {
 
            // Write text to OLED
 
            // [ therm :: number of setpoints ]
 
            // [ p = 12         ]
 
            ssd1306_drawstring("Num Setpoints", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "%ld ", set->val.setpoint_count);
 
            ssd1306_drawstring(tempstr, 1, 60);
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                if (set->val.setpoint_count > 1)
 
                {
 
                    status->state = STATE_SETSETPOINTAUXSELECTENABLE;
 
                }
 
                else
 
                {
 
                    if(set->val.control_mode == MODE_PID)
 
                        status->state = STATE_SETP;
 
                    else
 
                        status->state = STATE_SETHYSTERESIS;
 
                }
 
            }
 
            else {
 
                user_input_min_max((uint16_t*)&set->val.setpoint_count, 1, MAX_SETPOINTS);
 

	
 
                //update setpoint index to the new maximum
 
                if (status->setpoint_index >= set->val.setpoint_count)
 
                {
 
                    status->setpoint_index = set->val.setpoint_count - 1;
 
                }
 
            }
 

	
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

	
 

	
 
        case STATE_SETSETPOINTAUXSELECTENABLE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set p ]
 
            // [ p = 12         ]
 
            ssd1306_drawstring("Aux Select", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            if(set->val.setpoint_aux_select_enable == AUX_ENABLE)
 
                ssd1306_drawstring("Enable ", 1, 60);
 
            else
 
                ssd1306_drawstring("Disable", 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                if(set->val.control_mode == MODE_PID)
 
                    status->state = STATE_SETP;
 
                else
 
                    status->state = STATE_SETHYSTERESIS;
 
            }
 
            else if (!HAL_GPIO_ReadPin(SW_UP)) {
 
                set->val.setpoint_aux_select_enable = AUX_ENABLE;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                set->val.setpoint_aux_select_enable = AUX_DISABLE;
 
            }
 

	
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

	
 

	
 
        case STATE_SETP:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set p ]
 
            // [ p = 12         ]
 
            ssd1306_drawstring("Proportional", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "P=%d", set->val.k_p);
 
            snprintf(tempstr, 12, "P=%ld", set->val.k_p);
 
            ssd1306_drawstring(tempstr, 1, 60);
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETI;
 
            }
 
            else {
 
                user_input((uint16_t*)&set->val.k_p);
 
            }
 

	
 
            // Event Handler
 
@@ -295,25 +368,25 @@ void display_process(void)
 

	
 
        case STATE_SETI:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set i ]
 
            // [ i = 12         ]
 
            ssd1306_drawstring("Integral", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "I=%d", set->val.k_i);
 
            snprintf(tempstr, 12, "I=%ld", set->val.k_i);
 
            ssd1306_drawstring(tempstr, 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETD;
 
            }
 
            else {
 
                user_input((uint16_t*)&set->val.k_i);
 
            }
 

	
 
@@ -324,25 +397,25 @@ void display_process(void)
 

	
 
        case STATE_SETD:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set d ]
 
            // [ d = 12         ]
 
            ssd1306_drawstring("Derivative", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "D=%d", set->val.k_d);
 
            snprintf(tempstr, 12, "D=%ld", set->val.k_d);
 
            ssd1306_drawstring(tempstr, 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETWINDUP;
 
            }
 
            else {
 
                user_input((uint16_t*)&set->val.k_d);
 
            }
 

	
 
@@ -353,25 +426,25 @@ void display_process(void)
 

	
 

	
 

	
 
        case STATE_SETHYSTERESIS:
 
        {
 
            // Write text to OLED
 
            ssd1306_drawstring("Hysteresis", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "H=%d", set->val.hysteresis);
 
            snprintf(tempstr, 12, "H=%ld", set->val.hysteresis);
 
            ssd1306_drawstring(tempstr, 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETBOOTTOBREW;
 
            }
 
            else {
 
                user_input((uint16_t*)&set->val.hysteresis);
 
            }
 

	
 
@@ -383,25 +456,25 @@ void display_process(void)
 

	
 
        case STATE_SETWINDUP:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set windup ]
 
            // [ g = 12         ]
 
            ssd1306_drawstring("Windup Guard", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "G=%d", set->val.windup_guard);
 
            snprintf(tempstr, 12, "G=%ld", set->val.windup_guard);
 
            ssd1306_drawstring(tempstr, 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETBOOTTOBREW;
 
            }
 
            else {
 
                user_input((uint16_t*)&set->val.windup_guard);
 
            }
 

	
 
@@ -481,25 +554,25 @@ void display_process(void)
 

	
 
        case STATE_SETTEMPOFFSET:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set temp offset ]
 
            // [ g = 12         ]
 
            ssd1306_drawstring("Temp Cal Offset", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_drawchar(updown(), 1, 52);
 

	
 
            char tempstr[12];
 
            snprintf(tempstr, 12, "O=%d", set->val.temp_offset);
 
            snprintf(tempstr, 12, "O=%ld", set->val.temp_offset);
 
            ssd1306_drawstring(tempstr, 1, 60);
 

	
 
            ssd1306_drawstring("Press to accept", 3, 40);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                flash_savesettings();
 
                status->state = STATE_IDLE;
 
            }
 
            else {
 
                user_input_signed(&set->val.temp_offset);
 
            }
 
@@ -515,64 +588,101 @@ void display_process(void)
 
            // Write text to OLED
 
            // [ therm : preheating brew ]
 
            // [ 30 => 120 C             ]
 
            if(set->val.plant_type == PLANT_HEATER)
 
                ssd1306_drawstring("Preheating...", 0, 0);
 
            else
 
                ssd1306_drawstring("Precooling...", 0, 0);
 

	
 
            //ssd1306_drawlogo();
 
            draw_setpoint(status);
 

	
 
            status->pid_enabled = 1;
 
            status->setpoint = set->val.setpoint_brew;
 
            status->setpoint = set->val.setpoints[status->setpoint_index];
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_IDLE;
 
                flash_savesettings();
 
            }
 
            else if (!(set->val.setpoint_aux_select_enable) && SW_LEFT_PRESSED)
 
            {
 
                if (status->setpoint_index > 0)
 
                {
 
                    status->setpoint_index--;
 
                }
 
            }
 
            else if (!(set->val.setpoint_aux_select_enable) && SW_RIGHT_PRESSED)
 
            {
 
                if (status->setpoint_index < (set->val.setpoint_count - 1))
 
                {
 
                    status->setpoint_index++;
 
                }
 
            }
 
            else {
 
                user_input_signed(&set->val.setpoint_brew);
 
                user_input_signed(&set->val.setpoints[status->setpoint_index]);
 
            }
 

	
 
            // Event Handler
 
            if(status->temp >= status->setpoint) {
 
                status->state = STATE_MAINTAIN;
 
            }
 

	
 
            if(set->val.setpoint_aux_select_enable && aux_input)
 
            {
 
                status->setpoint_index = 1;
 
            }
 
            else if(set->val.setpoint_aux_select_enable && !aux_input)
 
            {
 
                status->setpoint_index = 0;
 
            }
 

	
 
        } break;
 

	
 
        case STATE_MAINTAIN:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to brew ]
 
            // [ 30 => 120 C           ]
 

	
 
            if(set->val.plant_type == PLANT_HEATER)
 
                ssd1306_drawstring("Preheated!", 0, 0);
 
            else
 
                ssd1306_drawstring("Precooled!", 0, 0);
 

	
 
            draw_setpoint(status);
 
            status->pid_enabled = 1;
 
            status->setpoint = set->val.setpoint_brew;
 
            status->setpoint = set->val.setpoints[status->setpoint_index];
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_IDLE;
 
                flash_savesettings();
 
            }
 
            else if (!(set->val.setpoint_aux_select_enable) && SW_LEFT_PRESSED)
 
            {
 
                if (status->setpoint_index > 0)
 
                {
 
                    status->setpoint_index--;
 
                }
 
            }
 
            else if (!(set->val.setpoint_aux_select_enable) && SW_RIGHT_PRESSED)
 
            {
 
                if (status->setpoint_index < (set->val.setpoint_count - 1))
 
                {
 
                    status->setpoint_index++;
 
                }
 
            }
 
            else {
 
                user_input_signed(&set->val.setpoint_brew);
 
                user_input_signed(&set->val.setpoints[status->setpoint_index]);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

	
 
        // Thermocouple error
 
        case STATE_TC_ERROR:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to steam ]
 
@@ -592,27 +702,27 @@ void display_process(void)
 
            else if(status->error_code == 8)
 
                ssd1306_drawstring("    TC Short to VCC", 1, 0);
 
            else
 
                ssd1306_drawstring("#?, Unknown Error", 1, 0);
 
            ssd1306_drawstring("                    ", 2, 0);
 

	
 
            ssd1306_drawstring("-> to ignore all or", 2, 0);
 
            ssd1306_drawstring("press to continue", 3, 0);
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_IDLE;
 
#ifdef MAX31865_RTD_SENSOR
 
                #ifdef MAX31865_RTD_SENSOR
 
                max31865_clear_errors(spi_get());
 
#endif
 
                #endif
 
            }
 
            else if(SW_RIGHT_PRESSED) {
 
                set->val.ignore_error = 1;
 
                status->state = STATE_IDLE;
 
            }
 
            // Event Handler
 
            // Maybe handle if TC is plugged in
 
            // N/A
 

	
 
        } break;
 

	
 

	
 
@@ -723,25 +833,25 @@ static void draw_setpoint(therm_status_t
 
    // FIXME: need to do this when switching modes too
 
    if(status->temp != temp_last || trigger_drawsetpoint) {
 
        char tempstr[8];
 
        snprintf(tempstr, 8, "%4.1f", status->temp);
 
        ssd1306_drawstringbig(tempstr, 3, 0);
 
    }
 

	
 
    if(trigger_drawsetpoint) 
 
        ssd1306_drawstringbig(">", 3, 74);
 

	
 
    if(status->setpoint != setpoint_last || trigger_drawsetpoint) {
 
        char tempstr[4];
 
        snprintf(tempstr, 4, "%g     ", status->setpoint);
 
        snprintf(tempstr, 4, "%ld     ", status->setpoint);
 
        ssd1306_drawstringbig(tempstr, 3, 90);
 
    }
 

	
 
    trigger_drawsetpoint = 0;
 
    setpoint_last = status->setpoint;
 
    temp_last = status->temp;
 
}
 

	
 
void display_startup_screen() {
 
    ssd1306_clearscreen();
 
    ssd1306_drawstring("therm v0.4", 1, 40);
 
    ssd1306_drawstring("protofusion.org/therm", 3, 0);
src/main.c
Show inline comments
 
//
 
// Therm Firmware
 
// Copyright 2018 Ethan Zonca
 
// Author(s): Ethan Zonca
 
// Author(s): Ethan Zonca and Matthew Reed
 
//
 
 
#include "stm32f3xx_hal.h"
 
#include "config.h"
 
#include "watchdog.h"
 
#include "system.h"
 
#include "display.h"
 
#include "thermostat.h"
 
#include "gpio.h"
 
#include "tempsense.h"
 
#include "pid.h"
 
#include "error.h"
 
#include "flash.h"
 
#include "ssd1306/ssd1306.h"
 
#include "pwmout.h"
 
 
 
int main(void)
 
{
 
    sysclock_init();
 
    hal_init();
 
    gpio_init();
 
    flash_init();
 
 
    ssd1306_init();
 
 
    // Startup screen
 
    display_startup_screen();
 
    HAL_Delay(2000);
 
    ssd1306_clearscreen();
 
    ssd1306_drawlogo();
 
    //ssd1306_drawlogo();
 
 
    // Default status
 
    runtime_status()->temp = 0.0;
 
    runtime_status()->state_resume = 0;
 
    runtime_status()->state = STATE_IDLE;
 
    runtime_status()->setpoint = 70;
 
    runtime_status()->pid_enabled = 0;
 
    runtime_status()->setpoint_index = 0;
 
    if (flash_getsettings()->val.boottobrew)
 
    {
 
        runtime_status()->state = STATE_PREHEAT;
 
    }
 
    else
 
    {
 
        runtime_status()->state = STATE_IDLE;
 
    }
 
 
    pid_init();
 
    pwmout_init();
 
    flash_init();
 
    watchdog_init();
 
    tempsense_init();
 
 
    // Soft timers
 
    uint32_t last_pid = 0;
 
    uint32_t last_thermostat = 0;
 
    uint32_t last_1hz = 0;
 
    uint32_t last_5hz = 0;
src/pid.c
Show inline comments
 
//
 
// PID: proportional/integral/derivative controller
 
//
 

	
 
#include "pid.h"
 
#include "flash.h"
 

	
 
// Private variables
 
static pid_state_t state;
 

	
 

	
 
// Initialize PID loop
 
void pid_init()
 
{
 
    state.i_state = 0;
 
    state.last_pid_temp = 0;
 
    state.last_pid_temp_frac = 0;
 
}
 
@@ -33,35 +32,37 @@ float pid_process(void)
 
    if(runtime_status()->pid_enabled)
 
    {
 
        // Get ssr output for next time
 
        int16_t power_percent = pid_update();
 

	
 
        if(flash_getsettings()->val.plant_type == PLANT_COOLER)
 
            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
 
        //TODO: move to display
 
        ssd1306_drawstring("      ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
 
        char tempstr[8];
 
        snprintf(tempstr, 8, "%4.1f%%", ssr_output/10.0);
 
        ssd1306_drawstring(tempstr, 0, 85);
 
    }
 
    else
 
    {
 
        ssr_output = 0.0;
 
    }
 

	
 
    return ssr_output; //ssr_output;
 
    return ssr_output; //ssr_output;=== START OF INFORMATION SECTION ===
 

	
 
}
 

	
 

	
 
// Calculate new PID values
 
int16_t pid_update(void)
 
{
 
    therm_status_t* status = runtime_status();
 
    therm_settings_t* set = flash_getsettings();
 

	
 
    // Convert temperature to fixed point number with 1/10th resolution
 
    float temp = status->temp;
 

	
src/pwmout.c
Show inline comments
 
//
 
// PWM Out: generate PWM waveform to control factory
 
//
 

	
 
#include "stm32f3xx_hal.h"
 
#include "pwmout.h"
 
#include "gpio.h"
 
#include "flash.h"
 
#include "error.h"
 

	
 

	
 
// Private variables
 
static TIM_HandleTypeDef htim17;
 
static uint32_t last_ssr_on = 0;
 

	
 

	
 
// Initialize hardware PWM output
 
void pwmout_init(void)
 
{
 
    GPIO_InitTypeDef GPIO_InitStruct;
 
    __HAL_RCC_TIM17_CLK_ENABLE();
src/system/flash.c
Show inline comments
 
@@ -33,58 +33,59 @@ void flash_savesettings()
 
            .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]);
 
        HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)(eeprom_emulation+writectr), settings.data[writectr]);
 
    }
 
 
    // Write magic value to flash
 
    HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, eeprom_emulation+FLASH_MAGIC_LOC,FLASH_MAGIC_VALUE);
 
    HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, (uint32_t)(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
 
    //TODO: Set all defaults
 
    else
 
    {
 
        settings.val.k_p = 100;
 
        settings.val.k_i = 2;
 
        settings.val.k_d = 0;
 
        settings.val.windup_guard = 300;
 
        settings.val.k_p = DEFAULT_K_P;
 
        settings.val.k_i = DEFAULT_K_I;
 
        settings.val.k_d = DEFAULT_K_D;
 
        settings.val.windup_guard = DEFAULT_WINDUP_GUARD;
 
        settings.val.sensor_type = 1;
 
        //torestore.values.can_id = 22;
 
        settings.val.setpoint_count = DEFAULT_SETPOINT_COUNT;
 
    }
 
}
 
 
 
// Accessor to retrieve settings structure
 
inline therm_settings_t* flash_getsettings(void)
 
{
 
    return &settings;
 
}
 
 
inline therm_status_t* runtime_status(void)
 
{
src/system/gpio.c
Show inline comments
 
@@ -21,63 +21,85 @@ void gpio_init(void)
 
    __GPIOB_CLK_ENABLE();
 
    __GPIOF_CLK_ENABLE();
 
 
 
    // Configure LED GPIO pins
 
    GPIO_InitStruct.Pin = LED_PIN;
 
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 
    HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
 
 
    GPIO_InitStruct.Pin = SW_A_Pin|SW_B_Pin|SW_C_Pin|SW_D_Pin;
 
    GPIO_InitStruct.Pin = SW_A_Pin|SW_B_Pin|SW_C_Pin|SW_D_Pin|AUX_INPUT_Pin;
 
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 
    GPIO_InitStruct.Pull = GPIO_PULLUP;
 
    HAL_GPIO_Init(SW_C_GPIO_Port, &GPIO_InitStruct);
 
 
    GPIO_InitStruct.Pin = AUX_RETURN_Pin;
 
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
    HAL_GPIO_Init(AUX_RETURN_GPIO_Port, &GPIO_InitStruct);
 
 
    GPIO_InitStruct.Pin = SW_BTN_Pin;
 
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 
    GPIO_InitStruct.Pull = GPIO_PULLUP;
 
    HAL_GPIO_Init(SW_BTN_GPIO_Port, &GPIO_InitStruct);
 
 
 
    /* EXTI interrupt init*/
 
    HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
 
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
 
 
    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
 
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
 
 
    // Define startup State
 
    HAL_GPIO_WritePin(LED, 0);
 
    HAL_GPIO_WritePin(AUX_RETURN, 0);
 
 
}
 
 
 
// Increment/decrement unsigned variable with up/down buttons
 
void user_input(uint16_t* to_modify)
 
{
 
    if(CHANGE_ELAPSED) {
 
        if(!HAL_GPIO_ReadPin(SW_UP) ) {
 
            CHANGE_RESET;
 
            (*to_modify)++;
 
        }
 
        else if(!HAL_GPIO_ReadPin(SW_DOWN) && (*to_modify) > 0) {
 
            CHANGE_RESET;
 
            (*to_modify)--;
 
        }
 
    }
 
}
 
 
// Increment/decrement unsigned variable with up/down buttons
 
void user_input_min_max(uint16_t* to_modify, uint16_t min, uint16_t max)
 
{
 
    if(CHANGE_ELAPSED) {
 
        if(!HAL_GPIO_ReadPin(SW_UP) && ((*to_modify) < max))
 
        {
 
            CHANGE_RESET;
 
            (*to_modify)++;
 
        }
 
        else if(!HAL_GPIO_ReadPin(SW_DOWN) && ((*to_modify) > min))
 
        {
 
            CHANGE_RESET;
 
            (*to_modify)--;
 
        }
 
    }
 
}
 
 
 
// Increment/decrement signed variable with up/down buttons
 
void user_input_signed(int32_t* to_modify)
 
{
 
    //fixme: need to cast to 16/32 bits correctly
 
    if(CHANGE_ELAPSED) {
 
        if(!HAL_GPIO_ReadPin(SW_UP) ) {
 
            CHANGE_RESET;
 
            if (*to_modify < 32768)
 
                (*to_modify)++;
 
        }
 
        else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
src/system/interrupts.c
Show inline comments
 
@@ -13,29 +13,31 @@
 
// Systick interrupt
 
void SysTick_Handler(void)
 
{
 
    HAL_IncTick();
 
    HAL_SYSTICK_IRQHandler();
 
}
 
 
void EXTI9_5_IRQHandler(void)
 
{
 
    HAL_GPIO_EXTI_IRQHandler(SW_B_Pin);
 
    HAL_GPIO_EXTI_IRQHandler(SW_A_Pin);
 
    HAL_GPIO_EXTI_IRQHandler(SW_C_Pin);
 
    HAL_GPIO_EXTI_IRQHandler(AUX_RETURN_Pin);
 
}
 
 
void EXTI15_10_IRQHandler(void)
 
{
 
    HAL_GPIO_EXTI_IRQHandler(SW_BTN_Pin);
 
    HAL_GPIO_EXTI_IRQHandler(AUX_INPUT_Pin);
 
}
 
 
uint32_t last_button_press = 0;
 
 
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 
{
 
    switch(GPIO_Pin)
 
    {
 
        case SW_BTN_Pin:
 
        {
 
            //			if(HAL_GetTick() > last_button_press + 100)
 
            //			{
src/thermostat.c
Show inline comments
 
//
 
// Thermostat: Thermostatic controller
 
//
 

	
 
#include "thermostat.h"
 
#include "flash.h"
 
#include "gpio.h"
 

	
 
// PID implementation
 

	
 
float thermostat_process(void)
 
{
 

	
 
    //            #ifdef MAX31865_RTD_SENSOR
 
    //            max31865_readtemp(spi_get(), &set, &status);
 
    //			#else
 
    //			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
 
    //			#endif
 

	
0 comments (0 inline, 0 general)