Changeset - 0dfb00c8792b
[Not reviewed]
cortex-f0
8 3 7
Ethan Zonca - 9 years ago 2015-11-28 14:17:04
ez@ethanzonca.com
Reorganize, remove unneeded stuff
16 files changed with 671 insertions and 744 deletions:
0 comments (0 inline, 0 general)
Makefile
Show inline comments
 
# STM32F0xx Makefile
 
# #####################################
 
#
 
# Part of the uCtools project
 
# uctools.github.com
 
#
 
#######################################
 
# user configuration:
 
#######################################
 

	
 

	
 
# SOURCES: list of sources in the user application
 
SOURCES = main.c system/usbd_conf.c system/usbd_cdc_if.c system/usb_device.c system/usbd_desc.c system/interrupts.c system/system_stm32f0xx.c gpio.c spi.c ssd1306.c stringhelpers.c display.c system/syslib.c storage.c flash.c max31855.c max31865.c pid.c
 
SOURCES = main.c gpio.c ssd1306.c display.c flash.c max31855.c max31865.c pid.c
 
SOURCES += system/usbd_conf.c system/usbd_cdc_if.c system/usb_device.c system/usbd_desc.c system/spi.c system/interrupts.c system/system_stm32f0xx.c system/stringhelpers.c system/syslib.c 
 
#SRC = $(shell find . -name *.c)
 

	
 
# TARGET: name of the user application
 
TARGET = main
 

	
 
# BUILD_DIR: directory to place output files in
 
BUILD_DIR = build
 

	
 
# LD_SCRIPT: location of the linker script
 
LD_SCRIPT = stm32f042c6_flash.ld
 

	
 
# USER_DEFS user defined macros
 
USER_DEFS = -D HSI48_VALUE=48000000 -D HSE_VALUE=16000000
 
# USER_INCLUDES: user defined includes
 
USER_INCLUDES = -Isystem
 

	
 
# USB_INCLUDES: includes for the usb library
 
USB_INCLUDES = -Imiddlewares/ST/STM32_USB_Device_Library/Core/Inc
 
USB_INCLUDES += -Imiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
 

	
 
# USER_CFLAGS: user C flags (enable warnings, enable debug info)
 
USER_CFLAGS = -Wall -g -ffunction-sections -fno-exceptions -fdata-sections -Os
 
# USER_LDFLAGS:  user LD flags
 
USER_LDFLAGS = -fno-exceptions -ffunction-sections -fno-exceptions -fdata-sections -Wl,--gc-sections
 

	
 
# TARGET_DEVICE: device to compile for
 
TARGET_DEVICE = STM32F042x6
 

	
 
#######################################
 
# end of user configuration
 
#######################################
 
#
 
#######################################
 
# binaries
 
#######################################
 
CC = arm-none-eabi-gcc
 
AR = arm-none-eabi-ar
 
RANLIB = arm-none-eabi-ranlib
 
SIZE = arm-none-eabi-size
 
OBJCOPY = arm-none-eabi-objcopy
 
MKDIR = mkdir -p
 
#######################################
 

	
 
# core and CPU type for Cortex M0
 
# ARM core type (CORE_M0, CORE_M3)
 
CORE = CORE_M0
 
# ARM CPU type (cortex-m0, cortex-m3)
 
CPU = cortex-m0
 

	
 
# where to build STM32Cube
 
CUBELIB_BUILD_DIR = $(BUILD_DIR)/STM32Cube
 

	
 
# various paths within the STmicro library
 
CMSIS_PATH = drivers/CMSIS
 
CMSIS_DEVICE_PATH = $(CMSIS_PATH)/Device/ST/STM32F0xx
 
DRIVER_PATH = drivers/STM32F0xx_HAL_Driver
 

	
 
# includes for gcc
 
INCLUDES = -I$(CMSIS_PATH)/Include
 
INCLUDES += -I$(CMSIS_DEVICE_PATH)/Include
 
INCLUDES += -I$(DRIVER_PATH)/Inc
 
INCLUDES += -I$(CURDIR)
 
INCLUDES += -I$(CURDIR)/usb
 
INCLUDES += $(USB_INCLUDES)
 
INCLUDES += $(USER_INCLUDES)
 

	
 
# macros for gcc
 
DEFS = -D$(CORE) $(USER_DEFS) -D$(TARGET_DEVICE)
 

	
 
# compile gcc flags
 
CFLAGS = $(DEFS) $(INCLUDES)
 
CFLAGS += -mcpu=$(CPU) -mthumb
 
CFLAGS += $(USER_CFLAGS)
 

	
 
# default action: build the user application
 
all: $(BUILD_DIR)/$(TARGET).hex
 

	
 
#######################################
 
# build the st micro peripherial library
 
# (drivers and CMSIS)
 
#######################################
 

	
 
CUBELIB = $(CUBELIB_BUILD_DIR)/libstm32cube.a
 

	
 
# List of stm32 driver objects
 
