Changeset - 49485c1fefae
[Not reviewed]
cortex-f0
2 7 2
Ethan Zonca - 9 years ago 2015-08-23 19:00:35
ez@ethanzonca.com
Migrate sysclk, cleanup
9 files changed with 49 insertions and 49 deletions:
0 comments (0 inline, 0 general)
Makefile
Show inline comments
 
# STM32F0xx Makefile
 
# #####################################
 
#
 
# Part of the uCtools project
 
# uctools.github.com
 
#
 
#######################################
 
# user configuration:
 
#######################################
 

	
 

	
 
# SOURCES: list of sources in the user application
 
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c gpio.c spi.c ssd1306.c stringhelpers.c display.c bootlib.c storage.c flash.c max31855.c
 
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c gpio.c spi.c ssd1306.c stringhelpers.c display.c syslib.c storage.c flash.c max31855.c max31865.c
 

	
 
# TARGET: name of the user application
 
TARGET = main
 

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

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

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

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

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

	
 
# TARGET_DEVICE: device to compile for
 
TARGET_DEVICE = STM32F042x6
 

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

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

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

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

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

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

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

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

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

	
 
CUBELIB = $(CUBELIB_BUILD_DIR)/libstm32cube.a
 

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

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

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

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

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

	
 
// Temperature sensor type
 
#define MAX31855_TC_SENSOR
 
//#define MAX31865_RTD_SENSOR
 

	
 

	
 
// Virtual serial port transmit rate
 
#define VCP_TX_FREQ 1000
 

	
 
// Solid-state relay maximum on-time
 
#define SSR_PERIOD 200
 

	
 
// Interval of PID calculations
 
#define PID_PERIOD 120
 

	
 

	
 

	
 
// Pin settings
 
#define LED_POWER GPIOF,GPIO_PIN_0
 
#define MAX_CS GPIOA,GPIO_PIN_15
 

	
 
#define SW_BTN  GPIOB, GPIO_PIN_4
 
#define SW_UP   GPIOB, GPIO_PIN_7
 
#define SW_DOWN GPIOB, GPIO_PIN_3
 
#define SW_LEFT GPIOB, GPIO_PIN_5
 
#define SW_RIGHT GPIOB, GPIO_PIN_6
 

	
 
#define SSR_PIN GPIOA, GPIO_PIN_1
 

	
 
// Visual niceness
 
#define hal_init() HAL_Init()
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
display.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
#include "ssd1306.h"
 
#include "stringhelpers.h"
 
#include "display.h"
 
#include "config.h"
 
#include "states.h"
 
#include "bootlib.h"
 
#include "syslib.h"
 
#include "flash.h"
 
#include "gpio.h"
 

	
 
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)
 

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

	
 
////////////////////////////////////////////////////////////////////////////////////////////////
 

	
 
uint8_t trigger_drawsetpoint = 1;
 

	
 
int16_t last_temp = 21245;
 

	
 
void display_process(therm_settings_t* set, therm_status_t* status)
 
