38
38
/* SRAM size */
39
39
#define SRAM_SIZE (20 * 1024)
40
40
41
+ /* SRAM end (bottom of stack) */
42
+ #define SRAM_END (SRAM_BASE + SRAM_SIZE)
43
+
41
44
/* HID Bootloader takes 4 kb flash. */
42
45
#define USER_PROGRAM (FLASH_BASE + BOOTLOADER_SIZE)
43
46
47
+ /* Simple function pointer type to call user program */
44
48
typedef void (* funct_ptr )(void );
45
49
46
- extern void Reset_Handler (void );
50
+ /* The bootloader entry point gunction prototype */
51
+ void Reset_Handler (void );
52
+
53
+ /* The SRAM vector table The initializer is to put this array in the
54
+ * .data section at the begining of SRAM
55
+ */
56
+ uint32_t RamVectors [37 ] __attribute__((section (".data" )));
47
57
48
- void _init ( void );
49
- void __libc_init_array ( void );
58
+ /* Minimal initial Flash-based vector table */
59
+ uint32_t * VectorTable [] __attribute__(( section ( ".isr_vector" ))) = {
50
60
51
- uint32_t RamVectors [37 ] = {1 };
61
+ /* Initial stack pointer (MSP) */
62
+ (uint32_t * ) SRAM_END ,
63
+
64
+ /* Reset handler */
65
+ (uint32_t * ) Reset_Handler
66
+ };
52
67
53
68
static void delay (uint32_t tmr ) {
54
69
for (uint32_t i = 0 ; i < tmr ; i ++ ) {
@@ -73,8 +88,8 @@ static bool check_flash_complete(void) {
73
88
return false;
74
89
}
75
90
76
- static bool check_user_code (u32 usrAddr ) {
77
- u32 sp = * (vu32 * ) usrAddr ;
91
+ static bool check_user_code (uint32_t usrAddr ) {
92
+ uint32_t sp = * (volatile uint32_t * ) usrAddr ;
78
93
79
94
/* Check if the stack pointer in the vector table points in
80
95
RAM */
@@ -88,7 +103,7 @@ static bool check_user_code(u32 usrAddr) {
88
103
static uint16_t get_and_clear_magic_word (void ) {
89
104
90
105
/* Enable the power and backup interface clocks by setting the
91
- * PWREN and BKPEN bitsin the RCC_APB1ENR register
106
+ * PWREN and BKPEN bits in the RCC_APB1ENR register
92
107
*/
93
108
SET_BIT (RCC -> APB1ENR , RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN );
94
109
uint16_t value = BKP -> DR10 ;
@@ -103,23 +118,23 @@ static uint16_t get_and_clear_magic_word(void) {
103
118
return value ;
104
119
}
105
120
106
- void _init (void ) {
107
- }
108
-
109
- void __libc_init_array (void ) {
110
- }
121
+ void Reset_Handler (void ) {
111
122
112
- int main (int argc , char * argv []) {
113
- (void ) argc ;
114
- (void ) argv ;
123
+ /* Setup the system clock (System clock source, PLL Multiplier
124
+ * factors, AHB/APBx prescalers and Flash settings)
125
+ */
126
+ SystemInit ();
115
127
116
- RamVectors [0 ] = SRAM_BASE + SRAM_SIZE ;
128
+ /* Setup to vector table in SRAM, so we can handle USB IRQs */
129
+ RamVectors [0 ] = SRAM_END ;
117
130
RamVectors [1 ] = (uint32_t ) Reset_Handler ;
118
131
RamVectors [36 ] = (uint32_t ) USB_LP_CAN1_RX0_IRQHandler ;
119
132
SCB -> VTOR = (volatile uint32_t ) RamVectors ;
120
133
134
+ /* Check for a magic word in BACKUP memory */
121
135
uint16_t magic_word = get_and_clear_magic_word ();
122
136
137
+ /* Initialize GPIOs */
123
138
pins_init ();
124
139
125
140
/* Wait 1uS so the pull-up settles... */
@@ -131,19 +146,25 @@ int main(int argc, char *argv[]) {
131
146
132
147
UploadStarted = false;
133
148
UploadFinished = false;
134
- uint32_t userProgramAddress = * (volatile uint32_t * ) (USER_PROGRAM + 0x04 );
135
- funct_ptr userProgram = (funct_ptr ) userProgramAddress ;
136
-
137
- /* If PB2 (BOOT 1 pin) is HIGH enter HID bootloader or no User
138
- * Code is uploaded to the MCU or <Battery Backed RAM
139
- * Register> was set from Arduino IDE exit from USB Serial
140
- * mode and go to HID mode ...
149
+ funct_ptr UserProgram = (funct_ptr ) * (volatile uint32_t * ) (USER_PROGRAM + 0x04 );
150
+
151
+ /* If:
152
+ * - PB2 (BOOT 1 pin) is HIGH or
153
+ * - no User Code is uploaded to the MCU or
154
+ * - a magic word was stored in the battery-backed RAM
155
+ * registers from the Arduino IDE
156
+ * then enter HID bootloader...
141
157
*/
142
158
if ((magic_word == 0x424C ) ||
143
159
(GPIOB -> IDR & GPIO_IDR_IDR2 ) ||
144
160
(check_user_code (USER_PROGRAM ) == false)) {
145
161
if (magic_word == 0x424C ) {
146
162
163
+ /* If a magic word was stored in the
164
+ * battery-backed RAM registers from the
165
+ * Arduino IDE, exit from USB Serial mode and
166
+ * go to HID mode...
167
+ */
147
168
#if defined HAS_LED2_PIN
148
169
led2_on ();
149
170
#endif
@@ -178,7 +199,7 @@ int main(int argc, char *argv[]) {
178
199
//CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);
179
200
SCB -> VTOR = USER_PROGRAM ;
180
201
__set_MSP ((* (volatile uint32_t * ) USER_PROGRAM ));
181
- userProgram ();
202
+ UserProgram ();
182
203
for (;;) {
183
204
;
184
205
}
0 commit comments