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
 
	rm -f $(TARGET).hex
 
	rm -f $(TARGET).bin
 

	
 
# Display size
 
size: $(TARGET).elf
 
	@echo Invoking: ARM GNU Print Size
 
	$(SIZE) --format=berkeley $<
 
	@echo
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
 
/**
 
  ******************************************************************************
 
  * @file    stm32f0xx.h
 
  * @author  MCD Application Team
 
  * @version V2.1.0
 
  * @date    03-Oct-2014
 
  * @brief   CMSIS STM32F0xx Device Peripheral Access Layer Header File.           
 
  *            
 
  *          The file is the unique include file that the application programmer
 
  *          is using in the C source code, usually in main.c. This file contains:
 
  *           - Configuration section that allows to select:
 
  *              - The STM32F0xx device used in the target application
 
  *              - To use or not the peripheral’s drivers in application code(i.e. 
 
  *                code will be based on direct access to peripheral’s registers 
 
  *                rather than drivers API), this option is controlled by 
 
  *                "#define USE_HAL_DRIVER"
 
  *  
 
  ******************************************************************************
 
  * @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
 
  * @{
 
  */
 
    
 
#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"
 
#elif defined(STM32F038xx)
 
  #include "stm32f038xx.h"
 
#elif defined(STM32F042x6)
 
  #include "stm32f042x6.h"
 
#elif defined(STM32F048xx)
 
  #include "stm32f048xx.h"
 
#elif defined(STM32F051x8)
 
  #include "stm32f051x8.h"
 
#elif defined(STM32F058xx)
 
  #include "stm32f058xx.h"
 
#elif defined(STM32F071xB)
 
  #include "stm32f071xb.h"
 
#elif defined(STM32F072xB)
 
  #include "stm32f072xb.h"
 
#elif defined(STM32F078xx)
 
  #include "stm32f078xx.h"
 
#elif defined(STM32F091xC)
 
  #include "stm32f091xc.h"
 
#elif defined(STM32F098xx)
 
  #include "stm32f098xx.h"  
 
#else
 
 #error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
 
#endif
 
 
/**
 
  * @}
 
  */
 
 
/** @addtogroup Exported_types
 
  * @{
 
  */ 
 
typedef enum 
 
{
 
  RESET = 0, 
 
  SET = !RESET
 
} FlagStatus, ITStatus;
 
 
typedef enum 
 
{
 
  DISABLE = 0, 
 
  ENABLE = !DISABLE
 
} FunctionalState;
 
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
 
 
typedef enum 
 
{
 
  ERROR = 0, 
 
  SUCCESS = !ERROR
 
} ErrorStatus;
 
 
/**
 
  * @}
 
  */
 
 
 
/** @addtogroup Exported_macros
 
  * @{
 
  */
 
#define SET_BIT(REG, BIT)     ((REG) |= (BIT))
 
 
#define CLEAR_BIT(REG, BIT)   ((REG) &= ~(BIT))
 
 
#define READ_BIT(REG, BIT)    ((REG) & (BIT))
 
 
#define CLEAR_REG(REG)        ((REG) = (0x0))
 
 
#define WRITE_REG(REG, VAL)   ((REG) = (VAL))
 
 
#define READ_REG(REG)         ((REG))
 
 
#define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
 
 
 
/**
 
  * @}
 
  */
 
 
#if defined (USE_HAL_DRIVER)
 
 #include "stm32f0xx_hal.h"
 
#endif /* USE_HAL_DRIVER */
 
 
 
#ifdef __cplusplus
 
}
 
#endif /* __cplusplus */
 
 
#endif /* __STM32F0xx_H */
 
/**
 
  * @}
 
  */
 
 
/**
 
  * @}
 
  */
 
  
 
 
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c
Show inline comments
 
/**
 
  ******************************************************************************
 
  * @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"
 
#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.
 
  */
 
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****/
 
libraries/STM32_USB_Device_Library/Class/CDC/usbd_cdc.c
Show inline comments
 
/**
 
  ******************************************************************************
 
  * @file    usbd_cdc.c
 
  * @author  MCD Application Team
 
  * @version V2.2.0
 
  * @date    13-June-2014
 
  * @brief   This file provides the high layer firmware functions to manage the 
 
  *          following functionalities of the USB CDC Class:
 
  *           - Initialization and Configuration of high and low layer
 
  *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
 
  *           - OUT/IN data transfer
 
  *           - Command IN transfer (class requests management)
 
  *           - Error management
 
  *           
 
  *  @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, 
 
                                 uint8_t cfgidx);
 
 
static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev, 
 
                                USBD_SetupReqTypedef *req);
 
 
static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, 
 
                                 uint8_t epnum);
 
 
static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, 
 
                                 uint8_t epnum);
 
 
static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev);
 
 
static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length);
 
 
static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length);
 
 
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
 
 
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
 
 
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length);
 
 
/* USB Standard Device Descriptor */
 
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
 
