Changeset - 988bab1cb593
[Not reviewed]
cortex-f0
2 16 0
Ethan Zonca - 10 years ago 2015-01-03 16:31:08
ez@ethanzonca.com
Got things mostly compiling, disabled SPI and USB for now because of RAM overflow
18 files changed with 185 insertions and 667 deletions:
0 comments (0 inline, 0 general)
Makefile
Show inline comments
 
TARGET:=therm
 
TOOLCHAIN_PATH:=/usr/bin
 
TOOLCHAIN_PREFIX:=arm-none-eabi
 
OPTLVL:=3 # Optimization level, can be [0, 1, 2, 3, s].
 

	
 
#PROJECT_NAME:=$(notdir $(lastword $(CURDIR)))
 
TOP:=$(shell readlink -f "../..")
 
LIBDIR:=libraries
 

	
 
HAL_LIB:=$(LIBDIR)/STM32F0xx_HAL_Driver
 
USB_LIB:=$(LIBDIR)/STM32_USB_Device_Library
 

	
 
STARTUP:=$(STMLIB)/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc
 
STARTUP:=$(LIBDIR)/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc
 

	
 
SYSTEMDIR:=$(LIBDIR)/CMSIS/Device/ST/STM32F0xx/Source/Templates # Houses system_STM32f0xx.c
 

	
 
LINKER_SCRIPT:=$(CURDIR)/stm32-flash.ld
 

	
 
# Local libs
 
INCLUDE=-I$(CURDIR)
 

	
 
# CMSIS
 
INCLUDE+=-I$(LIBDIR)/CMSIS/Include
 
INCLUDE+=-I$(LIBDIR)/CMSIS/Device/ST/STM32F0xx/Include
 

	
 
# USB
 
INCLUDE+=-I$(USB_LIB)/Class/CDC
 
INCLUDE+=-I$(USB_LIB)/Core
 

	
 
# HAL
 
INCLUDE+=-I$(HAL_LIB)/Inc
 

	
 

	
 
# vpath is used so object files are written to the current directory instead
 
# of the same directory as their source files
 
vpath %.c $(HAL_LIB)/src \
 
          $(LIBDIR)/$(USB_LIB) \
 
          $(LIBDIR)/$(USB_LIB)/Class/CDC \
 
          $(LIBDIR)/$(USB_LIB)/Core
 
vpath %.c $(HAL_LIB)/Src \
 
          $(USB_LIB) \
 
          $(USB_LIB)/Class/CDC \
 
          $(USB_LIB)/Core \
 
	  $(SYSTEMDIR)
 

	
 
vpath %.s $(STARTUP)
 

	
 
ASRC=startup_stm32f042x6.s
 
ASRC=$(STARTUP)/startup_stm32f042x6.s
 

	
 
# Project Source Files
 
SRC=main.c
 
SRC+=stm32f0xx_it.c
 
SRC+=stm32f0xx_hal_msp.c
 
SRC+=system_stm32f0xx.c
 
SRC+=ssd1306.c
 
SRC+=eeprom_min.c
 
SRC+=gpio.c
 
SRC+=spi.c
 
SRC+=clock.c
 
SRC+=stringhelpers.c
 

	
 
# Discovery Source Files
 
#SRC+=stm32f4_discovery_lis302dl.c
 
#SRC+=stm32f4_discovery.c
 
#SRC+=stm32f4_discovery_audio_codec.c
 
SRC+=stm32f0xx_it.c
 
SRC+=stm32f0xx_hal_msp.c
 

	
 
SRC+=usb_device.c
 
SRC+=usbd_cdc_if.c
 
SRC+=usbd_conf.c
 
SRC+=usbd_desc.c
 

	
 
# Standard Peripheral Source Files
 
SRC+=stm32f0xx_syscfg.c
 
SRC+=misc.c
 
SRC+=stm32f0xx_adc.c
 
SRC+=stm32f0xx_dac.c
 
SRC+=stm32f0xx_dma.c
 
SRC+=stm32f0xx_exti.c
 
SRC+=stm32f0xx_flash.c
 
SRC+=stm32f0xx_gpio.c
 
SRC+=stm32f0xx_i2c.c
 
SRC+=stm32f0xx_rcc.c
 
SRC+=stm32f0xx_spi.c
 
SRC+=stm32f0xx_tim.c
 
SRC+=system_stm32f0xx.c
 

	
 
SRC+=stm32f0xx_hal.c
 
SRC+=stm32f0xx_hal_spi.c
 
SRC+=stm32f0xx_hal_pcd.c
 
SRC+=stm32f0xx_hal_pcd_ex.c
 
SRC+=stm32f0xx_hal_cortex.c
 
SRC+=stm32f0xx_hal_dma.c
 
SRC+=stm32f0xx_hal_flash.c
 
SRC+=stm32f0xx_hal_flash_ex.c
 
SRC+=stm32f0xx_hal_gpio.c
 
SRC+=stm32f0xx_hal_pwr.c
 
SRC+=stm32f0xx_hal_pwr_ex.c
 
SRC+=stm32f0xx_hal_rcc.c
 
SRC+=stm32f0xx_hal_rcc_ex.c
 

	
 
# USB Source Files
 
SRC+=usb_core.c
 
SRC+=usb_init.c
 
SRC+=usb_int.c
 
SRC+=usb_mem.c
 
SRC+=usb_regs.c
 
SRC+=usb_sil.c
 
SRC+=hw_config.c
 
SRC+=usb_desc.c
 
SRC+=usb_endp.c
 
SRC+=usb_istr.c
 
SRC+=usb_prop.c
 
SRC+=usb_pwr.c
 
SRC+=usbd_cdc.c
 
SRC+=usbd_core.c
 
SRC+=usbd_ctlreq.c
 
SRC+=usbd_ioreq.c
 

	
 
CDEFS=-DUSE_STDPERIPH_DRIVER
 
CDEFS+=-DSTM32F0XX
 
CDEFS+=-DMANGUSTA_DISCOVERY
 
#CDEFS+=-DUSE_USB_OTG_FS
 

	
 
# EMZ FIXME
 
CDEFS+=-DHSE_VALUE=8000000
 

	
 

	
 
#EMZ Optimized: 
 
MCUFLAGS=-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -mfloat-abi=soft
 

	
 
# Default:  MCUFLAGS=-mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections
 

	
 
#MCUFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpa -mfloat-abi=hard -mthumb-interwork
 
#MCUFLAGS=-mcpu=cortex-m4 -mfpu=vfpv4-sp-d16 -mfloat-abi=hard
 
COMMONFLAGS=-O$(OPTLVL) -g -Wall
 
