1 // Copyright 2012 Emilie Gillet.
2 //
3 // Author: Emilie Gillet (emilie.o.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26 //
27 // Function for jumping from bootloader code to application code.
28
29 #include "stmlib/system/bootloader_utils.h"
30
31 #ifdef STM32F4XX
32 #include <stm32f4xx_conf.h>
33 #endif // STM32F4XX
34
35 #ifdef STM32F0XX
36 #include <stm32f0xx_conf.h>
37 #endif // STM32F0XX
38
39 #ifdef STM32F37X
40 #include <stm32f37x_conf.h>
41 #endif // STM32F37X
42
43 #ifdef STM32F10X
44 #include <stm32f10x_conf.h>
45 #endif // STM32F10X
46
47 #ifdef STM32H7XX
48 #include <stm32h7xx_hal_conf.h>
49 #endif // STM32H7XX
50
51 #ifdef STM32G4XX
52 #include <stm32g4xx_hal_conf.h>
53 #endif // STM32G4XX
54
55 namespace stmlib {
56
57 #define u32 uint32_t
58 #define vu32 volatile uint32_t
59
60 #define SET_REG(addr,val) do { *(vu32*)(addr)=val; } while(0)
61 #define GET_REG(addr) (*(vu32*)(addr))
62
63 #define RCC_CR RCC
64 #define RCC_CFGR (RCC + 0x04)
65 #define RCC_CIR (RCC + 0x08)
66 #define RCC_AHBENR (RCC + 0x14)
67 #define RCC_APB2ENR (RCC + 0x18)
68 #define RCC_APB1ENR (RCC + 0x1C)
69
70 #define SCS 0xE000E000
71 #define STK (SCS+0x10)
72 #define STK_CTRL (STK+0x00)
73 #define RCC_CR RCC
74
75 typedef struct {
76 vu32 ISER[2];
77 u32 RESERVED0[30];
78 vu32 ICER[2];
79 u32 RSERVED1[30];
80 vu32 ISPR[2];
81 u32 RESERVED2[30];
82 vu32 ICPR[2];
83 u32 RESERVED3[30];
84 vu32 IABR[2];
85 u32 RESERVED4[62];
86 vu32 IPR[15];
87 } NVIC_TypeDef;
88
Uninitialize()89 void Uninitialize() {
90 // Stop NVIC.
91 NVIC_TypeDef *rNVIC = (NVIC_TypeDef *) NVIC_BASE;
92 rNVIC->ICER[0] = 0xFFFFFFFF;
93 rNVIC->ICER[1] = 0xFFFFFFFF;
94 rNVIC->ICPR[0] = 0xFFFFFFFF;
95 rNVIC->ICPR[1] = 0xFFFFFFFF;
96 SET_REG(STK_CTRL, 0x04);
97
98 // System reset.
99 SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001);
100 SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000);
101 SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF);
102 SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF);
103 SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF);
104 SET_REG(RCC_CIR, 0x00000000);
105 }
106
107 typedef void (*EntryPoint)(void);
108
JumpTo(uint32_t address)109 void JumpTo(uint32_t address) {
110 uint32_t application_address = *(__IO uint32_t*)(address + 4);
111 EntryPoint application = (EntryPoint)(application_address);
112 __set_MSP(*(__IO uint32_t*)address);
113 application();
114 }
115
116 } // namespace stmlib
117
118