{
 
  USB_LEN_DEV_QUALIFIER_DESC,
 
  USB_DESC_TYPE_DEVICE_QUALIFIER,
 
  0x00,
 
  0x02,
 
  0x00,
 
  0x00,
 
  0x00,
 
  0x40,
 
  0x01,
 
  0x00,
 
};
 
 
/**
 
  * @}
 
  */ 
 
 
/** @defgroup USBD_CDC_Private_Variables
 
  * @{
 
  */ 
 
 
 
/* CDC interface class callbacks structure */
 
USBD_ClassTypeDef  USBD_CDC = 
 
{
 
  USBD_CDC_Init,
 
  USBD_CDC_DeInit,
 
  USBD_CDC_Setup,
 
  NULL,                 /* EP0_TxSent, */
 
  USBD_CDC_EP0_RxReady,
 
  USBD_CDC_DataIn,
 
  USBD_CDC_DataOut,
 
  NULL,
 
  NULL,
 
  NULL,     
 
  USBD_CDC_GetHSCfgDesc,  
 
  USBD_CDC_GetFSCfgDesc,    
 
  USBD_CDC_GetOtherSpeedCfgDesc, 
 
  USBD_CDC_GetDeviceQualifierDescriptor,
 
};
 
 
/* USB CDC device Configuration Descriptor */
 
__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
 
{
 
  /*Configuration Descriptor*/
 
  0x09,   /* bLength: Configuration Descriptor size */
 
  USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
 
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
 
  0x00,
 
  0x02,   /* bNumInterfaces: 2 interface */
 
  0x01,   /* bConfigurationValue: Configuration value */
 
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
 
  0xC0,   /* bmAttributes: self powered */
 
  0x32,   /* MaxPower 0 mA */
 
  
 
  /*---------------------------------------------------------------------------*/
 
  
 
  /*Interface Descriptor */
 
  0x09,   /* bLength: Interface Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
 
  /* Interface descriptor type */
 
  0x00,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x01,   /* bNumEndpoints: One endpoints used */
 
  0x02,   /* bInterfaceClass: Communication Interface Class */
 
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
 
  0x01,   /* bInterfaceProtocol: Common AT commands */
 
  0x00,   /* iInterface: */
 
  
 
  /*Header Functional Descriptor*/
 
  0x05,   /* bLength: Endpoint Descriptor size */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x00,   /* bDescriptorSubtype: Header Func Desc */
 
  0x10,   /* bcdCDC: spec release number */
 
  0x01,
 
  
 
  /*Call Management Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
 
  0x00,   /* bmCapabilities: D0+D1 */
 
  0x01,   /* bDataInterface: 1 */
 
  
 
  /*ACM Functional Descriptor*/
 
  0x04,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
 
  0x02,   /* bmCapabilities */
 
  
 
  /*Union Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x06,   /* bDescriptorSubtype: Union func desc */
 
  0x00,   /* bMasterInterface: Communication class interface */
 
  0x01,   /* bSlaveInterface0: Data Class Interface */
 
  
 
  /*Endpoint 2 Descriptor*/
 
  0x07,                           /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
 
  CDC_CMD_EP,                     /* bEndpointAddress */
 
  0x03,                           /* bmAttributes: Interrupt */
 
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
 
  HIBYTE(CDC_CMD_PACKET_SIZE),
 
  0x10,                           /* bInterval: */ 
 
  /*---------------------------------------------------------------------------*/
 
  
 
  /*Data class interface descriptor*/
 
  0x09,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
 
  0x01,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x02,   /* bNumEndpoints: Two endpoints used */
 
  0x0A,   /* bInterfaceClass: CDC */
 
  0x00,   /* bInterfaceSubClass: */
 
  0x00,   /* bInterfaceProtocol: */
 
  0x00,   /* iInterface: */
 
  
 
  /*Endpoint OUT Descriptor*/
 
  0x07,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
 
  CDC_OUT_EP,                        /* bEndpointAddress */
 
  0x02,                              /* bmAttributes: Bulk */
 
  LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
 
  HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
 
  0x00,                              /* bInterval: ignore for Bulk transfer */
 
  
 
  /*Endpoint IN Descriptor*/
 
  0x07,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
 
  CDC_IN_EP,                         /* bEndpointAddress */
 
  0x02,                              /* bmAttributes: Bulk */
 
  LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
 
  HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
 
  0x00                               /* bInterval: ignore for Bulk transfer */
 
} ;
 
 
 
/* USB CDC device Configuration Descriptor */
 
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
 
