1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "project.h"
#define BOOTLOADER_BUTTON GPIO12
#define BOOTLOADER_BUTTON_PORT GPIOE
static const clock_scale_t hsi_16mhz_3v3_48 = {
.pllm = 16,
.plln = 96,
.pllp = 2,
.pllq = 2,
.pllr = 0,
.pll_source = RCC_CFGR_PLLSRC_HSI_CLK,
.hpre = RCC_CFGR_HPRE_NODIV,
.ppre1 = RCC_CFGR_PPRE_DIV4,
.ppre2 = RCC_CFGR_PPRE_DIV2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 48000000,
.apb1_frequency = 12000000,
.apb2_frequency = 24000000,
};
int main (void)
{
rcc_periph_clock_enable (RCC_GPIOE);
rcc_periph_clock_enable (RCC_GPIOB);
rcc_periph_clock_enable (RCC_GPIOG);
MAP_INPUT_PU (BOOTLOADER_BUTTON);
if ((dfu_flag != 0xfee1dead) && (GET (BOOTLOADER_BUTTON))) {
/* Boot the application if it's valid. */
if ((* (volatile uint32_t *)APP_ADDRESS & 0x2FFE0000) == 0x20020000) {
max7219 ("boot");
rcc_periph_clock_disable (RCC_GPIOE);
rcc_periph_clock_disable (RCC_GPIOB);
rcc_periph_clock_disable (RCC_GPIOG);
/* Set vector table base address. */
SCB_VTOR = APP_ADDRESS & 0xFFFF;
/* Initialise master stack pointer. */
asm volatile ("msr msp, %0\n"
"blx %1\n" ::
"g" (* (volatile uint32_t *)APP_ADDRESS),
"r" (* (uint32_t *) (APP_ADDRESS + 4))
: "memory");
} else
max7219 ("nofw dfu");
} else
max7219 ("dfu");
dfu_flag = 0;
rcc_periph_clock_enable (RCC_SYSCFG);
rcc_clock_setup_pll (&hsi_16mhz_3v3_48);
RCC_AHB1RSTR |= RCC_AHB1RSTR_ETHMACRST;
RCC_AHB2RSTR |= RCC_AHB2RSTR_OTGFSRST;
asm ("nop":::"memory");
RCC_AHB2RSTR &= ~RCC_AHB2RSTR_OTGFSRST;
RCC_AHB1RSTR &= ~RCC_AHB1RSTR_ETHMACRST;
usart_init();
usart2_xmit_str ("\r\nDFU Bootloader\r\n");
delay_ms (100);
usart_init();
usart2_xmit_str ("Ready\r\n");
usb();
}
|