{
 
    uint8_t last_state = status->state;
 
    
 
    uint8_t temp_changed = status->temp != last_temp;
 
    last_temp = status->temp;
 

	
 
    uint8_t sw_btn = !HAL_GPIO_ReadPin(SW_BTN);
 
    uint8_t sw_up = !HAL_GPIO_ReadPin(SW_UP);
 
    uint8_t sw_down = !HAL_GPIO_ReadPin(SW_DOWN);
 
    uint8_t sw_left = !HAL_GPIO_ReadPin(SW_LEFT);
 
    uint8_t sw_right = !HAL_GPIO_ReadPin(SW_RIGHT);
 

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

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

	
 
            ssd1306_drawlogo();
 

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

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

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

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

	
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                switch(goto_mode) {
 
                    case 3:
 
                    {
 
                        ssd1306_clearscreen();
main.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
 
#include "config.h"
 
#include "syslib.h"
 
#include "states.h"
 
#include "ssd1306.h"
 
#include "max31855.h"
 
#include "gpio.h"
 
#include "spi.h"
 
#include "flash.h"
 
#include "stringhelpers.h"
 
#include "display.h"
 
#include "storage.h"
 
 
#include "usb_device.h"
 
#include "usbd_cdc_if.h"
 
 
 
// Prototypes
 
// Move to header file
 
void process();
 
void SystemClock_Config(void);
 
 
therm_settings_t set;
 
therm_status_t status;
 
 
 
// Globalish setting vars
 
SPI_HandleTypeDef hspi1;
 
static __IO uint32_t TimingDelay;
 
 
void deinit(void)
 
{
 
    HAL_DeInit();
 
}
 
 
volatile int i=0;
 
int main(void)
 
{
 
 
    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
    HAL_Init();
 
    // Initialize HAL
 
    hal_init();
 
 
    /* Configure the system clock */
 
    SystemClock_Config();
 
    // Configure the system clock
 
    systemclock_config();
 
 
    /* Unset bootloader option bytes (if set) */
 
    // Unset bootloader option bytes (if set)
 
    void bootloader_unset(void);
 
 
    /* Initialize all configured peripherals */
 
    // Init GPIO
 
    init_gpio();
 
 
    // Init USB (TODO: Handle plugged/unplugged with external power)
 
    MX_USB_DEVICE_Init();
 
//    set.usb_plugged = 
 
 
    // USB startup delay
 
    HAL_Delay(1000);
 
    HAL_GPIO_WritePin(LED_POWER, 1);
 
 
    // Enter into bootloader if up button pressed on boot
 
    if(!HAL_GPIO_ReadPin(SW_UP))
 
        bootloader_enter(); // Resets into bootloader
 
 
    // TODO: Awesome pwm of power LED 
 
 
    // Configure 1ms SysTick (change if more temporal resolution needed) 
 
    //RCC_ClocksTypeDef RCC_Clocks;
 
    //RCC_GetClocksFreq(&RCC_Clocks);
 
    //SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
 
        bootloader_enter(); 
 
 
    // Init SPI busses
 
    init_spi();
 
 
    // Init OLED over SPI
 
    ssd1306_Init();
 
    ssd1306_clearscreen();
 
   
 
    // Default settings 
 
    set.boottobrew = 0;
 
    set.temp_units = TEMP_UNITS_CELSIUS;
 
    set.windup_guard = 1;
 
    set.k_p = 1;
 
    set.k_i = 1;
 
    set.k_d = 1;
 
    set.ignore_tc_error = 0;
 
    set.setpoint_brew = 0;
 
    set.setpoint_steam = 0;
 
 
    // Default status
 
    status.temp = 0;
 
    status.temp_frac = 0;
 
    status.state_resume = 0;
 
    status.state = STATE_IDLE;
 
    status.setpoint = 0;
 
    status.pid_enabled = 0;
 
 
    // Load settings (if any) from EEPROM
 
    restore_settings(&set);
 
 
    // Go to brew instead of idle if configured thusly
 
    if(set.boottobrew)
 
      status.state = STATE_PREHEAT_BREW; 
 
 
    // Startup screen 
 
    ssd1306_DrawString("therm v0.2", 1, 40);
 
    ssd1306_DrawString("protofusion.org/therm", 3, 0);
 
 
    HAL_Delay(1500);
 
 
    flash_init(&set);
 
 
    HAL_Delay(1500);
 
    ssd1306_clearscreen();
 
 
 
    // Main loop
 
    while(1)
 
    {
 
        // Process sensor inputs
 
        process();
 
 
        // Run state machine
 
        display_process(&set, &status); 
 
    }
 
 
}
 
 
// Clock configuration
 
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();
 
 
}
 
 
// 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;
 
int32_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 = setpoint - temp; // TODO: Use fixed point fraction
 
 
  // Proportional component
 
  int32_t p_term = k_p * error;
 
 
  // Error accumulator (integrator)
 
  i_state += error;
 
 
  // to prevent the iTerm getting huge from lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // it cant help be cold despite its best efforts)
 
  // not necessary, but this makes windup guard values 
 
  // relative to the current iGain
 
  int32_t windup_guard_res = set.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;
 
 
  int32_t i_term = k_i * i_state;
 
 
  // Calculate differential term (slope since last iteration)
 
  int32_t d_term = (k_d * (status.temp - last_pid_temp));
 
 
  // Save temperature for next iteration
 
  last_pid_temp = status.temp;
 
  last_pid_temp_frac = status.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_vcp_tx = 0;
 
uint32_t last_led = 0;
 
uint32_t last_pid = 0;
 
int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD 
 
 
// Turn SSR output on/off according to set duty cycle.
 
// TODO: Eventually maybe replace with a very slow timer or something. Double-check this code...
 
void process()
 
{
 
 
    uint32_t ticks = HAL_GetTick();
 
 
    if(ticks - last_led > 400) 
 
    {
 
        last_led = ticks;
 
    }
 
 
    if((ticks - last_pid > PID_PERIOD))
 
    {
 
        #ifdef MAX31855_TC_SENSOR
 
        max31855_readtemp(&hspi1, &set, &status); // Read MAX31855
 
        #endif
 
 
        #ifdef MAX31865_RTD_SENSOR
 
        max31865_readtemp(&set, &status);
 
        #endif
 
 
    HAL_GPIO_TogglePin(LED_POWER);
 
 
        if(status.pid_enabled) 
 
        {
 
            // Get ssr output for next time
 
            int16_t power_percent = update_pid(set.k_p, set.k_i, set.k_d, status.temp, status.temp_frac, status.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;
 
        }
 
 
        last_pid = ticks;
max31855.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 

	
 
#include "config.h"
 
#include "stringhelpers.h"
 
#include "states.h"
 
#include "gpio.h"
 

	
 
// Grab temperature reading from MAX31855
 
void max31855_readtemp(SPI_HandleTypeDef* hspi1, therm_settings_t* set, therm_status_t* status)
 
{
 
    // Assert CS
 
    HAL_GPIO_WritePin(MAX_CS, 0);
 

	
 
    uint8_t rxdatah[1] = {0x00};
 
    uint8_t rxdatal[1] = {0x00};
 

	
 
    HAL_SPI_Receive(hspi1, rxdatah, 1, 100);
 
    HAL_SPI_Receive(hspi1, rxdatal, 1, 100);
 

	
 
    // Release CS
 
    HAL_GPIO_WritePin(MAX_CS, 1);
 

	
 
    // Assemble data array into one var
 
    uint16_t temp_pre = rxdatal[0] | (rxdatah[0]<<8);
 
/*
 
    if(temp_pre & 0b010) {
 
        ssd1306_clearscreen();
 
        HAL_Delay(400); // FIXME: remove?
 
        status.tc_errno = 4;
 
        status.state = STATE_TC_ERROR;
 
        status.temp = 0;
 
        status.temp_frac = 0;
 
    } */
 
    if(temp_pre & 0b001 && !set->ignore_tc_error) {
 
        status->tc_errno = 1;
 
        HAL_Delay(400); // FIXME: remove?
 
        status->state_resume = status->state;
 
        status->state = STATE_TC_ERROR;
 
        status->temp = 0;
 
        status->temp_frac = 0;
 
    }/*
 
    else if(temp_pre & 0b100 && !set.ignore_tc_error) {
 
        status.tc_errno = 8;
 
        HAL_Delay(400); // FIXME: remove?
 
        status.state_resume = status.state;
 
        status.state = STATE_TC_ERROR;
 
        status.temp = 0;
 
        status.temp_frac = 0;
 
    }*/
 
    else 
 
    {
 
        //if(status.state == STATE_TC_ERROR)
 
        //{
 
        //    status.state = status.state_resume;
 
        //    ssd1306_clearscreen();
 
        //}
 

	
 
        uint8_t sign = status->temp >> 15;// top bit is sign
 

	
 
        temp_pre = temp_pre >> 2; // Drop 2 lowest bits
 
        status->temp_frac = temp_pre & 0b11; // get fractional part
 
        status->temp_frac *= 25; // each bit is .25 a degree, up to fixed point
 
        temp_pre = temp_pre >> 2; // Drop 2 fractional bits 
 

	
 
        int8_t signint;
 

	
 
        if(sign) {
 
            signint = -1;
 
        }
 
        else {
 
            signint = 1;
 
        }
 

	
 
        // Convert to Fahrenheit
 
        if(set->temp_units == TEMP_UNITS_FAHRENHEIT)
 
        {
 
            status->temp = signint * ((temp_pre*100) + status->temp_frac);
 
            status->temp = status->temp * 1.8;
 
            status->temp += 3200;
 
            status->temp_frac = status->temp % 100;
 
            status->temp /= 100;
 
            status->temp += set->temp_offset;
 
        }
 

	
 
        // Use Celsius values
 
        else
 
        {
 
            status->temp = temp_pre * signint;
 
            status->temp += set->temp_offset;
 
        }
 
    }
 
}
 

	
 

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

	
 
void max31855_readtemp(SPI_HandleTypeDef* hspi1, therm_settings_t* set, therm_status_t* status);
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
syslib.c
Show inline comments
 
file renamed from bootlib.c to syslib.c
 
#include "stm32f0xx_hal.h"
 

	
 
/* Notes:
 

	
 
Need to have DFU jump right to the program to unset those option bytes, or somehow have dfu-util unset them. Probably try using the :leave parameter...
 

	
 
       Flashing a binary file to address 0x8004000 of device memory and ask the device to leave DFU mode:
 
         $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin
 

	
 
*/
 

	
 

	
 
// Unset bootloader option bytes 
 
void bootloader_unset(void)
 
{
 
    FLASH_OBProgramInitTypeDef OBParam;
 
 
 
    HAL_FLASHEx_OBGetConfig(&OBParam);
 
 
 
    if(OBParam.USERConfig != 0xFF)
 
    {
 
 
 
        OBParam.OptionType = OPTIONBYTE_USER;
 
        OBParam.USERConfig = 0xFF;
 
 
 
        HAL_FLASH_Unlock();
 
        HAL_FLASH_OB_Unlock();
 
        HAL_FLASHEx_OBErase();
 
        HAL_FLASHEx_OBProgram(&OBParam);
 
        HAL_FLASH_OB_Lock();
 
        HAL_FLASH_OB_Launch();
 
    }
 
}
 

	
 

	
 
// See thread: https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fJump%20to%20USB%20DFU%20Bootloader%20in%20startup%20code%20on%20STM32F042&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=185
 
// Set option bytes to enter bootloader upon reset
 
void bootloader_enter(void) {
 

	
 
    FLASH_OBProgramInitTypeDef OBParam;
 
   
 
    HAL_FLASHEx_OBGetConfig(&OBParam);
 
  
 

	
 
    // FIXME TODO: CHECK THESE OPTION BYTES, he was using an F1 processor. What about the switch flag?
 
    OBParam.OptionType = OPTIONBYTE_USER;
 
    /*Reset NBOOT0 and BOOT_SEL,  see: RM 2.5 Boot configuration*/
 
    OBParam.USERConfig = 0x77; //Sorry for magic number :)
 
  
 
    HAL_FLASH_Unlock();
 
    HAL_FLASH_OB_Unlock();
 
  
 
    HAL_FLASHEx_OBErase();
 
  
 
    HAL_FLASHEx_OBProgram(&OBParam);
 
  
 
    HAL_FLASH_OB_Lock();
 
    HAL_FLASH_Lock();
 
  
 
    HAL_FLASH_OB_Launch();
 
}
 

	
 

	
 
// Clock configuration
 
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();
 

	
 
}
 

	
syslib.h
Show inline comments
 
file renamed from bootlib.h to syslib.h
 
#ifndef BOOTLIB_H
 
#define BOOTLIB_H
 

	
 
void bootloader_unset(void);
 
void bootloader_enter(void);
 
void systemclock_config(void);
 

	
 
#endif
usbd_conf.c
Show inline comments
 
/**
 
  ******************************************************************************
 
  * @file           : usbd_conf.c
 
  * @date           : 05/12/2014 20:22:27
 
  * @version        : v1.0_Cube
 
  * @brief          : This file implements the board support package for the USB device library
 
  ******************************************************************************
 
  *
 
  * COPYRIGHT(c) 2014 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.h"
 
#include "stm32f0xx_hal.h"
 
#include "usbd_def.h"
 
#include "usbd_core.h"
 
/* Private typedef -----------------------------------------------------------*/
 
/* Private define ------------------------------------------------------------*/
 
/* Private macro -------------------------------------------------------------*/
 
/* Private variables ---------------------------------------------------------*/
 
PCD_HandleTypeDef hpcd_USB_FS;
 
 
/* USER CODE BEGIN 0 */
 
__IO uint32_t remotewakeupon=0;
 
/* USER CODE END 0 */
 
 
/* Private function prototypes -----------------------------------------------*/
 
/* Private functions ---------------------------------------------------------*/
 
/* USER CODE BEGIN 1 */
 
static void SystemClockConfig_Resume(void);
 
/* USER CODE END 1 */
 
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
 
extern void SystemClock_Config(void);
 
extern void systemclock_config(void);
 
 
/*******************************************************************************
 
		       LL Driver Callbacks (PCD -> USB Device Library)
 
*******************************************************************************/
 
/* MSP Init */
 
 
void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)
 
{
 
  if(hpcd->Instance==USB)
 
  {
 
  /* USER CODE BEGIN USB_MspInit 0 */
 
 
  /* USER CODE END USB_MspInit 0 */
 
    /* Peripheral clock enable */
 
    __USB_CLK_ENABLE();
 
    HAL_NVIC_SetPriority(USB_IRQn, 0, 0);
 
    HAL_NVIC_EnableIRQ(USB_IRQn);
 
  /* USER CODE BEGIN USB_MspInit 1 */
 
 
  /* USER CODE END USB_MspInit 1 */
 
  }
 
}
 
 
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)
 
{
 
  if(hpcd->Instance==USB)
 
  {
 
  /* USER CODE BEGIN USB_MspDeInit 0 */
 
 
  /* USER CODE END USB_MspDeInit 0 */
 
    /* Peripheral clock disable */
 
    __USB_CLK_DISABLE();
 
 
    /* Peripheral interrupt Deinit*/
 
    HAL_NVIC_DisableIRQ(USB_IRQn);
 
 
  /* USER CODE BEGIN USB_MspDeInit 1 */
 
 
  /* USER CODE END USB_MspDeInit 1 */
 
  }
 
}
 
 
/**
 
  * @brief  Setup stage callback
 
  * @param  hpcd: PCD handle
 
  * @retval None
 
  */
 
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
 
{
 
  USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup);
 
}
 
 
/**
 
  * @brief  Data Out stage callback.
 
  * @param  hpcd: PCD handle
 
  * @param  epnum: Endpoint Number
 
  * @retval None
 
  */
 
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 
{
 
  USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
 
}
 
 
/**
 
  * @brief  Data In stage callback..
 
  * @param  hpcd: PCD handle
 
  * @param  epnum: Endpoint Number
 
  * @retval None
 
  */
 
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
 
{
 
  USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
 
}
 
 
/**
 
  * @brief  SOF callback.
 
  * @param  hpcd: PCD handle
 
  * @retval None
 
  */
 
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
 
{
 
  USBD_LL_SOF(hpcd->pData);
 
}
 
 
/**
 
  * @brief  Reset callback.
 
  * @param  hpcd: PCD handle
 
  * @retval None
 
  */
 
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
 
{
 
  USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
 
 
  /*Set USB Current Speed*/
 
  switch (hpcd->Init.speed)
 
  {
 
@@ -409,123 +409,123 @@ uint8_t USBD_LL_IsStallEP (USBD_HandleTy
 
  * @retval USBD Status
 
  */
 
USBD_StatusTypeDef  USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr)
 
{
 
 
  HAL_PCD_SetAddress(pdev->pData, dev_addr);
 
  return USBD_OK;
 
}
 
 
/**
 
  * @brief  Transmits data over an endpoint.
 
  * @param  pdev: Device handle
 
  * @param  ep_addr: Endpoint Number
 
  * @param  pbuf: Pointer to data to be sent
 
  * @param  size: Data size
 
  * @retval USBD Status
 
  */
 
USBD_StatusTypeDef  USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
 
				      uint8_t  ep_addr,
 
				      uint8_t  *pbuf,
 
				      uint16_t  size)
 
{
 
 
  HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
 
  return USBD_OK;
 
}
 
 
/**
 
  * @brief  Prepares an endpoint for reception.
 
  * @param  pdev: Device handle
 
  * @param  ep_addr: Endpoint Number
 
  * @param  pbuf: Pointer to data to be received
 
  * @param  size: Data size
 
  * @retval USBD Status
 
  */
 
USBD_StatusTypeDef  USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
 
					   uint8_t  ep_addr,
 
					   uint8_t  *pbuf,
 
					   uint16_t  size)
 
{
 
 
  HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
 
  return USBD_OK;
 
}
 
 
/**
 
  * @brief  Returns the last transfered packet size.
 
  * @param  pdev: Device handle
 
  * @param  ep_addr: Endpoint Number
 
  * @retval Recived Data Size
 
  */
 
uint32_t USBD_LL_GetRxDataSize  (USBD_HandleTypeDef *pdev, uint8_t  ep_addr)
 
{
 
  return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr);
 
}
 
 
/**
 
  * @brief  Delays routine for the USB Device Library.
 
  * @param  Delay: Delay in ms
 
  * @retval None
 
  */
 
