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