{
 
  /*Configuration Descriptor*/
 
  0x09,   /* bLength: Configuration Descriptor size */
 
  USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
 
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
 
  0x00,
 
  0x02,   /* bNumInterfaces: 2 interface */
 
  0x01,   /* bConfigurationValue: Configuration value */
 
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
 
  0xC0,   /* bmAttributes: self powered */
 
  0x32,   /* MaxPower 0 mA */
 
  
 
  /*---------------------------------------------------------------------------*/
 
  
 
  /*Interface Descriptor */
 
  0x09,   /* bLength: Interface Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
 
  /* Interface descriptor type */
 
  0x00,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x01,   /* bNumEndpoints: One endpoints used */
 
  0x02,   /* bInterfaceClass: Communication Interface Class */
 
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
 
  0x01,   /* bInterfaceProtocol: Common AT commands */
 
  0x00,   /* iInterface: */
 
  
 
  /*Header Functional Descriptor*/
 
  0x05,   /* bLength: Endpoint Descriptor size */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x00,   /* bDescriptorSubtype: Header Func Desc */
 
  0x10,   /* bcdCDC: spec release number */
 
  0x01,
 
  
 
  /*Call Management Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
 
  0x00,   /* bmCapabilities: D0+D1 */
 
  0x01,   /* bDataInterface: 1 */
 
  
 
  /*ACM Functional Descriptor*/
 
  0x04,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
 
  0x02,   /* bmCapabilities */
 
  
 
  /*Union Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x06,   /* bDescriptorSubtype: Union func desc */
 
  0x00,   /* bMasterInterface: Communication class interface */
 
  0x01,   /* bSlaveInterface0: Data Class Interface */
 
  
 
  /*Endpoint 2 Descriptor*/
 
  0x07,                           /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
 
  CDC_CMD_EP,                     /* bEndpointAddress */
 
  0x03,                           /* bmAttributes: Interrupt */
 
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
 
  HIBYTE(CDC_CMD_PACKET_SIZE),
 
  0x10,                           /* bInterval: */ 
 
  /*---------------------------------------------------------------------------*/
 
  
 
  /*Data class interface descriptor*/
 
  0x09,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
 
  0x01,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x02,   /* bNumEndpoints: Two endpoints used */
 
  0x0A,   /* bInterfaceClass: CDC */
 
  0x00,   /* bInterfaceSubClass: */
 
  0x00,   /* bInterfaceProtocol: */
 
  0x00,   /* iInterface: */
 
  
 
  /*Endpoint OUT Descriptor*/
 
  0x07,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
 
  CDC_OUT_EP,                        /* bEndpointAddress */
 
  0x02,                              /* bmAttributes: Bulk */
 
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
 
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
 
  0x00,                              /* bInterval: ignore for Bulk transfer */
 
  
 
  /*Endpoint IN Descriptor*/
 
  0x07,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
 
  CDC_IN_EP,                         /* bEndpointAddress */
 
  0x02,                              /* bmAttributes: Bulk */
 
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
 
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
 
  0x00                               /* bInterval: ignore for Bulk transfer */
 
} ;
 
 
__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
 