CFLAGS=$(COMMONFLAGS) $(MCUFLAGS) $(INCLUDE) $(CDEFS)
 

	
 
LDLIBS=
 
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections \
 
        -nostartfiles -Wl,--gc-sections,-T$(LINKER_SCRIPT)
 

	
 
#####
 
#####
 

	
 
OBJ = $(SRC:%.c=%.o) $(ASRC:%.s=%.o)
 

	
 
CC=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
 
LD=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
 
OBJCOPY=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-objcopy
 
AS=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-as
 
AR=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-ar
 
GDB=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gdb
 
SIZE=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-size
 

	
 

	
 
all: $(OBJ)
 
	$(CC) -o $(TARGET).elf $(LDFLAGS) $(OBJ)	$(LDLIBS)
 
	$(OBJCOPY) -O ihex   $(TARGET).elf $(TARGET).hex
 
	$(OBJCOPY) -O binary $(TARGET).elf $(TARGET).bin
 

	
 
.PHONY: clean
 

	
 
clean:
 
	rm -f $(OBJ)
 
	rm -f $(TARGET).elf
clock.c
Show inline comments
 

	
 
#include "stm32f0xx_hal_conf.h"
 

	
 
void SystemClock_Config(void)
 
{
 

	
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
 
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
 

	
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
 
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
 
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 

	
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
 
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
 
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
 

	
 
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
 
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
 
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
 

	
 
  __SYSCFG_CLK_ENABLE();
 

	
 
}
config.h
Show inline comments
 
#ifndef CONFIG_H
 
#define CONFIG_H
 

	
 

	
 
#define SSR_PERIOD 200
 

	
 
#define LED_POWER GPIOB,GPIO_Pin_9
 
#define LED_STAT  GPIOA,GPIO_Pin_15
 
#define LED_POWER GPIOB,GPIO_PIN_9
 
#define LED_STAT  GPIOA,GPIO_PIN_15
 

	
 
#define MAX_CS GPIOB,GPIO_Pin_12
 
#define MAX_CS GPIOB,GPIO_PIN_12
 

	
 
#define SW_BTN  GPIOB, GPIO_Pin_3
 
#define SW_UP   GPIOB, GPIO_Pin_6
 
#define SW_DOWN GPIOB, GPIO_Pin_4
 
#define SW_LEFT GPIOB, GPIO_Pin_7
 
#define SW_RIGHT GPIOB, GPIO_Pin_5
 
#define SW_BTN  GPIOB, GPIO_PIN_3
 
#define SW_UP   GPIOB, GPIO_PIN_6
 
#define SW_DOWN GPIOB, GPIO_PIN_4
 
#define SW_LEFT GPIOB, GPIO_PIN_7
 
#define SW_RIGHT GPIOB, GPIO_PIN_5
 

	
 
#define SSR_PIN GPIOC, GPIO_Pin_13
 
#define SSR_PIN GPIOC, GPIO_PIN_13
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
gpio.c
Show inline comments
 
#include "gpio.h"
 
#include "config.h"
 
#include "stm32f0xx_hal_conf.h"
 
#include <inttypes.h>
 

	
 
extern volatile uint32_t ticks;
 

	
 
// Increase on each press, and increase at a fast rate after duration elapsed of continuously holding down... somehow...
 
uint32_t change_time_reset = 0;
 

	
 
void user_input(uint16_t* to_modify)
 