void  USBD_LL_Delay (uint32_t Delay)
 
{
 
  HAL_Delay(Delay);
 
}
 
 
/**
 
  * @brief  static single allocation.
 
  * @param  size: size of allocated memory
 
  * @retval None
 
  */
 
void *USBD_static_malloc(uint32_t size)
 
{
 
  static uint32_t mem[MAX_STATIC_ALLOC_SIZE];
 
  return mem;
 
}
 
 
/**
 
  * @brief  Dummy memory free
 
  * @param  *p pointer to allocated  memory address
 
  * @retval None
 
  */
 
void USBD_static_free(void *p)
 
{
 
 
}
 
 
/* USER CODE BEGIN 4 */
 
/**
 
  * @brief  Configures system clock after wake-up from USB Resume CallBack:
 
  *         enable HSI, PLL and select PLL as system clock source.
 
  * @param  None
 
  * @retval None
 
  */
 
static void SystemClockConfig_Resume(void)
 
{
 
	SystemClock_Config();
 
	systemclock_config();
 
}
 
/* USER CODE END 4 */
 
 
/**
 
* @brief Software Device Connection
 
* @param hpcd: PCD handle
 
* @param state: connection state (0 : disconnected / 1: connected)
 
* @retval None
 
*/
 
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
 
{
 
/* USER CODE BEGIN 5 */
 
  if (state == 1)
 
  {
 
    /* Configure Low Connection State */
 
 
  }
 
  else
 
  {
 
    /* Configure High Connection State */
 
 
  }
 
/* USER CODE END 5 */
 
}
 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
0 comments (0 inline, 0 general)