{ 
 
  0x09,   /* bLength: Configuation Descriptor size */
 
  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
 
  USB_CDC_CONFIG_DESC_SIZ,
 
  0x00,
 
  0x02,   /* bNumInterfaces: 2 interfaces */
 
  0x01,   /* bConfigurationValue: */
 
  0x04,   /* iConfiguration: */
 
  0xC0,   /* bmAttributes: */
 
  0x32,   /* MaxPower 100 mA */  
 
  
 
  /*Interface Descriptor */
 
  0x09,   /* bLength: Interface Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
 
  /* Interface descriptor type */
 
  0x00,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x01,   /* bNumEndpoints: One endpoints used */
 
  0x02,   /* bInterfaceClass: Communication Interface Class */
 
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
 
  0x01,   /* bInterfaceProtocol: Common AT commands */
 
  0x00,   /* iInterface: */
 
  
 
  /*Header Functional Descriptor*/
 
  0x05,   /* bLength: Endpoint Descriptor size */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x00,   /* bDescriptorSubtype: Header Func Desc */
 
  0x10,   /* bcdCDC: spec release number */
 
  0x01,
 
  
 
  /*Call Management Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
 
  0x00,   /* bmCapabilities: D0+D1 */
 
  0x01,   /* bDataInterface: 1 */
 
  
 
  /*ACM Functional Descriptor*/
 
  0x04,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
 
  0x02,   /* bmCapabilities */
 
  
 
  /*Union Functional Descriptor*/
 
  0x05,   /* bFunctionLength */
 
  0x24,   /* bDescriptorType: CS_INTERFACE */
 
  0x06,   /* bDescriptorSubtype: Union func desc */
 
  0x00,   /* bMasterInterface: Communication class interface */
 
  0x01,   /* bSlaveInterface0: Data Class Interface */
 
  
 
  /*Endpoint 2 Descriptor*/
 
  0x07,                           /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT      ,   /* bDescriptorType: Endpoint */
 
  CDC_CMD_EP,                     /* bEndpointAddress */
 
  0x03,                           /* bmAttributes: Interrupt */
 
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
 
  HIBYTE(CDC_CMD_PACKET_SIZE),
 
  0xFF,                           /* bInterval: */
 
  
 
  /*---------------------------------------------------------------------------*/
 
  
 
  /*Data class interface descriptor*/
 
  0x09,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
 
  0x01,   /* bInterfaceNumber: Number of Interface */
 
  0x00,   /* bAlternateSetting: Alternate setting */
 
  0x02,   /* bNumEndpoints: Two endpoints used */
 
  0x0A,   /* bInterfaceClass: CDC */
 
  0x00,   /* bInterfaceSubClass: */
 
  0x00,   /* bInterfaceProtocol: */
 
  0x00,   /* iInterface: */
 
  
 
  /*Endpoint OUT Descriptor*/
 
  0x07,   /* bLength: Endpoint Descriptor size */
 
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
 
  CDC_OUT_EP,                        /* bEndpointAddress */
 
  0x02,                              /* bmAttributes: Bulk */
 
  0x40,                              /* wMaxPacketSize: */
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()
 
{
 
/*    Minimal_EEPROM_Unlock();
 
    while(Minimal_FLASH_GetStatus()==FLASH_BUSY);
 
    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
 
            if(SW_BTN_PRESSED) {
 
		save_setpoints(); // TODO: Check for mod
 
                state = STATE_IDLE;
 
            }
 
            else {
 
                user_input(&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();
 
            pid_enabled = 1;
 
	    setpoint = setpoint_steam;
 
	    
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                state = STATE_IDLE;
 
		save_setpoints(); // TODO: Check for mod
 
            }
 
            else {
 
                user_input(&setpoint_steam);
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                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();
 
            pid_enabled = 1;
 
	    setpoint = setpoint_steam;
 
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                state = STATE_IDLE;
 
		save_setpoints(); // TODO: Check for mod
 
            }
 
            else {
 
                user_input(&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);
 
            ssd1306_DrawString("Connect thermocouple", 1, 0);
 
            ssd1306_DrawString("Press -> to ignore", 3, 0);
 
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                state = STATE_IDLE;
 
            }
 
            else if(SW_RIGHT_PRESSED) {
 
                ignore_tc_error = 1;
 
                state = STATE_IDLE;
 
            }
 
            // Event Handler
 
            // Maybe handle if TC is plugged in
 
            // N/A
 
 
 
        } break;
 
 
        // Something is terribly wrong
 
        default:
 
        {
 
            state = STATE_IDLE;
 
            pid_enabled = 0;
 
 
        } break;
 
            
 
    }
 
 
    if(last_state != state) {
 
        // Clear screen on state change
 
        goto_mode = 2;
 
        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;
 
}
 
 
// Delay a number of systicks
 
void delay(__IO uint32_t nTime)
 
{
 
  TimingDelay = nTime;
 
  while(TimingDelay != 0);
 
}
 
 
// ISR-triggered decrement of delay and increment of tickcounter
 
void TimingDelay_Decrement(void)
 
{
 
  if (TimingDelay != 0x00)
 
  { 
 
    TimingDelay--;
 
  }
 
  ticks++;
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
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
 
    {0x00,0x00,0x00,0x00,0x00},         //   (  0)    - 0x0020 No-Break Space
 
    {0x00,0x00,0x4F,0x00,0x00},         //   (  1)  ! - 0x0021 Exclamation Mark
 
    {0x00,0x07,0x00,0x07,0x00},         //   (  2)  " - 0x0022 Quotation Mark
 
    {0x14,0x7F,0x14,0x7F,0x14},         //   (  3)  # - 0x0023 Number Sign
 
    {0x24,0x2A,0x7F,0x2A,0x12},         //   (  4)  $ - 0x0024 Dollar Sign
 
    {0x23,0x13,0x08,0x64,0x62},         //   (  5)  % - 0x0025 Percent Sign
 
    {0x36,0x49,0x55,0x22,0x50},         //   (  6)  & - 0x0026 Ampersand
 
    {0x00,0x05,0x03,0x00,0x00},         //   (  7)  ' - 0x0027 Apostrophe
 
    {0x00,0x1C,0x22,0x41,0x00},         //   (  8)  ( - 0x0028 Left Parenthesis
 
    {0x00,0x41,0x22,0x1C,0x00},         //   (  9)  ) - 0x0029 Right Parenthesis
 
    {0x14,0x08,0x3E,0x08,0x14},         //   ( 10)  * - 0x002A Asterisk
 
    {0x08,0x08,0x3E,0x08,0x08},         //   ( 11)  + - 0x002B Plus Sign
 
    {0x00,0x50,0x30,0x00,0x00},         //   ( 12)  , - 0x002C Comma
 
    {0x08,0x08,0x08,0x08,0x08},         //   ( 13)  - - 0x002D Hyphen-Minus
 
    {0x00,0x60,0x60,0x00,0x00},         //   ( 14)  . - 0x002E Full Stop
 
    {0x20,0x10,0x08,0x04,0x02},         //   ( 15)  / - 0x002F Solidus
 
    {0x3E,0x51,0x49,0x45,0x3E},         //   ( 16)  0 - 0x0030 Digit Zero
 
    {0x00,0x42,0x7F,0x40,0x00},         //   ( 17)  1 - 0x0031 Digit One
 
    {0x42,0x61,0x51,0x49,0x46},         //   ( 18)  2 - 0x0032 Digit Two
 
    {0x21,0x41,0x45,0x4B,0x31},         //   ( 19)  3 - 0x0033 Digit Three
 
    {0x18,0x14,0x12,0x7F,0x10},         //   ( 20)  4 - 0x0034 Digit Four
 
    {0x27,0x45,0x45,0x45,0x39},         //   ( 21)  5 - 0x0035 Digit Five
 
    {0x3C,0x4A,0x49,0x49,0x30},         //   ( 22)  6 - 0x0036 Digit Six
 
    {0x01,0x71,0x09,0x05,0x03},         //   ( 23)  7 - 0x0037 Digit Seven
 
    {0x36,0x49,0x49,0x49,0x36},         //   ( 24)  8 - 0x0038 Digit Eight
 
    {0x06,0x49,0x49,0x29,0x1E},         //   ( 25)  9 - 0x0039 Dight Nine
 
    {0x00,0x36,0x36,0x00,0x00},         //   ( 26)  : - 0x003A Colon
 
    {0x00,0x56,0x36,0x00,0x00},         //   ( 27)  ; - 0x003B Semicolon
 
    {0x08,0x14,0x22,0x41,0x00},         //   ( 28)  < - 0x003C Less-Than Sign
 
    {0x14,0x14,0x14,0x14,0x14},         //   ( 29)  = - 0x003D Equals Sign
 
    {0x00,0x41,0x22,0x14,0x08},         //   ( 30)  > - 0x003E Greater-Than Sign
 
    {0x02,0x01,0x51,0x09,0x06},         //   ( 31)  ? - 0x003F Question Mark
 
    {0x32,0x49,0x79,0x41,0x3E},         //   ( 32)  @ - 0x0040 Commercial At
 
    {0x7E,0x11,0x11,0x11,0x7E},         //   ( 33)  A - 0x0041 Latin Capital Letter A
 
    {0x7F,0x49,0x49,0x49,0x36},         //   ( 34)  B - 0x0042 Latin Capital Letter B
 
    {0x3E,0x41,0x41,0x41,0x22},         //   ( 35)  C - 0x0043 Latin Capital Letter C
 
    {0x7F,0x41,0x41,0x22,0x1C},         //   ( 36)  D - 0x0044 Latin Capital Letter D
 
    {0x7F,0x49,0x49,0x49,0x41},         //   ( 37)  E - 0x0045 Latin Capital Letter E
 
    {0x7F,0x09,0x09,0x09,0x01},         //   ( 38)  F - 0x0046 Latin Capital Letter F
 
    {0x3E,0x41,0x49,0x49,0x7A},         //   ( 39)  G - 0x0047 Latin Capital Letter G
 
    {0x7F,0x08,0x08,0x08,0x7F},         //   ( 40)  H - 0x0048 Latin Capital Letter H
 
    {0x00,0x41,0x7F,0x41,0x00},         //   ( 41)  I - 0x0049 Latin Capital Letter I
 
    {0x20,0x40,0x41,0x3F,0x01},         //   ( 42)  J - 0x004A Latin Capital Letter J
 
    {0x7F,0x08,0x14,0x22,0x41},         //   ( 43)  K - 0x004B Latin Capital Letter K
 
    {0x7F,0x40,0x40,0x40,0x40},         //   ( 44)  L - 0x004C Latin Capital Letter L
 
    {0x7F,0x02,0x0C,0x02,0x7F},         //   ( 45)  M - 0x004D Latin Capital Letter M
 
    {0x7F,0x04,0x08,0x10,0x7F},         //   ( 46)  N - 0x004E Latin Capital Letter N
 
    {0x3E,0x41,0x41,0x41,0x3E},         //   ( 47)  O - 0x004F Latin Capital Letter O
 
    {0x7F,0x09,0x09,0x09,0x06},         //   ( 48)  P - 0x0050 Latin Capital Letter P
 
    {0x3E,0x41,0x51,0x21,0x5E},         //   ( 49)  Q - 0x0051 Latin Capital Letter Q
 
    {0x7F,0x09,0x19,0x29,0x46},         //   ( 50)  R - 0x0052 Latin Capital Letter R
 
    {0x46,0x49,0x49,0x49,0x31},         //   ( 51)  S - 0x0053 Latin Capital Letter S
 
    {0x01,0x01,0x7F,0x01,0x01},         //   ( 52)  T - 0x0054 Latin Capital Letter T
 
    {0x3F,0x40,0x40,0x40,0x3F},         //   ( 53)  U - 0x0055 Latin Capital Letter U
 
    {0x1F,0x20,0x40,0x20,0x1F},         //   ( 54)  V - 0x0056 Latin Capital Letter V
 
    {0x3F,0x40,0x38,0x40,0x3F},         //   ( 55)  W - 0x0057 Latin Capital Letter W
 
    {0x63,0x14,0x08,0x14,0x63},         //   ( 56)  X - 0x0058 Latin Capital Letter X
 
    {0x07,0x08,0x70,0x08,0x07},         //   ( 57)  Y - 0x0059 Latin Capital Letter Y
 
    {0x61,0x51,0x49,0x45,0x43},         //   ( 58)  Z - 0x005A Latin Capital Letter Z
 
    {0x00,0x7F,0x41,0x41,0x00},         //   ( 59)  [ - 0x005B Left Square Bracket
 
    {0x02,0x04,0x08,0x10,0x20},         //   ( 60)  \ - 0x005C Reverse Solidus
 
    {0x00,0x41,0x41,0x7F,0x00},         //   ( 61)  ] - 0x005D Right Square Bracket
 
    {0x04,0x02,0x01,0x02,0x04},         //   ( 62)  ^ - 0x005E Circumflex Accent
 
    {0x40,0x40,0x40,0x40,0x40},         //   ( 63)  _ - 0x005F Low Line
 
    {0x01,0x02,0x04,0x00,0x00},         //   ( 64)  ` - 0x0060 Grave Accent
 
    {0x20,0x54,0x54,0x54,0x78},         //   ( 65)  a - 0x0061 Latin Small Letter A
 
    {0x7F,0x48,0x44,0x44,0x38},         //   ( 66)  b - 0x0062 Latin Small Letter B
 
    {0x38,0x44,0x44,0x44,0x20},         //   ( 67)  c - 0x0063 Latin Small Letter C
 
    {0x38,0x44,0x44,0x48,0x7F},         //   ( 68)  d - 0x0064 Latin Small Letter D
 
    {0x38,0x54,0x54,0x54,0x18},         //   ( 69)  e - 0x0065 Latin Small Letter E
 
    {0x08,0x7E,0x09,0x01,0x02},         //   ( 70)  f - 0x0066 Latin Small Letter F
 
    {0x06,0x49,0x49,0x49,0x3F},         //   ( 71)  g - 0x0067 Latin Small Letter G
 
    {0x7F,0x08,0x04,0x04,0x78},         //   ( 72)  h - 0x0068 Latin Small Letter H
 
    {0x00,0x44,0x7D,0x40,0x00},         //   ( 73)  i - 0x0069 Latin Small Letter I
 
    {0x20,0x40,0x44,0x3D,0x00},         //   ( 74)  j - 0x006A Latin Small Letter J
 
    {0x7F,0x10,0x28,0x44,0x00},         //   ( 75)  k - 0x006B Latin Small Letter K
 
    {0x00,0x41,0x7F,0x40,0x00},         //   ( 76)  l - 0x006C Latin Small Letter L
 
    {0x7C,0x04,0x18,0x04,0x7C},         //   ( 77)  m - 0x006D Latin Small Letter M
 
    {0x7C,0x08,0x04,0x04,0x78},         //   ( 78)  n - 0x006E Latin Small Letter N
 
    {0x38,0x44,0x44,0x44,0x38},         //   ( 79)  o - 0x006F Latin Small Letter O
 
    {0x7C,0x14,0x14,0x14,0x08},         //   ( 80)  p - 0x0070 Latin Small Letter P
 
    {0x08,0x14,0x14,0x18,0x7C},         //   ( 81)  q - 0x0071 Latin Small Letter Q
 
    {0x7C,0x08,0x04,0x04,0x08},         //   ( 82)  r - 0x0072 Latin Small Letter R
 
    {0x48,0x54,0x54,0x54,0x20},         //   ( 83)  s - 0x0073 Latin Small Letter S
 
    {0x04,0x3F,0x44,0x40,0x20},         //   ( 84)  t - 0x0074 Latin Small Letter T
 
    {0x3C,0x40,0x40,0x20,0x7C},         //   ( 85)  u - 0x0075 Latin Small Letter U
 
    {0x1C,0x20,0x40,0x20,0x1C},         //   ( 86)  v - 0x0076 Latin Small Letter V
 
    {0x3C,0x40,0x30,0x40,0x3C},         //   ( 87)  w - 0x0077 Latin Small Letter W
 
    {0x44,0x28,0x10,0x28,0x44},         //   ( 88)  x - 0x0078 Latin Small Letter X
 
    {0x0C,0x50,0x50,0x50,0x3C},         //   ( 89)  y - 0x0079 Latin Small Letter Y
 
    {0x44,0x64,0x54,0x4C,0x44},         //   ( 90)  z - 0x007A Latin Small Letter Z
 
    {0x00,0x08,0x36,0x41,0x00},         //   ( 91)  { - 0x007B Left Curly Bracket
 
    {0x00,0x00,0x7F,0x00,0x00},         //   ( 92)  | - 0x007C Vertical Line
 
    {0x00,0x41,0x36,0x08,0x00},         //   ( 93)  } - 0x007D Right Curly Bracket
 
    {0x02,0x01,0x02,0x04,0x02},         //   ( 94)  ~ - 0x007E Tilde
 
    {0x08,0x14,0x2A,0x14,0x22},         //   ( 95) << - 0x00AB Left-Pointing Double Angle Quotation Mark
 
    {0x00,0x02,0x05,0x02,0x00},         //   ( 96)    - 0x00B0 Degree Sign
 
    {0x44,0x44,0x5F,0x44,0x44},         //   ( 97) +- - 0x00B1 Plus-Minus Sign
 
    {0x7E,0x20,0x20,0x10,0x3E},         //   ( 98)  u - 0x00B5 Micro Sign
 
    {0x22,0x14,0x2A,0x14,0x08},         //   ( 99) >> - 0x00BB Right-Pointing Double Angle Quotation Mark
 
    {0x30,0x48,0x45,0x40,0x20},         //   (100)  ? - 0x00BF Inverted Question Mark
 
    {0x22,0x14,0x08,0x14,0x22},         //   (101)  x - 0x00D7 Multiplcation Sign
 
    {0x08,0x08,0x2A,0x08,0x08},         //   (102)  + - 0x00F7 Division Sign
 
    {0x18,0x14,0x08,0x14,0x0C},         //   (103)    - 0x221E Infinity
 
    {0x44,0x4A,0x4A,0x51,0x51},         //   (104)  < - 0x2264 Less-Than or Equal to
 
    {0x51,0x51,0x4A,0x4A,0x44},         //   (105)  > - 0x2265 Greater-Than or Equal to
 
    {0x54,0x14,0x64,0x08,0x70},         //   (106)  .: - RF Symbol
 
    {0x70,0x7C,0x72,0x7C,0x70},         //   (107)  ^ - Lock symbol
 
    {0x70,0x5C,0x52,0x54,0x70},         //   (108)  / - Unlock symbol
 
    {0x0C,0x1E,0x3C,0x1E,0x0C},         //   (109)  <3 - Heart Symbol
 
    {0x18,0x22,0xFF,0x12,0x0C},         //   (110)  U - USB Symbol
 
};
 
 
 
void setStartPage(unsigned char d)
 
{
 
    WriteCommand(0xB0|d);       // Set Page Start Address for Page Addressing Mode
 
                                // Default => 0xB0 (0x00)
 
}
 
/* Below are functions used to configure the OLED */
 
void setStartColumn(unsigned char d)
 
{
 
    WriteCommand(0x00+d%16);    // Set Lower Column Start Address for Page Addressing Mode
 
    WriteCommand(0x10+d/16);    // Set Higher Column Start Address for Page Addressing Mode
 
                                // Default => 0x10
 
}
 
 
 
const uint8_t row[4][32] = { 
 
 
	{0x00,0x00,0x01,0x03,0x07,0x0F,0x1E,0x3C,0x3C,0x7C,0x7C,0x7C,0xFC,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFF,0x7F,0x7F,0x7F,0x3C,0x3C,0x1C,0x0C,0x06,0x03,0x01,0x00,0x00},
 
 
	{0x0F,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x3F,0x3F,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x7F,0x0F},
 
 
	{0xF0,0xFE,0xFF,0xFF,0xFF,0xC7,0x00,0x00,0x00,0x00,0x87,0xC7,0xC7,0xFF,0xFF,0x00,0x00,0x00,0x00,0x87,0x87,0xC7,0xC3,0x03,0x07,0x07,0x0F,0x7F,0xFF,0xFF,0xFE,0xF0},
 
 
	{0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFC,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0x1F,0x1F,0x1F,0x1F,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00},
 
 
};
 
 
void ssd1306_clearscreen()
 
{
 
    uint8_t i = 0;
 
    uint8_t page = 0;
 
    for(page = 0; page<4; page++)
 
    {
 
        setStartPage(page);
 
        setStartColumn(0);
 
        for(i = 0; i<128; i++)
 
        {
 
            WriteData(0x00);
 
        }
 
    }
 
    WriteData(0x00);
 
}
 
 
void ssd1306_drawlogo()
 
{
 
    uint8_t i = 0;
 
    setStartPage(3);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[0][i]);
 
    }
 
 
    WriteData(0x00);
 
 
    setStartPage(2);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[1][i]);
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(1);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[2][i]);
 
    }
 
    WriteData(0x00);
 
 
    setStartPage(0);
 
    setStartColumn(0);
 
    for(i = 0; i<32; i++)
 
    {
 
        WriteData(row[3][i]);
 
    }
 
    WriteData(0x00);
 
}
 
 
/* Print a single character from font.cpp */
 
