Changeset - f2990941d9d9
[Not reviewed]
cortex-f0
0 4 2
Ethan Zonca - 9 years ago 2015-06-01 16:48:26
ez@ethanzonca.com
Added untested jump-to-DFU using option bytes per ST forums. Should work, need to make sure the user program is run after DFU flash so the bits are unset
6 files changed with 71 insertions and 5 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 eeprom_min.c display.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 eeprom_min.c display.c bootlib.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
 

	
bootlib.c
Show inline comments
 
new file 100644
 
#include "stm32f0xx_hal.h"
 

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

	
 

	
bootlib.h
Show inline comments
 
new file 100644
 
#ifndef BOOTLIB_H
 
#define BOOTLIB_H
 

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

	
 
#endif
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 "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 ]
 
@@ -82,58 +82,61 @@ void display_process(therm_settings_t* s
 
                {
 
                    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:
 
                        status->state = STATE_PREHEAT_BREW;
 
                        break;
 
                    case 1:
 
                        status->state = STATE_SETP;
 
                        break;
 
                    case 0:
 
                    {
 
                        ssd1306_clearscreen();
 
                        ssd1306_DrawString("Entering Bootloader", 1, 0);
 
                        ssd1306_DrawString("(hopefully)", 2, 0);
 
                        //HAL_Delay(1000);
 
                        HAL_Delay(1000);
 
                        bootloader_enter();
 

	
 
/*
 
                        HAL_RCC_DeInit();
 
                        SysTick->CTRL = 0;
 
                        SysTick->LOAD = 0;
 
                        SysTick->VAL = 0;
 
                        __set_PRIMASK(1);
 
                        __set_MSP(0x200010000);
 
                        *((unsigned long *)0x200017F0) = 0xDEADBEEF; // 6KB STM32F042
 
                        NVIC_SystemReset();
 

	
 
*/
 
                        status->state = STATE_IDLE;
 
                    } break;
 

	
 
                    default:
 
                        status->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 ]
main.c
Show inline comments
 
@@ -23,48 +23,51 @@ 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();
 
 
    /* Configure the system clock */
 
    SystemClock_Config();
 
 
    /* Unset bootloader option bytes (if set) */
 
    void bootloader_unset(void);
 
 
    /* Initialize all configured peripherals */
 
    init_gpio();
 
    MX_USB_DEVICE_Init();
 
 
    // USB startup delay
 
    HAL_Delay(1000);
 
    HAL_GPIO_WritePin(LED_POWER, 1);
 
 
    // 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);
 
 
    // Init SPI busses
 
    init_spi();
 
 
    // Init OLED over SPI
 
    ssd1306_Init();
 
    ssd1306_clearscreen();
 
   
 
    // Default settings 
 
    set.boottobrew = 0;
startup_stm32f042x6.s
Show inline comments
 
@@ -63,61 +63,63 @@ defined in linker script */
 
  .section .text.Reset_Handler
 
  .weak Reset_Handler
 
  .type Reset_Handler, %function
 
Reset_Handler:
 
 
  /* Bootloader jumping */
 
  ldr r0, =0x200017F0 /* address of magic token, is addr within memory range? */
 
  ldr r1, =0xDEADBEEF /* magical beef token */
 
  ldr r2, [r0, #0] /* load data from magic address */
 
  str r0, [r0, #0] /* zero data at magic address so we don't bootloop */ 
 
  cmp r2, r1 /* compare data at magic address to magic token */
 
  beq Reboot_Loader /* jump to bootloader if token match */
 
  /* End bootloader jumping */
 
 
 
  ldr   r0, =_estack
 
  mov   sp, r0          /* set stack pointer */
 
 
/* Copy the data segment initializers from flash to SRAM */
 
  movs r1, #0
 
  b LoopCopyDataInit
 
 
/* Boot into bootloader */
 
Reboot_Loader:
 
  b Reboot_Loader
 
  LDR     R0, =0x40021018 // RCC_APB2ENR (+0x18)
 
  LDR     R1, =0x00000001 // ENABLE SYSCFG CLOCK
 
  STR     R1, [R0, #0]
 
  LDR     R0, =0x40010000 // SYSCFG_CFGR1 (+0x00)
 
  LDR     R1, =0x00000001 // MAP ROM AT ZERO
 
  STR     R1, [R0, #0]
 
  //                LDR     R0, =0x1FFFEC00 ; ROM BASE (STM32F03x)
 
  LDR     R0, =0x1FFFC400 // ROM BASE (STM32F04x)
 
  LDR     R0, =0x1FFFC800 // ROM BASE (STM32F04x)
 
  //                LDR     R0, =0x1FFFEC00 ; ROM BASE (STM32F05x)
 
  //                LDR     R0, =0x1FFFC800 ; ROM BASE (STM32F07x)
 
  //                LDR     R0, =0x1FFFD800 ; ROM BASE (STM32F09x)
 
  LDR     R1, [R0, #0]    // SP @ +0
 
  MOV     SP, R1
 
 
  LDR     R0, [R0, #4]    // PC @ +4
 
  BX      R0
 
 
 
  // On reset, SP=value at address 0x0
 
//  ldr r0, =0x00000000
 
//  ldr r0, [r0, #0]
 
//  mov sp, r0
 
 
//  ldr r0, =0x1FFFC800 /* Address of bootloader on f042 from CD00167594 pg 15 table 3 */
 
 
  // Branch to bootloader
 
//  ldr r0, [r0, #4]
 
//  bx r0
 
 
 
CopyDataInit:
 
  ldr r3, =_sidata
 
  ldr r3, [r3, r1]
 
  str r3, [r0, r1]
 
  adds r1, r1, #4
 
 
LoopCopyDataInit:
 
  ldr r0, =_sdata
0 comments (0 inline, 0 general)