{
 
    if(CHANGE_ELAPSED) {
 
        if(!GPIO_ReadInputDataBit(SW_UP) ) {
 
        if(!HAL_GPIO_ReadPin(SW_UP) ) {
 
            CHANGE_RESET;
 
            (*to_modify)++;
 
        }
 
        else if(!GPIO_ReadInputDataBit(SW_DOWN) && (*to_modify) > 0) {
 
        else if(!HAL_GPIO_ReadPin(SW_DOWN) && (*to_modify) > 0) {
 
            CHANGE_RESET;
 
            (*to_modify)--;
 
        }
 
    }
 
}
 

	
 

	
 
void init_gpio(void) {
 

	
 
  GPIO_InitTypeDef GPIO_InitStruct;
 

	
 
    /* GPIO Ports Clock Enable */
 
  __GPIOF_CLK_ENABLE();
 
  __GPIOA_CLK_ENABLE();
 
  __GPIOB_CLK_ENABLE();
 

	
 
   
 
  //////////////////
 
  // PORT F       //
 
  //////////////////  
 
  
 
  // PORTF OUTPUT
 
  // Configure GPIO pin : PF0
 
  GPIO_InitStruct.Pin = GPIO_PIN_0;
 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 

	
 
  // PORTF UNUSED
 
  // Configure GPIO pin : PF1
 
  GPIO_InitStruct.Pin = GPIO_PIN_1;
 
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 

	
 
  
 
  //////////////////
 
  // PORT A       //
 
  //////////////////
 
  
 
  // PORT A OUTPUT
 
  // Configure GPIO pins : PA1 PA2 PA3 PA4
 
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4;
 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  
 
  // PORTA INPUT
 
  // Configure GPIO pin : PA15 
 
  GPIO_InitStruct.Pin = GPIO_PIN_15;
 
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 
  GPIO_InitStruct.Pull = GPIO_PULLUP;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 

	
 
  // PORTA UNUSED
 
  // Configure GPIO pins : PA0 PA8
 
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_8;
 
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  
 
  // USART1 [PORTA]
 
  // Configure GPIO pins : PA9 PA10
 
  GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
 
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
  GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 

	
 
  // SPI1 [PORTA]
 
  // Configure GPIO pin : PA, MOSI, SCK 
 
  GPIO_InitStruct.GPIO_Pin = GPIO_PIN_7|GPIO_PIN_5;
 
  GPIO_InitStruct.GPIO_Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.GPIO_PuPd = GPIO_NOPULL;
 
  GPIO_InitStruct.GPIO_Speed = GPIO_SPEED_HIGH;
 
  GPIO_InitStruct.Alternate = GPIO_AF1_SPI1;
 
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_5;
 
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 
  GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  
 
  // Configure GPIO pin: PA, MISO
 
  GPIO_InitStruct.GPIO_Pin = GPIO_PIN_6;
 
  GPIO_InitStruct.GPIO_Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.GPIO_PuPd = GPIO_NOPULL;
 
  GPIO_InitStruct.GPIO_Speed = GPIO_SPEED_HIGH;
 
  GPIO_InitStruct.Alternate = GPIO_AF1_SPI1;
 
  GPIO_InitStruct.Pin = GPIO_PIN_6;
 
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 
  GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 

	
 
  // USB [PORTA]
 

	
 
  /** USB GPIO Configuration  
 
  PA11   ------> USB_DM
 
  PA12   ------> USB_DP
 
  */  
 
  // Configure GPIO pin : PA, D+, D-
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
 
  GPIO_InitStruct.GPIO_Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
 
  GPIO_InitStruct.Alternate = GPIO_AF1_USB;
 
  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
 
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 
  GPIO_InitStruct.Alternate = GPIO_AF2_USB; // Can also be AF5
 
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 

	
 
  
 
  //////////////////
 
  // PORT B       //
 
  //////////////////
 
  
 
  // PORT B UNUSED
 
  // Configure GPIO pins : PB0 PB1 PB8 
 
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_8;
 
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 

	
 
  // PORT B INPUT
 
  // Configure GPIO pins : PB3 PB4 PB5 PB6 PB7
 
  GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6 
 
                          |GPIO_PIN_7;
 
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 
  GPIO_InitStruct.Pull = GPIO_PULLUP;
 
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);  
 
  
 
  
 
  // Enable DMA clocks (Is AHB even the right thing???)
 
  //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // EMZ TODO get the right ones
 

	
 

	
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
gpio.h
Show inline comments
 
#ifndef GPIO_H
 
#define GPIO_H
 

	
 
#include <inttypes.h>
 

	
 
#define CHANGE_PERIOD_MS 100
 
#define CHANGE_ELAPSED (ticks - change_time_reset) > CHANGE_PERIOD_MS
 
#define CHANGE_RESET change_time_reset = ticks
 

	
 

	
 
void user_input(uint16_t* to_modify);
 
void init_gpio(void);
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
libraries/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h
Show inline comments
 
@@ -33,97 +33,97 @@
 
  *
 
  * 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
 
  * @{
 
  */
 
    
 
#ifndef __STM32F0xx_H
 
#define __STM32F0xx_H
 
 
#ifdef __cplusplus
 
 extern "C" {
 
#endif /* __cplusplus */
 
   
 
/** @addtogroup Library_configuration_section
 
  * @{
 
  */
 
 
/* Uncomment the line below according to the target STM32 device used in your
 
   application 
 
  */
 
 
#if !defined (STM32F030x6) && !defined (STM32F030x8) &&                           \
 
    !defined (STM32F031x6) && !defined (STM32F038xx) &&                           \
 
    !defined (STM32F042x6) && !defined (STM32F048xx) &&                           \
 
    !defined (STM32F051x8) && !defined (STM32F058xx) &&                           \
 
    !defined (STM32F071xB) && !defined (STM32F072xB) && !defined (STM32F078xx) && \
 
    !defined (STM32F091xC) && !defined (STM32F098xx)
 
  /* #define STM32F030x6 */  /*!< STM32F030x4, STM32F030x6 Devices (STM32F030xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes)              */
 
  /* #define STM32F030x8 */  /*!< STM32F030x8 Devices (STM32F030xx microcontrollers where the Flash memory is 64 Kbytes)                                              */
 
  /* #define STM32F031x6 */  /*!< STM32F031x4, STM32F031x6 Devices (STM32F031xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes)              */
 
  /* #define STM32F038xx */  /*!< STM32F038xx Devices (STM32F038xx microcontrollers where the Flash memory is 32 Kbytes)                                              */
 
  /* #define STM32F042x6 */  /*!< STM32F042x4, STM32F042x6 Devices (STM32F042xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes)              */
 
  #define STM32F042x6 /*!< STM32F042x4, STM32F042x6 Devices (STM32F042xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes)              */
 
  /* #define STM32F048x6 */  /*!< STM32F048xx Devices (STM32F042xx microcontrollers where the Flash memory is 32 Kbytes)                                              */
 
  /* #define STM32F051x8 */  /*!< STM32F051x4, STM32F051x6, STM32F051x8 Devices (STM32F051xx microcontrollers where the Flash memory ranges between 16 and 64 Kbytes) */
 
  /* #define STM32F058xx */  /*!< STM32F058xx Devices (STM32F058xx microcontrollers where the Flash memory is 64 Kbytes)                                              */
 
  /* #define STM32F071xB */  /*!< STM32F071x8, STM32F071xB Devices (STM32F071xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes)             */
 
  /* #define STM32F072xB */  /*!< STM32F072x8, STM32F072xB Devices (STM32F072xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes)             */
 
  /* #define STM32F078xx */  /*!< STM32F078xx Devices (STM32F078xx microcontrollers where the Flash memory is 128 Kbytes)                                             */
 
  /* #define STM32F091xC */  /*!< STM32F091xC Devices (STM32F091xx microcontrollers where the Flash memory is 256 Kbytes)                                             */
 
  /* #define STM32F098xx */  /*!< STM32F098xx Devices (STM32F098xx microcontrollers where the Flash memory is 256 Kbytes)                                             */
 
#endif
 
   
 
/*  Tip: To avoid modifying this file each time you need to switch between these
 
        devices, you can define the device in your toolchain compiler preprocessor.
 
  */
 
#if !defined  (USE_HAL_DRIVER)
 
/**
 
 * @brief Comment the line below if you will not use the peripherals drivers.
 
   In this case, these drivers will not be included and the application code will 
 
   be based on direct access to peripherals registers 
 
   */
 
  /*#define USE_HAL_DRIVER */
 
#endif /* USE_HAL_DRIVER */
 
 
/**
 
  * @brief CMSIS Device version number V2.1.0
 
  */
 
#define __STM32F0xx_CMSIS_DEVICE_VERSION_MAIN   (0x02) /*!< [31:24] main version */
 
#define __STM32F0xx_CMSIS_DEVICE_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version */
 
#define __STM32F0xx_CMSIS_DEVICE_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version */
 
#define __STM32F0xx_CMSIS_DEVICE_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
 
#define __STM32F0xx_CMSIS_DEVICE_VERSION        ((__CMSIS_DEVICE_VERSION_MAIN     << 24)\
 
                                                |(__CMSIS_DEVICE_HAL_VERSION_SUB1 << 16)\
 
                                                |(__CMSIS_DEVICE_HAL_VERSION_SUB2 << 8 )\
 
                                                |(__CMSIS_DEVICE_HAL_VERSION_RC))
 
                                             
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup Device_Included
 
  * @{
 
  */
 
 
#if defined(STM32F030x6)
 
  #include "stm32f030x6.h"
 
#elif defined(STM32F030x8)
 
  #include "stm32f030x8.h"
 
#elif defined(STM32F031x6)
 
  #include "stm32f031x6.h"
libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c
Show inline comments
 
@@ -37,96 +37,97 @@
 
  *        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"
 
#include "stm32f0xx_hal_conf.h" // EMZ
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_TypesDefinitions
 
  * @{
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup STM32F0xx_System_Private_Defines
 
  * @{
 
  */
 
#if !defined  (HSE_VALUE) 
 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< 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.
 
  */
libraries/STM32_USB_Device_Library/Class/CDC/usbd_cdc.c
Show inline comments
 
@@ -14,97 +14,97 @@
 
  *           
 
  *  @verbatim
 
  *      
 
  *          ===================================================================      
 
  *                                CDC Class Driver Description
 
  *          =================================================================== 
 
  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
 
  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus 
 
  *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
 
  *           This driver implements the following aspects of the specification:
 
  *             - Device descriptor management
 
  *             - Configuration descriptor management
 
  *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
 
  *             - Requests management (as described in section 6.2 in specification)
 
  *             - Abstract Control Model compliant
 
  *             - Union Functional collection (using 1 IN endpoint for control)
 
  *             - Data interface class
 
  * 
 
  *           These aspects may be enriched or modified for a specific user application.
 
  *          
 
  *            This driver doesn't implement the following aspects of the specification 
 
  *            (but it is possible to manage these features with some modifications on this driver):
 
  *             - Any class-specific aspect relative to communication classes should be managed by user application.
 
  *             - All communication classes other than PSTN are not managed
 
  *      
 
  *  @endverbatim
 
  *                                  
 
  ******************************************************************************
 
  * @attention
 
  *
 
  * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
 
  *
 
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
 
  * You may not use this file except in compliance with the License.
 
  * You may obtain a copy of the License at:
 
  *
 
  *        http://www.st.com/software_license_agreement_liberty_v2
 
  *
 
  * Unless required by applicable law or agreed to in writing, software 
 
  * distributed under the License is distributed on an "AS IS" BASIS, 
 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  * See the License for the specific language governing permissions and
 
  * limitations under the License.
 
  *
 
  ******************************************************************************
 
  */ 
 
 
/* Includes ------------------------------------------------------------------*/
 
#include "USBD_CDC.h"
 
#include "usbd_cdc.h"
 
#include "usbd_desc.h"
 
#include "usbd_ctlreq.h"
 
 
 
/** @addtogroup STM32_USB_DEVICE_LIBRARY
 
  * @{
 
  */
 
 
 
/** @defgroup USBD_CDC 
 
  * @brief usbd core module
 
  * @{
 
  */ 
 
 
/** @defgroup USBD_CDC_Private_TypesDefinitions
 
  * @{
 
  */ 
 
/**
 
  * @}
 
  */ 
 
 
 
/** @defgroup USBD_CDC_Private_Defines
 
  * @{
 
  */ 
 
/**
 
  * @}
 
  */ 
 
 
 
/** @defgroup USBD_CDC_Private_Macros
 
  * @{
 
  */ 
 
 
/**
 
  * @}
 
  */ 
 
 
 
/** @defgroup USBD_CDC_Private_FunctionPrototypes
 
  * @{
 
  */
 
 
 
static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev, 
 
                               uint8_t cfgidx);
 
 
static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, 
main.c
Show inline comments
 
#include "main.h"
 
#include <inttypes.h>
 
#include "stm32f0xx_hal_conf.h"
 
#include "usb_device.h"
 
//#include "usb_device.h"
 
#include "ssd1306.h"
 
#include "config.h"
 
#include "eeprom_min.h"
 
#include "gpio.h"
 
#include "clock.h"
 
#include "spi.h"
 
 
// USB includes
 
//#include "hw_config.h"
 
//#include "usb_lib.h"
 
//#include "usb_desc.h"
 
//#include "usb_pwr.h"
 
//#include "stringhelpers.h"
 
//#include "spi.h"
 
 
// TODO: Grab buttonpresses with interrupts
 
 
// USB Supporting Vars
 
extern __IO uint8_t Receive_Buffer[64];
 
extern __IO  uint32_t Receive_length ;
 
extern __IO  uint32_t length ;
 
uint8_t Send_Buffer[64];
 
uint32_t packet_sent=1;
 
uint32_t packet_receive=1;
 
//extern __IO uint8_t Receive_Buffer[64];
 
//extern __IO  uint32_t Receive_length ;
 
//extern __IO  uint32_t length ;
 
//uint8_t Send_Buffer[64];
 
//uint32_t packet_sent=1;
 
//uint32_t packet_receive=1;
 
 
enum tempunits {
 
    TEMP_UNITS_CELSIUS = 0,
 
    TEMP_UNITS_FAHRENHEIT,
 
};
 
 
// Globalish setting vars
 
uint8_t boottobrew = 0;
 
uint8_t temp_units = TEMP_UNITS_CELSIUS;
 
uint16_t windup_guard = 1;
 
uint16_t k_p = 1;
 
uint16_t k_i = 1;
 
uint16_t k_d = 1;
 
 
uint8_t ignore_tc_error  = 0;
 
 
// ISR ticks var
 
volatile uint32_t ticks = 0;
 
 
int16_t setpoint_brew = 0;
 
int16_t setpoint_steam = 0;
 
 
// HAL Variables
 
SPI_HandleTypeDef hspi1;
 
//extern SPI_HandleTypeDef spi1;
 
 
 
// State definition
 
enum state {
 
    STATE_IDLE = 0,
 
 
    STATE_SETP,
 
    STATE_SETI,
 
    STATE_SETD,
 
    STATE_SETSTEPS,
 
    STATE_SETWINDUP,
 
    STATE_SETBOOTTOBREW,
 
    STATE_SETUNITS,
 
 
    STATE_PREHEAT_BREW,
 
    STATE_MAINTAIN_BREW,
 
    STATE_PREHEAT_STEAM,
 
    STATE_MAINTAIN_STEAM,
 
 
    STATE_TC_ERROR
 
};
 
 
uint8_t state = STATE_IDLE;
 
 
static __IO uint32_t TimingDelay;
 
 
// Move to header file
 
void process();
 
void machine();
 
 
void restore_settings();
 
void save_settings();
 
void save_setpoints();
 
 
int main(void)
 
{
 
    // Init clocks
 
    HAL_Init();
 
    SystemClock_Config();
 
    
 
    // Init GPIO
 
    init_gpio();
 
 
    // Turn on power LED
 
    GPIO_SetBits(LED_POWER);
 
    HAL_GPIO_WritePin(LED_POWER, 1);
 
 
    // TODO: Awesome pwm of power LED (TIM4_CH4 or TIM11_CH1)
 
 
    // Configure 1ms SysTick (change if more temporal resolution needed) 
 
    RCC_ClocksTypeDef RCC_Clocks;
 
    RCC_GetClocksFreq(&RCC_Clocks);
 
    SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
 
    //RCC_ClocksTypeDef RCC_Clocks;
 
    //RCC_GetClocksFreq(&RCC_Clocks);
 
    //SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
 
 
    // Init SPI busses
 
    init_spi();
 
    //init_spi(&spi1);
 
 
    // Init USB 
 
    init_usb();
 
    //MX_USB_DEVICE_Init();
 
    
 
    // Init OLED over SPI
 
    ssd1306_Init();
 
    ssd1306_clearscreen();
 
 
    // Check for problems on startup
 
    uint8_t clock_fail = 0; // FIXME implement in system
 
    if(clock_fail) {
 
        //ssd1306_DrawStringBig("ERROR: Check Xtal", 2, 0);
 
        ssd1306_DrawStringBig("NO XTAL", 2, 0);
 
        delay(1000);
 
        ssd1306_clearscreen();
 
    }
 
 
    // Init USB
 
    //Set_System(); // hw_config.h
 
    //Set_USBClock();
 
    //SB_Interrupts_Config();
 
    //SB_Init();
 
    //SYSCFG_USBPuCmd(ENABLE);
 
    //PowerOn();
 
 
    // Startup screen 
 
    ssd1306_DrawString("therm v0.1", 1, 40);
 
    ssd1306_DrawString("protofusion.org/therm", 3, 0);
 
 
    delay(1500);
 
    ssd1306_clearscreen();
 
    
 
    restore_settings();
 
    if(boottobrew)
 
      state = STATE_PREHEAT_BREW; // Go to brew instead of idle if configured thusly
 
 
    GPIO_ResetBits(LED_STAT);
 
    HAL_GPIO_WritePin(LED_STAT, 0);
 
 
    // Main loop
 
    while(1)
 
    {
 
        // Process sensor inputs
 
        process();
 
 
        // Run state machine
 
        machine(); 
 
    }
 
}
 
 
// Read temperature and update global temp vars
 
int32_t temp = 0;
 
uint8_t temp_frac = 0;
 
uint8_t state_resume = 0;
 
 
 
// FIXME: Now this needs to work 8bits at a time, or change the port mode on the fly
 
void update_temp() {
 
    // Assert CS
 
    GPIO_ResetBits(MAX_CS);
 
    HAL_GPIO_WritePin(MAX_CS, 0);
 
    delay(1);
 
 
    // This may not clock at all... might need to send 16 bits first
 
    SPI_I2S_SendData(SPI2, 0xAAAA); // send dummy data
 
    //SPI_I2S_SendData(SPI2, 0xAA); // send dummy data
 
    uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2);
 
    // SPI_I2S_SendData(SPI2, 0xAAAA); // send dummy data
 
 
    uint8_t data[2] = {0xAA, 0xAA};
 
    //HAL_SPI_Transmit(&spi1, data, 2, 100);
 
    
 
    //OLD: SPI_I2S_SendData(SPI2, 0xAA); // send dummy data
 
    // OLD:   uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2);
 
    
 
    //HAL_SPI_Receive(&spi1, data, 2, 100);
 
 
    // Assemble data array into one var
 
    uint16_t temp_pre = data[0] & (data[1]<<8);
 
 
    if(temp_pre & 0b0000000000000010) {
 
        ssd1306_DrawString("Fatal Error", 3, 35);
 
        state = STATE_TC_ERROR;
 
    }
 
    else if(temp_pre & 0b0000000000000001 && !ignore_tc_error) {
 
        state_resume = state;
 
        state = STATE_TC_ERROR;
 
        temp = 0;
 
        temp_frac = 0;
 
    }
 
    else 
 
    {
 
        if(state == STATE_TC_ERROR)
 
        {
 
            state = state_resume;
 
            ssd1306_clearscreen();
 
        }
 
 
        uint8_t sign = temp >> 15;// top bit is sign
 
 
        temp_pre = temp_pre >> 2; // Drop 2 lowest bits
 
        temp_frac = temp_pre & 0b11; // get fractional part
 
        temp_frac *= 25; // each bit is .25 a degree, up to fixed point
 
        temp_pre = temp_pre >> 2; // Drop 2 fractional bits 
 
 
        if(sign) {
 
            temp = -temp_pre;
 
        }
 
        else {
 
            temp = temp_pre;
 
        }
 
 
        if(temp_units == TEMP_UNITS_FAHRENHEIT) {
 
            temp *= 9; // fixed point mul by 1.8
 
            temp /= 5;
 
            temp += 32;
 
 
            temp_frac *= 9;
 
            temp_frac /= 5;
 
            temp_frac += 32;
 
            temp += temp_frac/100; // add overflow to above
 
            temp_frac %= 100;
 
        }
 
    }
 
 
    // Deassert CS
 
    delay(1);
 
    GPIO_SetBits(MAX_CS);
 
    HAL_GPIO_WritePin(MAX_CS, 1);
 
}
 
 
 
// PID implementation
 
// TODO: Make struct that has the last_temp and i_state in it, pass by ref. Make struct that has other input values maybe.
 
int16_t last_pid_temp = 0;
 
uint8_t last_pid_temp_frac = 0;
 
int16_t i_state = 0;
 
 
int16_t update_pid(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint) 
 
{
 
  // Calculate instantaneous error
 
  int16_t error = (int16_t)setpoint - (int16_t)temp; // TODO: Use fixed point fraction
 
 
  // Proportional component
 
  int16_t p_term = k_p * error;
 
 
  // Error accumulator (integrator)
 
  i_state += error;
 
 
  // to prevent the iTerm getting huge despite lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // it cant help be cold despite its best efforts)
 
  // not necessary, but this makes windup guard values 
 
  // relative to the current iGain
 
  int16_t windup_guard_res = windup_guard / k_i;  
 
 
  // Calculate integral term with windup guard 
 
  if (i_state > windup_guard_res) 
 
    i_state = windup_guard_res;
 
  else if (i_state < -windup_guard_res) 
 
    i_state = -windup_guard_res;
 
  int16_t i_term = k_i * i_state;
 
 
  // Calculate differential term (slope since last iteration)
 
  int16_t d_term = (k_d * (temp - last_pid_temp));
 
 
  // Save temperature for next iteration
 
  last_pid_temp = temp;
 
  last_pid_temp_frac = temp_frac;
 
 
  int16_t result = p_term + i_term - d_term;
 
 
  // Put out tenths of percent, 0-1000. 
 
  if(result > 1000)
 
    result = 1000;
 
  else if(result < -1000)
 
    result = -1000;
 
 
  // Return feedback
 
  return result;
 
}
 
 
 
uint32_t last_ssr_on = 0;
 
uint32_t last_led = 0;
 
int32_t setpoint = 0;
 
int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD 
 
uint8_t pid_enabled = 0;
 
 
// Process things
 
void process()
 
{
 
    update_temp(); // Read MAX31855
 
 
    // TODO: Add calibration offset (linear)
 
 
    if(ticks - last_led > 400) 
 
    {
 
        GPIO_ToggleBits(LED_POWER);
 
        HAL_GPIO_TogglePin(LED_POWER);
 
        last_led = ticks;
 
    }
 
 
    // Every 200ms, set the SSR on unless output is 0
 
    if((ticks - last_ssr_on > SSR_PERIOD))
 
    {
 
        if(pid_enabled) 
 
        {
 
            // Get ssr output for next time
 
            int16_t power_percent = update_pid(k_p, k_i, k_d, temp, temp_frac, setpoint);
 
            //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;
 
        }
 
 
        // Only support heating (ssr_output > 0) right now
 
        if(ssr_output > 0) {
 
 
            char tempstr[6];
 
            itoa(ssr_output, tempstr);
 
            itoa(ssr_output, tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 90);
 
 
            GPIO_SetBits(LED_STAT);
 
            GPIO_SetBits(SSR_PIN);
 
            HAL_GPIO_WritePin(LED_STAT, 1);
 
            HAL_GPIO_WritePin(SSR_PIN, 1);
 
            last_ssr_on = ticks;
 
        }
 
    }
 
    
 
    // Kill SSR after elapsed period less than SSR_PERIOD 
 
    if(ticks - last_ssr_on > ssr_output || ssr_output == 0)
 
    {
 
        GPIO_ResetBits(LED_STAT);
 
        GPIO_ResetBits(SSR_PIN);
 
        HAL_GPIO_WritePin(LED_STAT, 0);
 
        HAL_GPIO_WritePin(SSR_PIN, 0);
 
    }
 
}
 
 
void draw_setpoint() {
 
    char tempstr[3];
 
    itoa_fp(temp, temp_frac, tempstr);
 
    ssd1306_DrawStringBig("      ", 3, 0);
 
    ssd1306_DrawStringBig(tempstr, 3, 0);
 
    ssd1306_DrawStringBig(">", 3, 74);
 
    itoa(setpoint, tempstr);
 
    itoa(setpoint, tempstr, 10);
 
    ssd1306_DrawStringBig("    ", 3, 90);
 
    ssd1306_DrawStringBig(tempstr, 3, 90);
 
}
 
 
uint8_t goto_mode = 2;
 
 
// State machine
 
uint8_t sw_btn_last = 0;
 
uint8_t sw_up_last = 0;
 
uint8_t sw_down_last = 0;
 
uint8_t sw_left_last = 0;
 
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)
 
 
void save_settings()
 
{
 
/*
 
   Minimal_EEPROM_Unlock();
 
    // Try programming a word at an address divisible by 4
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_BOOTTOBREW, boottobrew);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_WINDUP_GUARD, windup_guard);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_P, k_p);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_I, k_i);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_K_D, k_d);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS, temp_units);
 
    Minimal_EEPROM_Lock();
 
*/
 
}
 
 
void save_setpoints()
 
{
 
/*
 
 
    Minimal_EEPROM_Unlock();
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_BREWTEMP, setpoint_brew);
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_STEAMTEMP, setpoint_steam); 
 
    Minimal_EEPROM_Lock();
 
*/
 
}
 
 
 
// TODO: Make a struct that has all settings in it. Pass by ref to this func in a library.
 
void restore_settings()
 
@@ -386,380 +391,380 @@ void restore_settings()
 
    boottobrew = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_BOOTTOBREW));
 
    
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    windup_guard = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_WINDUP_GUARD));
 
    
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    k_p = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_P));
 
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    k_i = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_I));
 
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    k_d = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_K_D));
 
    
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    setpoint_brew = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_BREWTEMP));
 
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    setpoint_steam = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_STEAMTEMP));    
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    temp_units = (*(__IO uint32_t*)(EEPROM_BASE_ADDR + EEPROM_ADDR_UNITS));    
 
 
    Minimal_EEPROM_Lock(); */
 
}
 
 
int16_t last_temp = 21245;
 
 
 