void ssd1306_DrawChar(char ascii, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer = -1;
 
    unsigned char i;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    for(i=0;i<5;i++)
 
    {
 
        WriteData(*srcPointer);
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
}
 
 
void ssd1306_DrawCharBig(char ascii, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer = -1;
 
    unsigned char i;
 
 
    srcPointer = &fontData[(ascii-32)][0];
 
 
    setStartPage(row-1);
 
    setStartColumn(xPos);
 
 
    // Write first row
 
    for(i=0;i<5;i++)
 
    {
 
        uint8_t data = 0;
 
        data |= ((*srcPointer) & 0b1000) << 4; // get top 4 bits
 
        data |= ((*srcPointer) & 0b1000) << 3; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0100) << 3; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0100) << 2; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0010) << 2; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0010) << 1; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b0001) << 1; // get top 4 bits
 
        data |= ((*srcPointer) & 0b0001); // get top 4 bits
 
 
        WriteData(data);
 
        WriteData(data);
 
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
 
    srcPointer -= 5;
 
 
    setStartPage(row);
 
    setStartColumn(xPos);
 
 
    // Write second row
 
    for(i=0;i<5;i++)
 
    {
 
        uint8_t data = 0;
 
        data |=  (*srcPointer) & 0b10000000; // get top 4 bits
 
        data |= ((*srcPointer) & 0b10000000) >> 1; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b01000000) >> 1; // get top 4 bits
 
        data |= ((*srcPointer) & 0b01000000) >> 2; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b00100000) >> 2; // get top 4 bits
 
        data |= ((*srcPointer) & 0b00100000) >> 3; // get top 4 bits
 
 
        data |= ((*srcPointer) & 0b00010000) >> 3; // get top 4 bits
 
        data |= ((*srcPointer) & 0b00010000) >> 4; // get top 4 bits
 
 
        WriteData(data);
 
        WriteData(data);
 
 
        srcPointer++;
 
    }
 
    WriteData(0x00);
 
 
 
}
 
 
void ssd1306_DrawString(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer;
 
 
    srcPointer = (char*)dataPtr;
 
    ssd1306_DrawChar(' ',row,xPos); // NBSP must be written first before the string start
 
 
    while(1)
 
    {
 
        ssd1306_DrawChar(*srcPointer,row,xPos);
 
        srcPointer++;
 
        xPos+=6;
 
        if(*srcPointer == 0) break;
 
    }
 
}
 
 
 
void ssd1306_DrawStringBig(const char *dataPtr, unsigned char row, unsigned char xPos)
 
{
 
    char *srcPointer;
 
 
    srcPointer = (char*)dataPtr;
 
    ssd1306_DrawCharBig(' ',row,xPos); // NBSP must be written first before the string start
 
 
    while(1)
 
    {
 
        ssd1306_DrawCharBig(*srcPointer,row,xPos);
 
        srcPointer++;
 
        xPos+=12;
 
        if(*srcPointer == 0) break;
 
    }
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
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
 
/**
 
  ******************************************************************************
 
  * @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_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 */
 
#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              1              
 
#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****/
stm32f0xx_hal_msp.c
Show inline comments
 
/**
 
  ******************************************************************************
 
  * File Name          : stm32f0xx_hal_msp.c
 
  * Date               : 03/01/2015 14:04:02
 
  * Description        : This file provides code for the MSP Initialization 
 
  *                      and de-Initialization codes.
 
  ******************************************************************************
 
  *
 
  * COPYRIGHT(c) 2015 STMicroelectronics
 
  *
 
  * 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.
 
  *
 
  ******************************************************************************
 
  */
 
/* 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)