15
15
#define BANK_2_ADDRESS 0x08100000
16
16
#define SD_BOOTLOADER_ADDRESS 0x08032000
17
17
18
+ // Other software (like retro-go) should set this value
18
19
#define BOOTLOADER_MAGIC 0x544F4F42 // "BOOT"
20
+
21
+ // Intended for internal-use only; bypasses other checks
22
+ #define BOOTLOADER_MAGIC_FORCE 0x45435246 // "FRCE"
23
+
19
24
#define BOOTLOADER_MAGIC_ADDRESS ((uint32_t *)0x2001FFF8)
20
25
#define BOOTLOADER_JUMP_ADDRESS ((uint32_t **)0x2001FFFC)
21
26
22
- static void MX_RTC_Init (RTC_HandleTypeDef * hrtc );
23
-
24
27
static void __attribute__((naked )) start_app (void (* const pc )(void ), uint32_t sp ) {
25
28
__asm(" \n\
26
29
msr msp, r1 /* load r1 into MSP */\n\
@@ -29,7 +32,7 @@ static void __attribute__((naked)) start_app(void (* const pc)(void), uint32_t
29
32
}
30
33
31
34
static inline void set_bootloader (uint32_t address ){
32
- * BOOTLOADER_MAGIC_ADDRESS = BOOTLOADER_MAGIC ;
35
+ * BOOTLOADER_MAGIC_ADDRESS = BOOTLOADER_MAGIC_FORCE ;
33
36
* BOOTLOADER_JUMP_ADDRESS = (uint32_t * )address ;
34
37
}
35
38
@@ -41,20 +44,46 @@ static inline void set_bootloader(uint32_t address){
41
44
* So to run that app, set those values and execute a reset.
42
45
*/
43
46
void bootloader (){
44
- if (* BOOTLOADER_MAGIC_ADDRESS == BOOTLOADER_MAGIC ) {
47
+ if (* BOOTLOADER_MAGIC_ADDRESS == BOOTLOADER_MAGIC_FORCE ) {
45
48
* BOOTLOADER_MAGIC_ADDRESS = 0 ;
46
49
uint32_t sp = (* BOOTLOADER_JUMP_ADDRESS )[0 ];
47
50
uint32_t pc = (* BOOTLOADER_JUMP_ADDRESS )[1 ];
48
51
start_app ((void (* const )(void )) pc , (uint32_t ) sp );
49
52
}
53
+
50
54
HAL_Init ();
51
- __HAL_RCC_CRS_CLK_ENABLE ();
52
- HAL_PWR_EnableBkUpAccess (); // Enable backup domain access
53
- __HAL_RCC_RTC_ENABLE (); // Enable RTC clock
54
- RTC_HandleTypeDef hrtc ;
55
- MX_RTC_Init (& hrtc );
56
- uint32_t rtc_backup_value = HAL_RTCEx_BKUPRead (& hrtc , RTC_BKP_DR0 );
57
- if (rtc_backup_value == BOOTLOADER_MAGIC ){
55
+
56
+ HAL_PWR_EnableBkUpAccess ();
57
+ __HAL_RCC_RTC_ENABLE ();
58
+ __HAL_RCC_GPIOC_CLK_ENABLE ();
59
+
60
+ RTC_HandleTypeDef hrtc = {0 };
61
+ hrtc .Instance = RTC ;
62
+ // Note: Don't need to call HAL_RTC_Init() since we're just reading backup register
63
+
64
+ GPIO_InitTypeDef GPIO_InitStruct = {0 };
65
+ GPIO_InitStruct .Pin = BTN_GAME_Pin ;
66
+ GPIO_InitStruct .Mode = GPIO_MODE_INPUT ;
67
+ GPIO_InitStruct .Pull = GPIO_PULLUP ; // Button connects to GND.
68
+ GPIO_InitStruct .Speed = GPIO_SPEED_FREQ_LOW ;
69
+
70
+ HAL_GPIO_Init (BTN_GAME_GPIO_Port , & GPIO_InitStruct );
71
+
72
+ if (HAL_GPIO_ReadPin (BTN_GAME_GPIO_Port , BTN_GAME_Pin ) == GPIO_PIN_RESET ) {
73
+ // If GAME is pressed: reset all triggers that might cause us to dual-boot.
74
+ * BOOTLOADER_MAGIC_ADDRESS = 0 ;
75
+ HAL_RTCEx_BKUPWrite (& hrtc , RTC_BKP_DR0 , 0 );
76
+ }
77
+
78
+ if (* BOOTLOADER_MAGIC_ADDRESS == BOOTLOADER_MAGIC ) {
79
+ * BOOTLOADER_MAGIC_ADDRESS = 0 ;
80
+ uint32_t sp = (* BOOTLOADER_JUMP_ADDRESS )[0 ];
81
+ uint32_t pc = (* BOOTLOADER_JUMP_ADDRESS )[1 ];
82
+ start_app ((void (* const )(void )) pc , (uint32_t ) sp );
83
+ }
84
+
85
+
86
+ if (HAL_RTCEx_BKUPRead (& hrtc , RTC_BKP_DR0 ) == BOOTLOADER_MAGIC ){
58
87
#if SD_BOOTLOADER
59
88
uint32_t sp = * ((uint32_t * )SD_BOOTLOADER_ADDRESS );
60
89
uint32_t pc = * ((uint32_t * )SD_BOOTLOADER_ADDRESS + 1 );
@@ -122,16 +151,19 @@ gamepad_t read_buttons() {
122
151
NVIC_SystemReset ();
123
152
}
124
153
#endif
154
+
125
155
#if CLOCK_ONLY
126
156
if (gamepad & GAMEPAD_GAME ){
127
157
#else
128
158
if ((gamepad & GAMEPAD_LEFT ) && (gamepad & GAMEPAD_GAME )){
129
159
#endif
160
+
130
161
#if SD_BOOTLOADER
131
162
set_bootloader (SD_BOOTLOADER_ADDRESS );
132
163
#else
133
164
set_bootloader (BANK_2_ADDRESS );
134
165
#endif
166
+
135
167
NVIC_SystemReset ();
136
168
}
137
169
@@ -229,38 +261,6 @@ gnw_mode_t get_gnw_mode(){
229
261
}
230
262
#endif
231
263
232
- /**
233
- * @brief RTC Initialization Function
234
- * @param None
235
- * @retval None
236
- */
237
- static void MX_RTC_Init (RTC_HandleTypeDef * hrtc )
238
- {
239
-
240
- /* USER CODE BEGIN RTC_Init 0 */
241
-
242
- /* USER CODE END RTC_Init 0 */
243
-
244
- /* USER CODE BEGIN RTC_Init 1 */
245
-
246
- /* USER CODE END RTC_Init 1 */
247
- /** Initialize RTC Only
248
- */
249
- hrtc -> Instance = RTC ;
250
- hrtc -> Init .HourFormat = RTC_HOURFORMAT_24 ;
251
- hrtc -> Init .AsynchPrediv = 127 ; // Recommended value from application note for LSE, the higher the value the better the accuracy and power consumption
252
- hrtc -> Init .SynchPrediv = 255 ; // Recommended value from application note for LSE
253
- hrtc -> Init .OutPut = RTC_OUTPUT_DISABLE ;
254
- hrtc -> Init .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH ;
255
- hrtc -> Init .OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN ;
256
- hrtc -> Init .OutPutRemap = RTC_OUTPUT_REMAP_NONE ;
257
- HAL_RTC_Init (hrtc );
258
-
259
- /* USER CODE BEGIN Check_RTC_BKUP */
260
- return ; // Retain RTC values on boot
261
- }
262
-
263
-
264
264
void NMI_Handler (void ) {
265
265
__BKPT (0 );
266
266
}
0 commit comments