CUBELIB_DRIVER_OBJS = $(addprefix $(CUBELIB_BUILD_DIR)/, $(patsubst %.c, %.o, $(notdir $(wildcard $(DRIVER_PATH)/Src/*.c))))
 

	
 
# shortcut for building core library (make cubelib)
 
cubelib: $(CUBELIB)
 

	
 
$(CUBELIB): $(CUBELIB_DRIVER_OBJS)
 
	$(AR) rv $@ $(CUBELIB_DRIVER_OBJS)
 
	$(RANLIB) $@
 

	
 
$(CUBELIB_BUILD_DIR)/%.o: $(DRIVER_PATH)/Src/%.c | $(CUBELIB_BUILD_DIR)
 
	$(CC) -c $(CFLAGS) -o $@ $^
 

	
 
$(CUBELIB_BUILD_DIR):
 
	$(MKDIR) $@
 

	
 
#######################################
 
# build the USB library
 
#######################################
 
USB_MIDDLEWARE_PATH = ./middlewares/ST/STM32_USB_Device_Library/
 
USB_BUILD_DIR = $(BUILD_DIR)/usb
 
USB_SOURCES += usbd_ctlreq.c usbd_ioreq.c usbd_core.c usbd_cdc.c
 
# list of usb library objects
 
USB_OBJECTS += $(addprefix $(USB_BUILD_DIR)/,$(notdir $(USB_SOURCES:.c=.o)))
 

	
 
usb: $(USB_OBJECTS)
 

	
 
$(USB_BUILD_DIR)/%.o: $(USB_MIDDLEWARE_PATH)/Core/Src/%.c | $(USB_BUILD_DIR)
 
	$(CC) -Os $(CFLAGS) -c -o $@ $^
 

	
 
$(USB_BUILD_DIR)/%.o: $(USB_MIDDLEWARE_PATH)/Class/CDC/Src/%.c | $(USB_BUILD_DIR)
 
	$(CC) -Os $(CFLAGS) -c -o $@ $^
 

	
 
$(USB_BUILD_DIR):
 
	@echo $(USB_BUILD_DIR)
 
	$(MKDIR) $@
 

	
 
#######################################
 
# build the user application
 
#######################################
 

	
 
SYSTEM_BUILD_DIR = $(BUILD_DIR)/system
 

	
 
# list of user program objects
 
#OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES:.c=.o)))
 
OBJECTS = $(addprefix $(BUILD_DIR)/,$(SOURCES:.c=.o))
 
# add an object for the startup code
 
OBJECTS += $(BUILD_DIR)/system/startup_stm32f042x6.o
 

	
 
# use the periphlib core library, plus generic ones (libc, libm, libnosys)
 
LIBS = -lstm32cube -lc -lm -lnosys
 
LDFLAGS = -T $(LD_SCRIPT) -L $(CUBELIB_BUILD_DIR) $(LIBS) $(USER_LDFLAGS)
 

	
 
$(BUILD_DIR)/$(TARGET).hex: $(BUILD_DIR)/$(TARGET).elf | $(SYSTEM_BUILD_DIR)
 
	$(OBJCOPY) -O ihex $(BUILD_DIR)/$(TARGET).elf $@
 
	$(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin
 

	
 
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) $(USB_OBJECTS) $(CUBELIB) | $(SYSTEM_BUILD_DIR)
 
	$(CC) -o $@ $(CFLAGS) $(USER_LDFLAGS) $(OBJECTS) $(USB_OBJECTS) \
 
		-L$(CUBELIB_BUILD_DIR) -static $(LIBS) -Xlinker \
 
		-Map=$(BUILD_DIR)/$(TARGET).map \
 
		-T $(LD_SCRIPT)
 
	$(SIZE) $@
 

	
 
$(SYSTEM_BUILD_DIR):
 
	@echo $(SYSTEM_BUILD_DIR)
 
	$(MKDIR) $@
 

	
 
$(BUILD_DIR)/%.o: %.c | $(BUILD_DIR) $(SYSTEM_BUILD_DIR)
 
	$(CC) $(CFLAGS) -Os -c -o $@ $^
 

	
 
$(BUILD_DIR)/%.o: %.s | $(BUILD_DIR) $(SYSTEM_BUILD_DIR)
 
	$(CC) $(CFLAGS) -c -o $@ $^
 

	
 
$(BUILD_DIR):
 
	$(MKDIR) $@
 

	
 
# delete all user application files, keep the libraries
 
clean:
 
		-rm $(BUILD_DIR)/*.o
 
		-rm $(BUILD_DIR)/*.elf
 
		-rm $(BUILD_DIR)/*.bin
 
		-rm $(BUILD_DIR)/*.map
 

	
 
.PHONY: clean all cubelib
display.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
#include "ssd1306.h"
 
#include "stringhelpers.h"
 
#include "display.h"
 
#include "config.h"
 
#include "states.h"
 
#include "syslib.h"
 
#include "flash.h"
 
#include "gpio.h"
 

	
 
static uint8_t goto_mode = 2;
 

	
 
// State machine
 
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;
 

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

	
 

	
 
static uint8_t trigger_drawsetpoint = 1;
 

	
 
static int16_t last_temp = 21245;
 

	
 
void display_process(therm_settings_t* set, therm_status_t* status)
 
{
 
    uint8_t 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);
 

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

	
 
            ssd1306_drawlogo();
 

	
 
            switch(goto_mode) {
 
                case 3:
 
                {
 
                    ssd1306_DrawString("-> loader   ", 1, 40);
 
                } break;
 

	
 
                case 2:
 
                {
 
                    ssd1306_DrawString("-> heat     ", 1, 40);
 
                } break;
 

	
 
                case 1:
 
                {
 
                    ssd1306_DrawString("-> setup    ", 1, 40);
 
                } break;
 

	
 
                case 0:
 
                {
 
                    ssd1306_DrawString("-> reset    ", 1, 40);
 
                }
 
            }
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                switch(goto_mode) {
 
                    case 3:
 
                    {
 
                        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_IDLE; // Just in case
 
                    } break;
 
                    case 2:
 
                        status->state = STATE_PREHEAT_BREW;
 
                        break;
 
                    case 1:
 
                        status->state = STATE_SETP;
 
                        break;
 
                    case 0:
 
                        status->state = STATE_IDLE;
 
                        //flash_erase();
 
                        NVIC_SystemReset(); 
 
                        break;
 

	
 
                    default:
 
                        status->state = STATE_PREHEAT_BREW;
 
                }
 
            }
 
            else if(SW_UP_PRESSED && goto_mode < 3) {
 
                goto_mode++;
 
            }
 
            else if(SW_DOWN_PRESSED && goto_mode > 0) {
 
                goto_mode--;
 
            }
 

	
 

	
 
            // Event Handler
 
            // N/A
 

	
 
        } break;
 

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

	
 
            char tempstr[6];
 
            itoa(set->val.k_p, tempstr, 10);
 
            ssd1306_DrawString("P=", 1, 45);
 
            ssd1306_DrawString("    ", 1, 57);
 
            ssd1306_DrawString(tempstr, 1, 57);
 

	
 
            ssd1306_DrawString("Press to accept", 3, 40);
 
            
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETI;
 
            }
 
            else {
 
                user_input(&set->val.k_p);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

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

	
 
            char tempstr[6];
 
            itoa(set->val.k_i, tempstr, 10);
 
            ssd1306_DrawString("I=", 1, 45);
 
            ssd1306_DrawString("    ", 1, 57);
 
            ssd1306_DrawString(tempstr, 1, 57);
 

	
 
            ssd1306_DrawString("Press to accept", 3, 40);
 
            
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETD;
 
            }
 
            else {
 
                user_input(&set->val.k_i);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

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

	
 
            char tempstr[6];
 
            itoa(set->val.k_d, tempstr, 10);
 
            ssd1306_DrawString("D=", 1, 45);
 
            ssd1306_DrawString("    ", 1, 57);
 
            ssd1306_DrawString(tempstr, 1, 57);
 

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

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

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

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

	
 
            char tempstr[6];
 
            itoa(set->val.windup_guard, tempstr, 10);
 
            ssd1306_DrawString("G=", 1, 45);
 
            ssd1306_DrawString("    ", 1, 57);
 
            ssd1306_DrawString(tempstr, 1, 57);
 

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

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

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 
        case STATE_SETBOOTTOBREW:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set windup ]
 
            // [ g = 12         ]
 
            ssd1306_DrawString("Start on Boot", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            ssd1306_DrawString("sob=", 1, 45);
 
            
 
            if(set->val.boottobrew)
 
                ssd1306_DrawString("Enabled ", 1, 70);
 
            else
 
                ssd1306_DrawString("Disabled", 1, 70);
 

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

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETUNITS;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_UP)) {
 
                set->val.boottobrew = 1;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                set->val.boottobrew = 0;
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 
        case STATE_SETUNITS:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set windup ]
 
            // [ g = 12         ]
 
            ssd1306_DrawString("Units: ", 0, 40);
 
            ssd1306_drawlogo();
 

	
 
            if(set->val.temp_units == TEMP_UNITS_FAHRENHEIT)
 
                ssd1306_DrawString("Fahrenheit", 1, 60);
 
            else
 
                ssd1306_DrawString("Celsius   ", 1, 60);
 

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

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_SETTEMPOFFSET;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_UP)) {
 
                set->val.temp_units = TEMP_UNITS_FAHRENHEIT;
 
            }
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                set->val.temp_units = TEMP_UNITS_CELSIUS;
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 

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

	
 
            char tempstr[6];
 
            itoa(set->val.temp_offset, tempstr, 10);
 
            ssd1306_DrawString("O=", 1, 45);
 
            ssd1306_DrawString("    ", 1, 57);
 
            ssd1306_DrawString(tempstr, 1, 57);
 

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

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                flash_save(&set);
 
                status->state = STATE_IDLE;
 
            }
 
            else {
 
                user_input_signed(&set->val.temp_offset);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 

	
 
        case STATE_PREHEAT_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating brew ]
 
            // [ 30 => 120 C             ]
 
            ssd1306_DrawString("Preheating...", 0, 0);
 
            //ssd1306_drawlogo();
 
            draw_setpoint(status);
 

	
 
            status->pid_enabled = 1;
 
	    status->setpoint = set->val.setpoint_brew;
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
		save_setpoints(&set); // TODO: Check for mod
 
                status->state = STATE_IDLE;
 
            }
 
            else {
 
                user_input(&set->val.setpoint_brew);
 
            }
 

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

	
 
        case STATE_MAINTAIN_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to brew ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("Preheated!", 0, 0);
 
            //ssd1306_drawlogo();
 
            draw_setpoint(status);
 
            status->pid_enabled = 1;
 
	    status->setpoint = set->val.setpoint_brew;
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
		save_setpoints(&set); // TODO: Check for mod
 
                status->state = STATE_IDLE;
 
            }
 
            else {
 
                user_input(&set->val.setpoint_brew);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 
        case STATE_PREHEAT_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating steam ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("Preheating...", 0, 0);
 
            //ssd1306_drawlogo();
 
            draw_setpoint(status);
 
            status->pid_enabled = 1;
 
	    status->setpoint = set->val.setpoint_steam;
 
	    
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_IDLE;
 
		save_setpoints(&set); // TODO: Check for mod
 
            }
 
            else {
 
                user_input(&set->val.setpoint_steam);
 
            }
 

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

	
 
        case STATE_MAINTAIN_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to steam ]
 
            // [ 30 => 120 C            ]
 
            ssd1306_DrawString("Ready to Steam!", 0, 0);
 
            //ssd1306_drawlogo();
 
            draw_setpoint(status);
 
            status->pid_enabled = 1;
 
	    status->setpoint = set->val.setpoint_steam;
 

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                status->state = STATE_IDLE;
 
		save_setpoints(&set); // TODO: Check for mod
 
            }
 
            else {
 
                user_input(&set->val.setpoint_steam);
 
            }
 

	
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 

	
 
        case STATE_TC_ERROR:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to steam ]
 
            // [ 30 => 120 C            ]
 
            ssd1306_DrawString("Error:              ", 0, 0);
 

	
 
            char tempstr[6];
 
            itoa(status->tc_errno, tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 57);
 

	
 
            if(status->tc_errno == 1)
 
                ssd1306_DrawString("    TC Open Circuit", 1, 0);
 
            else if(status->tc_errno == 4)
 
                ssd1306_DrawString("    TC Short to GND", 1, 0);
 
            else if(status->tc_errno == 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;
 
            }
 
            else if(SW_RIGHT_PRESSED) {
 
                set->val.ignore_tc_error = 1;
 
                status->state = STATE_IDLE;
 
            }
 
            // Event Handler
 
            // Maybe handle if TC is plugged in
 
            // N/A
 
 
 
        } break;
 

	
 
        // Something is terribly wrong
 
        default:
 
        {
 
            status->state = STATE_IDLE;
 
            status->pid_enabled = 0;
 

	
 
        } break;
 
            
 
    }
 

	
 
    if(last_state != status->state) {
 
        // Clear screen on state change
 
        goto_mode = 2;
 
        trigger_drawsetpoint = 1;
 
        ssd1306_clearscreen();
 
    }
 

	
 
    // Last buttonpress
 
    sw_btn_last = sw_btn;
 
    sw_up_last = sw_up;
 
    sw_down_last = sw_down;
 
    sw_left_last = sw_left;
 
    sw_right_last = sw_right;
 
}
 

	
 

	
 
static int32_t temp_last = 43002;
 
static int32_t setpoint_last = 10023;
 
void draw_setpoint(therm_status_t* status) {
 
    // FIXME: need to do this when switching modes too
 
    if(status->temp != temp_last || trigger_drawsetpoint) { 
 
        char tempstr[3];
 
        itoa_fp(status->temp, status->temp_frac, tempstr);
 
        ssd1306_DrawStringBig("      ", 3, 0);
 
        ssd1306_DrawStringBig(tempstr, 3, 0);
 
    }
 

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

	
 
    if(status->setpoint != setpoint_last || trigger_drawsetpoint) {
 
        char tempstr[3];
 
        itoa(status->setpoint, tempstr, 10);
 
        ssd1306_DrawStringBig("   ", 3, 90);
 
        ssd1306_DrawStringBig(tempstr, 3, 90);
 
    }
 

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

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
main.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
 
#include "config.h"
 
#include "syslib.h"
 
#include "pid.h"
 
#include "states.h"
 
#include "ssd1306.h"
 
#include "max31855.h"
 
#include "gpio.h"
 
#include "spi.h"
 
#include "flash.h"
 
#include "stringhelpers.h"
 
#include "display.h"
 
#include "storage.h"
 
 
#include "usb_device.h"
 
#include "usbd_cdc_if.h"
 
 
therm_settings_t set;
 
therm_status_t status;
 
 
int main(void)
 
{
 
    // Initialize HAL
 
    hal_init();
 
 
    // Configure the system clock
 
    systemclock_init();
 
 
    // Unset bootloader option bytes (if set)
 
    // FIXME this was never getting called. Try again sometime.
 
    //bootloader_unset();
 
 
    // Init GPIO
 
    gpio_init();
 
 
    // Init USB (TODO: Handle plugged/unplugged with external power)
 
    MX_USB_DEVICE_Init();
 
//    set.val.usb_plugged = 
 
 
    // USB startup delay
 
    HAL_Delay(500);
 
    HAL_GPIO_WritePin(LED_POWER, 1);
 
 
    // Enter into bootloader if up button pressed on boot
 
    if(!HAL_GPIO_ReadPin(SW_UP))
 
        bootloader_enter(); 
 
 
    // Init SPI busses
 
    spi_init();
 
 
    // Init OLED over SPI
 
    ssd1306_Init();
 
    ssd1306_clearscreen();
 
   
 
    // Default settings 
 
    set.val.boottobrew = 0;
 
    set.val.temp_units = TEMP_UNITS_FAHRENHEIT;
 
    set.val.windup_guard = 200;
 
    set.val.k_p = 10;
 
    set.val.k_i = 10;
 
    set.val.k_d = 1;
 
    set.val.ignore_tc_error = 0;
 
    set.val.setpoint_brew = 70;
 
    set.val.setpoint_steam = 70;
 
 
    // Default status
 
    status.temp = 0;
 
    status.temp_frac = 0;
 
    status.state_resume = 0;
 
    status.state = STATE_IDLE;
 
    status.setpoint = 70;
 
    status.pid_enabled = 0;
 
 
    // Load settings (if any) from EEPROM
 
    restore_settings(&set);
 
 
    // Go to brew instead of idle if configured thusly
 
    if(set.val.boottobrew)
 
      status.state = STATE_PREHEAT_BREW; 
 
 
    // Startup screen 
 
    ssd1306_DrawString("therm v0.2", 1, 40);
 
    ssd1306_DrawString("protofusion.org/therm", 3, 0);
 
 
    HAL_Delay(1000);
 
 
    // Restore settings from flash memory
 
    flash_restore(&set);
 
 
    HAL_Delay(1000);
 
    ssd1306_clearscreen();
 
 
    // Soft timers
 
    uint32_t last_ssr_on = 0;
 
    uint32_t last_vcp_tx = 0;
 
    uint32_t last_led = 0;
 
    uint32_t last_pid = 0;
 
    int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD 
 
 
    // Main loop
 
    while(1)
 
    {
 
        // Process sensor inputs
 
 
        if(HAL_GetTick() - last_led > 400) 
 
        {
 
            last_led = HAL_GetTick();
 
        }
 
 
        if((HAL_GetTick() - last_pid > PID_PERIOD))
 
        {
 
            #ifdef MAX31855_TC_SENSOR
 
            max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
 
            #endif
 
 
            #ifdef MAX31865_RTD_SENSOR
 
            max31865_readtemp(&set, &status);
 
            #endif
 
 
 
            if(status.pid_enabled) 
 
            {
 
                // Get ssr output for next time
 
                int16_t power_percent = pid_update(set.val.k_p, set.val.k_i, set.val.k_d, status.temp, status.temp_frac, status.setpoint, &set, &status);
 
                //power-percent is 0-1000?
 
                ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000;
 
            }
 
            else 
 
            {
 
                ssr_output = 0;
 
            }
 
 
            last_pid = HAL_GetTick();
 
        }
 
 
        // Kill SSR once the desired on-time has elapsed
 
        if(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(HAL_GetTick() - last_ssr_on > SSR_PERIOD)
 
        {
 
            // Only support heating (ssr_output > 0) right now
 
            if(ssr_output > 0) 
 
            {
 
                char tempstr[6];
 
                itoa(ssr_output, tempstr, 10);
 
                ssd1306_DrawString(tempstr, 0, 90);
 
 
            char tempstr[6];
 
            itoa(ssr_output, tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 90);
 
 
 
            // Only support heating (ssr_output > 0) right now
 
            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);
 
            }
 
            
 
        }
 
        
 
 
        // Transmit temperature over USB-CDC on a regulat 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); 
 
    }
 
}
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
sflash.sh
Show inline comments
 
new file 100755
 
#!/bin/bash
 
cd build
 
st-flash write main.bin 0x8000000
 
cd ..
 

	
 

	
 
# USB DFU:
 
#dfu-util -a 0 -d 0483:df11 -s 0x08000000:leave -D build/main.bin 
 
#sleep 1
 
#dfu-util -a 1 -s 0x1FFFF800:8 -D optbytes.dat
spi.c
Show inline comments
 
deleted file
spi.h
Show inline comments
 
deleted file
stm32f0xx_hal_conf.h
Show inline comments
 
deleted file
storage.c
Show inline comments
 
deleted file
storage.h
Show inline comments
 
deleted file
system/spi.c
Show inline comments
 
new file 100644
 

	
 
#include "stm32f0xx_hal_conf.h"
 
#include "stm32f0xx_hal_gpio_ex.h"
 
SPI_HandleTypeDef hspi1;
 

	
 
void spi_init()
 
{
 
    hspi1.Instance = SPI1;
 
    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);
 
}    
 
    
 
SPI_HandleTypeDef* spi_get()
 
{
 
    return &hspi1;
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
system/spi.h
Show inline comments
 
new file 100644
 
#ifndef SPI_H
 
#define SPI_H
 

	
 
#include "stm32f0xx_hal_conf.h"
 

	
 
void spi_init();
 
SPI_HandleTypeDef* spi_get();
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
system/stm32f0xx_hal_conf.h
Show inline comments
 
new file 100644
 
/**
 
  ******************************************************************************
 
  * @file    stm32f0xx_hal_conf.h
 
  * @brief   HAL configuration template file.
 
  ******************************************************************************
 
  * @attention
 
  *
 
  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
 
  *
 
  * Redistribution and use in source and binary forms, with or without modification,
 
  * are permitted provided that the following conditions are met:
 
  *   1. Redistributions of source code must retain the above copyright notice,
 
  *      this list of conditions and the following disclaimer.
 
  *   2. Redistributions in binary form must reproduce the above copyright notice,
 
  *      this list of conditions and the following disclaimer in the documentation
 
  *      and/or other materials provided with the distribution.
 
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
 
  *      may be used to endorse or promote products derived from this software
 
  *      without specific prior written permission.
 
  *
 
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  *
 
  ******************************************************************************
 
  */
 
 
/* Define to prevent recursive inclusion -------------------------------------*/
 
#ifndef __STM32F0xx_HAL_CONF_H
 
#define __STM32F0xx_HAL_CONF_H
 
 
#ifdef __cplusplus
 
 extern "C" {
 
#endif
 
 
/* Exported types ------------------------------------------------------------*/
 
/* Exported constants --------------------------------------------------------*/
 
 
/* ########################## Module Selection ############################## */
 
/**
 
  * @brief This is the list of modules to be used in the HAL driver
 
  */
 
#define HAL_MODULE_ENABLED
 
//#define HAL_ADC_MODULE_ENABLED
 
//#define HAL_CAN_MODULE_ENABLED
 
//#define HAL_CEC_MODULE_ENABLED
 
//#define HAL_COMP_MODULE_ENABLED
 
//#define HAL_CRC_MODULE_ENABLED
 
//#define HAL_CRYP_MODULE_ENABLED
 
//#define HAL_TSC_MODULE_ENABLED
 
//#define HAL_DAC_MODULE_ENABLED
 
//#define HAL_I2C_MODULE_ENABLED
 
//#define HAL_I2S_MODULE_ENABLED
 
//#define HAL_IWDG_MODULE_ENABLED
 
//#define HAL_LCD_MODULE_ENABLED
 
//#define HAL_LPTIM_MODULE_ENABLED
 
//#define HAL_RNG_MODULE_ENABLED
 
//#define HAL_RTC_MODULE_ENABLED
 
#define HAL_SPI_MODULE_ENABLED
 
#define HAL_TIM_MODULE_ENABLED
 
//#define HAL_UART_MODULE_ENABLED
 
//#define HAL_USART_MODULE_ENABLED
 
//#define HAL_IRDA_MODULE_ENABLED
 
//#define HAL_SMARTCARD_MODULE_ENABLED
 
//#define HAL_SMBUS_MODULE_ENABLED
 
//#define HAL_WWDG_MODULE_ENABLED
 
#define HAL_PCD_MODULE_ENABLED
 
#define HAL_CORTEX_MODULE_ENABLED
 
#define HAL_DMA_MODULE_ENABLED
 
#define HAL_FLASH_MODULE_ENABLED
 
#define HAL_GPIO_MODULE_ENABLED
 
#define HAL_PWR_MODULE_ENABLED
 
#define HAL_RCC_MODULE_ENABLED
 
 
/* ########################## HSE/HSI Values adaptation ##################### */
 
/**
 
  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
 
  *        This value is used by the RCC HAL module to compute the system frequency
 
  *        (when HSE is used as system clock source, directly or through the PLL).
 
  */
 
#if !defined  (HSE_VALUE)
 
  #define HSE_VALUE    ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */
 
#endif /* HSE_VALUE */
 
 
/**
 
  * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
 
  *        Timeout value
 
  */
 
#if !defined  (HSE_STARTUP_TIMEOUT)
 
  #define HSE_STARTUP_TIMEOUT    ((uint32_t)5000)   /*!< Time out for HSE start up, in ms */
 
#endif /* HSE_STARTUP_TIMEOUT */
 
 
/**
 
  * @brief Internal High Speed oscillator (HSI) value.
 
  *        This value is used by the RCC HAL module to compute the system frequency
 
  *        (when HSI is used as system clock source, directly or through the PLL).
 
  */
 
#if !defined  (HSI_VALUE)
 
  #define HSI_VALUE    ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
 
#endif /* HSI_VALUE */
 
 
/**
 
  * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup
 
  *        Timeout value
 
  */
 
#if !defined  (HSI_STARTUP_TIMEOUT)
 
 #define HSI_STARTUP_TIMEOUT   ((uint32_t)5000) /*!< Time out for HSI start up */
 
#endif /* HSI_STARTUP_TIMEOUT */
 
 
/**
 
  * @brief Internal High Speed oscillator for ADC (HSI14) value.
 
  */
 
#if !defined  (HSI14_VALUE)
 
#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz.
 
					     The real value may vary depending on the variations
 
					     in voltage and temperature.  */
 
#endif /* HSI14_VALUE */
 
 
/**
 
  * @brief Internal High Speed oscillator for USB (HSI48) value.
 
  */
 
#if !defined  (HSI48_VALUE)
 
#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz.
 
					     The real value may vary depending on the variations
 
					     in voltage and temperature.  */
 
#endif /* HSI48_VALUE */
 
 
/**
 
  * @brief Internal Low Speed oscillator (LSI) value.
 
  */
 
#if !defined  (LSI_VALUE)
 
 #define LSI_VALUE  ((uint32_t)40000)
 
#endif /* LSI_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
 
					     The real value may vary depending on the variations
 
					     in voltage and temperature.  */
 
/**
 
  * @brief External Low Speed oscillator (LSI) value.
 
  */
 
#if !defined  (LSE_VALUE)
 
 #define LSE_VALUE  ((uint32_t)32768)    /*!< Value of the External Low Speed oscillator in Hz */
 
#endif /* LSE_VALUE */
 
 
/* Tip: To avoid modifying this file each time you need to use different HSE,
 
   ===  you can define the HSE value in your toolchain compiler preprocessor. */
 
 
/* ########################### System Configuration ######################### */
 
/**
 
  * @brief This is the HAL system configuration section
 
  */
 
#define  VDD_VALUE                    ((uint32_t)3300) /*!< Value of VDD in mv */
 
#define  TICK_INT_PRIORITY            ((uint32_t)0)    /*!< tick interrupt priority (lowest by default)  */
 
									      /*  Warning: Must be set to higher priority for HAL_Delay()  */
 
									      /*  and HAL_GetTick() usage under interrupt context          */
 
#define  USE_RTOS                     0
 
#define  PREFETCH_ENABLE              0
 
#define  INSTRUCTION_CACHE_ENABLE     0
 
#define  DATA_CACHE_ENABLE            0
 
/* ########################## Assert Selection ############################## */
 
/**
 
  * @brief Uncomment the line below to expanse the "assert_param" macro in the
 
  *        HAL drivers code
 
  */
 
/* #define USE_FULL_ASSERT   1 */
 
 
/* Includes ------------------------------------------------------------------*/
 
/**
 
  * @brief Include module's header file
 
  */
 
 
#ifdef HAL_RCC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_rcc.h"
 
#endif /* HAL_RCC_MODULE_ENABLED */
 
 
#ifdef HAL_GPIO_MODULE_ENABLED
 
 #include "stm32f0xx_hal_gpio.h"
 
#endif /* HAL_GPIO_MODULE_ENABLED */
 
 
#ifdef HAL_DMA_MODULE_ENABLED
 
  #include "stm32f0xx_hal_dma.h"
 
#endif /* HAL_DMA_MODULE_ENABLED */
 
 
#ifdef HAL_CORTEX_MODULE_ENABLED
 
 #include "stm32f0xx_hal_cortex.h"
 
#endif /* HAL_CORTEX_MODULE_ENABLED */
 
 
#ifdef HAL_ADC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_adc.h"
 
#endif /* HAL_ADC_MODULE_ENABLED */
 
 
#ifdef HAL_CAN_MODULE_ENABLED
 
 #include "stm32f0xx_hal_can.h"
 
#endif /* HAL_CAN_MODULE_ENABLED */
 
 
#ifdef HAL_CEC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_cec.h"
 
#endif /* HAL_CEC_MODULE_ENABLED */
 
 
#ifdef HAL_COMP_MODULE_ENABLED
 
 #include "stm32f0xx_hal_comp.h"
 
#endif /* HAL_COMP_MODULE_ENABLED */
 
 
#ifdef HAL_CRC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_crc.h"
 
#endif /* HAL_CRC_MODULE_ENABLED */
 
 
#ifdef HAL_DAC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_dac.h"
 
#endif /* HAL_DAC_MODULE_ENABLED */
 
 
#ifdef HAL_FLASH_MODULE_ENABLED
 
 #include "stm32f0xx_hal_flash.h"
 
#endif /* HAL_FLASH_MODULE_ENABLED */
 
 
#ifdef HAL_I2C_MODULE_ENABLED
 
 #include "stm32f0xx_hal_i2c.h"
 
#endif /* HAL_I2C_MODULE_ENABLED */
 
 
#ifdef HAL_I2S_MODULE_ENABLED
 
 #include "stm32f0xx_hal_i2s.h"
 
#endif /* HAL_I2S_MODULE_ENABLED */
 
 
#ifdef HAL_IRDA_MODULE_ENABLED
 
 #include "stm32f0xx_hal_irda.h"
 
#endif /* HAL_IRDA_MODULE_ENABLED */
 
 
#ifdef HAL_IWDG_MODULE_ENABLED
 
 #include "stm32f0xx_hal_iwdg.h"
 
#endif /* HAL_IWDG_MODULE_ENABLED */
 
 
#ifdef HAL_PCD_MODULE_ENABLED
 
 #include "stm32f0xx_hal_pcd.h"
 
#endif /* HAL_PCD_MODULE_ENABLED */
 
 
#ifdef HAL_PWR_MODULE_ENABLED
 
 #include "stm32f0xx_hal_pwr.h"
 
#endif /* HAL_PWR_MODULE_ENABLED */
 
 
#ifdef HAL_RTC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_rtc.h"
 
#endif /* HAL_RTC_MODULE_ENABLED */
 
 
#ifdef HAL_SMARTCARD_MODULE_ENABLED
 
 #include "stm32f0xx_hal_smartcard.h"
 
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
 
 
#ifdef HAL_SMBUS_MODULE_ENABLED
 
 #include "stm32f0xx_hal_smbus.h"
 
#endif /* HAL_SMBUS_MODULE_ENABLED */
 
 
#ifdef HAL_SPI_MODULE_ENABLED
 
 #include "stm32f0xx_hal_spi.h"
 
#endif /* HAL_SPI_MODULE_ENABLED */
 
 
#ifdef HAL_TIM_MODULE_ENABLED
 
 #include "stm32f0xx_hal_tim.h"
 
#endif /* HAL_TIM_MODULE_ENABLED */
 
 
#ifdef HAL_TSC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_tsc.h"
 
#endif /* HAL_TSC_MODULE_ENABLED */
 
 
#ifdef HAL_UART_MODULE_ENABLED
 
 #include "stm32f0xx_hal_uart.h"
 
#endif /* HAL_UART_MODULE_ENABLED */
 
 
#ifdef HAL_USART_MODULE_ENABLED
 
 #include "stm32f0xx_hal_usart.h"
 
#endif /* HAL_USART_MODULE_ENABLED */
 
 
#ifdef HAL_WWDG_MODULE_ENABLED
 
 #include "stm32f0xx_hal_wwdg.h"
 
#endif /* HAL_WWDG_MODULE_ENABLED */
 
 
/* Exported macro ------------------------------------------------------------*/
 
#ifdef  USE_FULL_ASSERT
 
/**
 
  * @brief  The assert_param macro is used for function's parameters check.
 
  * @param  expr: If expr is false, it calls assert_failed function
 
  *         which reports the name of the source file and the source
 
  *         line number of the call that failed.
 
  *         If expr is true, it returns no value.
 
  * @retval None
 
  */
 
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
 
/* Exported functions ------------------------------------------------------- */
 
  void assert_failed(uint8_t* file, uint32_t line);
 
#else
 
  #define assert_param(expr) ((void)0)
 
#endif /* USE_FULL_ASSERT */
 
 
#ifdef __cplusplus
 
}
 
#endif
 
 
#endif /* __STM32F0xx_HAL_CONF_H */
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
system/stringhelpers.c
Show inline comments
 
file renamed from stringhelpers.c to system/stringhelpers.c
system/stringhelpers.h
Show inline comments
 
file renamed from stringhelpers.h to system/stringhelpers.h
system/system_stm32f0xx.c
Show inline comments
 
new file 100644
 
/**
 
  ******************************************************************************
 
  * @file    system_stm32f0xx.c
 
  * @author  MCD Application Team
 
  * @version V2.1.0
 
  * @date    03-Oct-2014
 
  * @brief   CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
 
  *
 
  * 1. This file provides two functions and one global variable to be called from
 
  *    user application:
 
  *      - SystemInit(): This function is called at startup just after reset and
 
  *                      before branch to main program. This call is made inside
 
  *                      the "startup_stm32f0xx.s" file.
 
  *
 
  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
 
  *                                  by the user application to setup the SysTick
 
  *                                  timer or configure other parameters.
 
  *
 
  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
 
  *                                 be called whenever the core clock is changed
 
  *                                 during program execution.
 
  *
 
  * 2. After each device reset the HSI (8 MHz) is used as system clock source.
 
  *    Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to
 
  *    configure the system clock before to branch to main program.
 
  *
 
  * 3. This file configures the system clock as follows:
 
  *=============================================================================
 
  *                         Supported STM32F0xx device
 
  *-----------------------------------------------------------------------------
 
  *        System Clock source                    | HSI
 
  *-----------------------------------------------------------------------------
 
  *        SYSCLK(Hz)                             | 8000000
 
  *-----------------------------------------------------------------------------
 
  *        HCLK(Hz)                               | 8000000
 
  *-----------------------------------------------------------------------------
 
  *        AHB Prescaler                          | 1
 
  *-----------------------------------------------------------------------------
 
  *        APB1 Prescaler                         | 1
 
  *-----------------------------------------------------------------------------
 
  *=============================================================================
 
  ******************************************************************************
 
  * @attention
 
  *
 
  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
 
  *
 
  * Redistribution and use in source and binary forms, with or without modification,
 
  * are permitted provided that the following conditions are met:
 
  *   1. Redistributions of source code must retain the above copyright notice,
 
  *      this list of conditions and the following disclaimer.
 
  *   2. Redistributions in binary form must reproduce the above copyright notice,
 
  *      this list of conditions and the following disclaimer in the documentation
 
  *      and/or other materials provided with the distribution.
 
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
 
  *      may be used to endorse or promote products derived from this software
 
  *      without specific prior written permission.
 
  *
 
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  *
 
  ******************************************************************************
 
  */
 
 
/** @addtogroup CMSIS
 
  * @{
 
  */
 
 
/** @addtogroup stm32f0xx_system
 
  * @{
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Includes
 
  * @{
 
  */
 
 
#include "stm32f0xx.h"
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_TypesDefinitions
 
  * @{
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Defines
 
  * @{
 
  */
 
#if !defined  (HSE_VALUE)
 
  #define HSE_VALUE    ((uint32_t)16000000) /*!< Default value of the External oscillator in Hz.
 
						This value can be provided and adapted by the user application. */
 
#endif /* HSE_VALUE */
 
 
#if !defined  (HSI_VALUE)
 
  #define HSI_VALUE    ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
 
						This value can be provided and adapted by the user application. */
 
#endif /* HSI_VALUE */
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Macros
 
  * @{
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Variables
 
  * @{
 
  */
 
  /* This variable is updated in three ways:
 
      1) by calling CMSIS function SystemCoreClockUpdate()
 
      2) by calling HAL API function HAL_RCC_GetHCLKFreq()
 
      3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
 
	 Note: If you use this function to configure the system clock there is no need to
 
	       call the 2 first functions listed above, since SystemCoreClock variable is
 
	       updated automatically.
 
  */
 
uint32_t SystemCoreClock = 8000000;
 
 
__IO const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes
 
  * @{
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Functions
 
  * @{
 
  */
 
 
/**
 
  * @brief  Setup the microcontroller system.
 
  *         Initialize the default HSI clock source, vector table location and the PLL configuration is reset.
 
  * @param  None
 
  * @retval None
 
  */
 
void SystemInit(void)
 
{
 
  /* Reset the RCC clock configuration to the default reset state ------------*/
 
  /* Set HSION bit */
 
  RCC->CR |= (uint32_t)0x00000001;
 
 
#if defined (STM32F051x8) || defined (STM32F058x8)
 
  /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits */
 
  RCC->CFGR &= (uint32_t)0xF8FFB80C;
 
#else
 
  /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits */
 
  RCC->CFGR &= (uint32_t)0x08FFB80C;
 
#endif /* STM32F051x8 or STM32F058x8 */
 
 
  /* Reset HSEON, CSSON and PLLON bits */
 
  RCC->CR &= (uint32_t)0xFEF6FFFF;
 
 
  /* Reset HSEBYP bit */
 
  RCC->CR &= (uint32_t)0xFFFBFFFF;
 
 
  /* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
 
  RCC->CFGR &= (uint32_t)0xFFC0FFFF;
 
 
  /* Reset PREDIV[3:0] bits */
 
  RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
 
 
#if defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xB)
 
  /* Reset USART2SW[1:0] USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
 
  RCC->CFGR3 &= (uint32_t)0xFFFCFE2C;
 
#elif defined (STM32F091xC) || defined (STM32F098xx)
 
  /* Reset USART3SW[1:0], USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW bits */
 
  RCC->CFGR3 &= (uint32_t)0xFFF0FFAC;
 
#else
 
  /* Reset USART1SW[1:0], I2C1SW, CECSW, USBSW  and ADCSW bits */
 
  RCC->CFGR3 &= (uint32_t)0xFFFFFE2C;
 
#endif
 
 
  /* Reset HSI14 bit */
 
  RCC->CR2 &= (uint32_t)0xFFFFFFFE;
 
 
  /* Disable all interrupts */
 
  RCC->CIR = 0x00000000;
 
 
}
 
 
/**
 
   * @brief  Update SystemCoreClock variable according to Clock Register Values.
 
  *         The SystemCoreClock variable contains the core clock (HCLK), it can
 
  *         be used by the user application to setup the SysTick timer or configure
 
  *         other parameters.
 
  *
 
  * @note   Each time the core clock (HCLK) changes, this function must be called
 
  *         to update SystemCoreClock variable value. Otherwise, any configuration
 
  *         based on this variable will be incorrect.
 
  *
 
  * @note   - The system frequency computed by this function is not the real
 
  *           frequency in the chip. It is calculated based on the predefined
 
  *           constant and the selected clock source:
 
  *
 
  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
 
  *
 
  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
 
  *
 
  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
 
  *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
 
  *
 
  *         (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value
 
  *             8 MHz) but the real value may vary depending on the variations
 
  *             in voltage and temperature.
 
  *
 
  *         (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value
 
  *              8 MHz), user has to ensure that HSE_VALUE is same as the real
 
  *              frequency of the crystal used. Otherwise, this function may
 
  *              have wrong result.
 
  *
 
  *         - The result of this function could be not correct when using fractional
 
  *           value for HSE crystal.
 
  *
 
  * @param  None
 
  * @retval None
 
  */
 
void SystemCoreClockUpdate (void)
 
{
 
  uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
 
 
  /* Get SYSCLK source -------------------------------------------------------*/
 
  tmp = RCC->CFGR & RCC_CFGR_SWS;
 
 
  switch (tmp)
 
  {
 
    case RCC_CFGR_SWS_HSI:  /* HSI used as system clock */
 
      SystemCoreClock = HSI_VALUE;
 
      break;
 
    case RCC_CFGR_SWS_HSE:  /* HSE used as system clock */
 
      SystemCoreClock = HSE_VALUE;
 
      break;
 
    case RCC_CFGR_SWS_PLL:  /* PLL used as system clock */
 
      /* Get PLL clock source and multiplication factor ----------------------*/
 
      pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
 
      pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
 
      pllmull = ( pllmull >> 18) + 2;
 
      predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
 
 
      if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
 
      {
 
	/* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */
 
	SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull;
 
      }
 
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
 
      else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
 
      {
 
	/* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */
 
	SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull;
 
      }
 
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */
 
      else
 
      {
 
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
 
	/* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */
 
	SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull;
 
#else
 
	/* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */
 
	SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
 
#endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */
 
      }
 
      break;
 
    default: /* HSI used as system clock */
 
      SystemCoreClock = HSI_VALUE;
 
      break;
 
  }
 
  /* Compute HCLK clock frequency ----------------*/
 
  /* Get HCLK prescaler */
 
  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
 
  /* HCLK clock frequency */
 
  SystemCoreClock >>= tmp;
 
}
 
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
system_stm32f0xx.c
Show inline comments
 
deleted file
0 comments (0 inline, 0 general)