///////////////////////////////////////////////////////////////////////////////////////
 
/// freaking multiple setpoint support ///
 
uint8_t step_duration[10] = {0,0,0,0,0,0,0,0,0,0};
 
int16_t step_setpoint[10] = {0,0,0,0,0,0,0,0,0,0};
 
uint8_t final_setpoint = 0;
 
 
// Multiple screens to set setpoint and duration on each screen
 
// press center to go to the next one, and press left or right or something to confirm
 
 
// When executing, complete on time AND(?) temperature. Maybe allow switching to OR via settings
 
 
////////////////////////////////////////////////////////////////////////////////////////////////
 
 
void machine()
 
{
 
    uint8_t last_state = state;
 
    
 
    uint8_t temp_changed = temp != last_temp;
 
    last_temp = temp;
 
 
    uint8_t sw_btn = !GPIO_ReadInputDataBit(SW_BTN);
 
    uint8_t sw_up = !GPIO_ReadInputDataBit(SW_UP);
 
    uint8_t sw_down = !GPIO_ReadInputDataBit(SW_DOWN);
 
    uint8_t sw_left = !GPIO_ReadInputDataBit(SW_LEFT);
 
    uint8_t sw_right = !GPIO_ReadInputDataBit(SW_RIGHT);
 
    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(state)
 
    {
 
        // Idle state
 
        case STATE_IDLE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: idle ]
 
            ssd1306_DrawString("therm :: idle ", 0, 40);
 
            pid_enabled = 0;
 
 
            if(temp_changed) {
 
                char tempstr[6];
 
                itoa_fp(temp, temp_frac, tempstr);
 
                ssd1306_DrawString("Temp: ", 3, 40);
 
                ssd1306_DrawString("    ", 3, 72);
 
                ssd1306_DrawString(tempstr, 3, 72);
 
            }
 
 
            ssd1306_drawlogo();
 
 
            switch(goto_mode) {
 
                case 2:
 
                {
 
                    ssd1306_DrawString("-> heat     ", 1, 40);
 
                } break;
 
 
                case 1:
 
                {
 
                    ssd1306_DrawString("-> setup    ", 1, 40);
 
                } break;
 
 
                case 0:
 
                {
 
                    ssd1306_DrawString("-> reset    ", 1, 40);
 
                } break;
 
            }
 
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                switch(goto_mode) {
 
                    case 2:
 
                        state = STATE_PREHEAT_BREW;
 
                        break;
 
                    case 1:
 
                        state = STATE_SETP;
 
                        break;
 
                    case 0:
 
                        state = STATE_IDLE;
 
                        break;
 
                    default:
 
                        state = STATE_PREHEAT_BREW;
 
                }
 
            }
 
            else if(SW_UP_PRESSED && goto_mode < 2) {
 
                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(k_p, tempstr);
 
            itoa(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) {
 
                state = STATE_SETI;
 
            }
 
            else {
 
                user_input(&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(k_i, tempstr);
 
            itoa(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) {
 
                state = STATE_SETD;
 
            }
 
            else {
 
                user_input(&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(k_d, tempstr);
 
            itoa(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) {
 
                state = STATE_SETWINDUP;
 
            }
 
            else {
 
                user_input(&k_d);
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_SETSTEPS:
 
        {
 
            // Write text to OLED
 
            // [ step #1:: Duration: ### ]
 
            // [           Setpoint: ### ]
 
            char tempstr[6];
 
 
            itoa(final_setpoint, tempstr);
 
            itoa(final_setpoint, tempstr, 10);
 
            ssd1306_DrawString("Step #", 0, 0);
 
            ssd1306_DrawString(tempstr, 0, 40);
 
 
            ssd1306_DrawString("Duration: ", 0, 5);
 
            itoa(step_duration[final_setpoint], tempstr);
 
            itoa(step_duration[final_setpoint], tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 70);
 
 
            ssd1306_DrawString("Setpoint: ", 0, 0);
 
            itoa(step_setpoint[final_setpoint], tempstr);
 
            itoa(step_setpoint[final_setpoint], tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 70);
 
 
            ssd1306_DrawString("Press to accept", 3, 40);
 
            
 
            // Button handler - TODO: increment max_step if pressed
 
            // return and go to next state otherwise
 
            if(SW_BTN_PRESSED) {
 
                state = STATE_SETSTEPS;
 
                final_setpoint++;
 
            }
 
        //    else if(SW_LEFT_PRESSED) {
 
        //        state++; // go to next state or something
 
        //    }
 
            else {
 
                user_input(&k_p);
 
            }
 
 
            // 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(windup_guard, tempstr);
 
            itoa(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) {
 
                state = STATE_SETBOOTTOBREW;
 
            }
 
            else {
 
                user_input(&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(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) {
 
                state = STATE_SETUNITS;
 
            }
 
            else if(!GPIO_ReadInputDataBit(SW_UP)) {
 
            else if(!HAL_GPIO_ReadPin(SW_UP)) {
 
                boottobrew = 1;
 
            }
 
            else if(!GPIO_ReadInputDataBit(SW_DOWN)) {
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                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(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) {
 
                save_settings();
 
                state = STATE_IDLE;
 
            }
 
            else if(!GPIO_ReadInputDataBit(SW_UP)) {
 
            else if(!HAL_GPIO_ReadPin(SW_UP)) {
 
                temp_units = TEMP_UNITS_FAHRENHEIT;
 
            }
 
            else if(!GPIO_ReadInputDataBit(SW_DOWN)) {
 
            else if(!HAL_GPIO_ReadPin(SW_DOWN)) {
 
                temp_units = TEMP_UNITS_CELSIUS;
 
            }
 
 
            // 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();
 
            pid_enabled = 1;
 
	    setpoint = setpoint_brew;
 
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
		save_setpoints(); // TODO: Check for mod
 
                state = STATE_IDLE;
 
            }
 
            else {
 
                user_input(&setpoint_brew);
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                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();
 
            pid_enabled = 1;
 
	    setpoint = setpoint_brew;
 
 
            // Button handler
main.h
Show inline comments
 
#ifndef __MAIN_H
 
#define __MAIN_H
 
 
#define STM32F042x6
 
 
#include "stm32f0xx_hal_conf.h"
 
 
void TimingDelay_Decrement(void);
 
void delay(__IO uint32_t nTime);
 
 
//SPI_HandleTypeDef spi1;
 
 
 
#endif /* __MAIN_H */
 
spi.c
Show inline comments
 

	
 
void init_spi(void)
 
#include "stm32f0xx_hal_conf.h"
 
/*
 
void init_spi(SPI_HandleTypeDef* hspi1)
 
{
 
  
 
    SPI_HandleTypeDef hspi1;
 
    
 
    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_8;
 
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
 
    hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
 
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
 
    hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLED;
 
    HAL_SPI_Init(&hspi1);
 
    
 
    hspi1->Instance = 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_8;
 
    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);
 
}*/    
 
    
 
    /* OLD:
 
        SPI_InitTypeDef  SPI_InitStructure;
 

	
 
    // OLED IC
 
    SPI_Cmd(SPI1, DISABLE); 
 
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
 
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
 
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
 
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
 
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
 
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 
    SPI_InitStructure.SPI_CRCPolynomial = 7;
 
    SPI_Init(SPI1, &SPI_InitStructure);
 
    SPI_Cmd(SPI1, ENABLE);          
 

	
 

	
 
    // MAX IC
 
    SPI_Cmd(SPI2, DISABLE); 
 
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
 
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
 
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; // Andysworkshop
 
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // From andysworkshop
 
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // same
 
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 
    SPI_InitStructure.SPI_CRCPolynomial = 7;
 
    SPI_Init(SPI2, &SPI_InitStructure);
 
    SPI_Cmd(SPI2, ENABLE);          
 
    */
 
}
 

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

	
 
void init_spi(void);
 
#include "stm32f0xx_hal_conf.h"
 

	
 
void init_spi(SPI_HandleTypeDef* hspi1);
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
ssd1306.c
Show inline comments
 
#include "stm32f0xx_hal_conf.h"
 
#include "ssd1306.h"
 
 
// Write command to OLED
 
void WriteCommand(unsigned char command)
 
{
 
  SSD_A0_Low();
 
  SPI_SendByte(command);
 
  SPI_Wait();
 
  //SPI_SendByte(command);
 
  //SPI_Wait();
 
}
 
 
// Write data to OLED
 
void WriteData(unsigned char data)
 
{
 
  SSD_A0_High();
 
  SPI_SendByte(data);
 
  SPI_Wait();
 
  //SPI_SendByte(data);
 
  //SPI_Wait();
 
}
 
 
// Initialize OLED
 
void ssd1306_Init(void)
 
{
 
 
  /* Generate a reset */
 
  SSD_Reset_Low();
 
  uint32_t i;
 
  for(i=5000; i>1; i--) 
 
  SSD_Reset_High();
 
 
  WriteCommand(0xAE);
 
  WriteCommand(0xD5);
 
  WriteCommand(0x80);
 
  WriteCommand(0xA8);
 
  WriteCommand(0x1F);
 
  WriteCommand(0xD3);
 
  WriteCommand(0x00);
 
  WriteCommand(0x40 | 0x00); // line #0
 
  WriteCommand(0x8D);
 
  WriteCommand(0x14); //10 or 14 if not externalvcc
 
  WriteCommand(0x20);
 
  WriteCommand(0x00);
 
//  WriteCommand(0xA0 | 0x1); // segremap (normal)
 
  WriteCommand(0xA0); // segremap (flip)
 
//  WriteCommand(0xC8); // comscandec (normal)
 
  WriteCommand(0xC0); // comscandec (flip)
 
  WriteCommand(0xDA); // setcompins 
 
  WriteCommand(0x02);
 
  WriteCommand(0x81); // contrast
 
  WriteCommand(0x0F); // contrast value. 8f is a good one.
 
  WriteCommand(0xD9);
 
  WriteCommand(0xF1); //22 or F1 if not externalvcc
 
  WriteCommand(0xDB);
 
  WriteCommand(0x40);
 
  WriteCommand(0xA4); // dispalyallon_resume
 
  WriteCommand(0xA6); // normaldisplay
 
 
 
  WriteCommand(0xAF); // display on 
 
}
 
 
 
// Times New Roman font
 
const char fontData[240][5] =
 
{                                       // Refer to "Times New Roman" Font Database
 
                                        //   Basic Characters
ssd1306.h
Show inline comments
 
#ifndef   ssd1306_H
 
#define   ssd1306_H
 
 
#define   SSD_RESET       GPIOB,GPIO_Pin_2
 
#define   SSD_A0          GPIOB,GPIO_Pin_10
 
#define   SSD_CS          GPIOB,GPIO_Pin_1
 
#define   SSD_RESET       GPIOB,GPIO_PIN_2
 
#define   SSD_A0          GPIOB,GPIO_PIN_10
 
#define   SSD_CS          GPIOB,GPIO_PIN_1
 
 
#define   SSD_Reset_Low()   GPIO_ResetBits(SSD_RESET)
 
#define   SSD_Reset_High()  GPIO_SetBits(SSD_RESET)
 
#define   SSD_A0_Low()      GPIO_ResetBits(SSD_A0)
 
#define   SSD_A0_High()     GPIO_SetBits(SSD_A0)
 
#define   SSD_CS_Low()      GPIO_ResetBits(SSD_CS)
 
#define   SSD_CS_High()     GPIO_SetBits(SSD_CS)
 
#define   SSD_Reset_Low()   HAL_GPIO_WritePin(SSD_RESET, 0)
 
#define   SSD_Reset_High()  HAL_GPIO_WritePin(SSD_RESET, 1)
 
#define   SSD_A0_Low()      HAL_GPIO_WritePin(SSD_A0, 0)
 
#define   SSD_A0_High()     HAL_GPIO_WritePin(SSD_A0, 1)
 
#define   SSD_CS_Low()      HAL_GPIO_WritePin(SSD_CS, 0)
 
#define   SSD_CS_High()     HAL_GPIO_WritePin(SSD_CS, 1)
 
 
// Use stdperiph
 
#define   SPI_SendByte(data)  SPI_I2S_SendData(SPI1,data) 
 
#define   SPI_Wait()       while(!(SPI1->SR&SPI_I2S_FLAG_TXE));while(SPI1->SR&SPI_I2S_FLAG_BSY); 
 
 
//extern SPI_HandleTypeDef spi1;
 
 
// EMZ FIXME this won't really work
 
//#define   SPI_SendByte(data)  HAL_SPI_Transmit(&spi1, 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); 
 
 
 
void ssd1306_Init(void);
 
void ssd1306_DrawChar(char ascii, unsigned char row, unsigned char xPos);
 
void ssd1306_DrawCharBig(char ascii, 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 
stm32f0xx_hal_conf.h
Show inline comments
 
@@ -18,97 +18,97 @@
 
  *      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_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)8000000) /*!< 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 */
stm32f0xx_hal_msp.c
Show inline comments
 
@@ -12,117 +12,103 @@
 
  * 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.
 
  *
 
  ******************************************************************************
 
  */
 
/* Includes ------------------------------------------------------------------*/
 
#include "stm32f0xx_hal.h"
 
 
/* USER CODE BEGIN 0 */
 
 
/* USER CODE END 0 */
 
 
/**
 
  * Initializes the Global MSP.
 
  */
 
void HAL_MspInit(void)
 
{
 
  /* USER CODE BEGIN MspInit 0 */
 
 
  /* USER CODE END MspInit 0 */
 
 
  /* System interrupt init*/
 
/* SysTick_IRQn interrupt configuration */
 
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
 
 
  /* USER CODE BEGIN MspInit 1 */
 
 
  /* USER CODE END MspInit 1 */
 
}
 
 
/*
 
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
 
{
 
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
  if(hspi->Instance==SPI1)
 
  {
 
  /* USER CODE BEGIN SPI1_MspInit 0 */
 
 
  /* USER CODE END SPI1_MspInit 0 */
 
    /* Peripheral clock enable */
 
    __SPI1_CLK_ENABLE();
 
  
 
    /**SPI1 GPIO Configuration    
 
    PA5     ------> SPI1_SCK
 
    PA6     ------> SPI1_MISO
 
    PA7     ------> SPI1_MOSI 
 
    */
 
    // SPI1 GPIO Configuration    
 
   // PA5     ------> SPI1_SCK
 
   //  PA6     ------> SPI1_MISO
 
   // PA7     ------> SPI1_MOSI 
 
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 
  /* USER CODE BEGIN SPI1_MspInit 1 */
 
 
  /* USER CODE END SPI1_MspInit 1 */
 
  }
 
 
}
 
 
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
 
{
 
 
  if(hspi->Instance==SPI1)
 
  {
 
  /* USER CODE BEGIN SPI1_MspDeInit 0 */
 
 
  /* USER CODE END SPI1_MspDeInit 0 */
 
    /* Peripheral clock disable */
 
    // Peripheral clock disable 
 
    __SPI1_CLK_DISABLE();
 
  
 
    /**SPI1 GPIO Configuration    
 
    PA5     ------> SPI1_SCK
 
    PA6     ------> SPI1_MISO
 
    PA7     ------> SPI1_MOSI 
 
    */
 
    //SPI1 GPIO Configuration    
 
   // PA5     ------> SPI1_SCK
 
   // PA6     ------> SPI1_MISO
 
   // PA7     ------> SPI1_MOSI 
 
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
 
 
  /* USER CODE BEGIN SPI1_MspDeInit 1 */
 
 
  /* USER CODE END SPI1_MspDeInit 1 */
 
  }
 
 
}
 
*/
 
 
/* USER CODE BEGIN 1 */
 
 
/* USER CODE END 1 */
 
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
system_stm32f0xx.c
Show inline comments
 
deleted file
system_stm32f0xx.h
Show inline comments
 
deleted file
0 comments (0 inline, 0 general)