|
66 | 66 |
|
67 | 67 | void setup() |
68 | 68 | { |
| 69 | + io.init(); |
| 70 | + |
69 | 71 | serial.start(); |
70 | 72 | } |
71 | 73 |
|
@@ -194,12 +196,82 @@ extern "C" void __cxa_pure_virtual() { while (true); } |
194 | 196 | #endif // defined(__SAM3X8E__) && defined(ARDUINO_SAM_DUE) |
195 | 197 |
|
196 | 198 | #if defined(STM32F4XX) || defined(STM32F7XX) |
| 199 | +#if defined(STM32F4XX) |
| 200 | +#include <stm32f4xx_flash.h> |
| 201 | +#endif |
| 202 | +#if defined(STM32F7XX) |
| 203 | +#include <stm32f7xx_flash.h> |
| 204 | +#endif |
| 205 | + |
| 206 | +#define STM32_CNF_PAGE_ADDR (uint32_t)0x08010000 |
| 207 | +#define STM32_CNF_PAGE ((uint32_t *)0x08010000) |
| 208 | +#define STM32_CNF_SECTOR FLASH_Sector_4 |
| 209 | +#define STM32_CNF_PAGE_24 24U |
| 210 | + |
197 | 211 | // -------------------------------------------------------------------------- |
198 | 212 | // Firmware Entry Point |
199 | | -// --------------------------------------------------------------------------- |
| 213 | +// -------------------------------------------------------------------------- |
| 214 | + |
| 215 | +void jumpToBootLoader() |
| 216 | +{ |
| 217 | + // Disable RCC, set it to default (after reset) settings Internal clock, no PLL, etc. |
| 218 | + RCC_DeInit(); |
| 219 | + ADC_DeInit(); |
| 220 | + DAC_DeInit(); |
| 221 | + TIM_DeInit(TIM2); |
| 222 | + USART_DeInit(USART1); |
| 223 | + USART_DeInit(UART5); |
| 224 | + |
| 225 | + // Disable Systick timer |
| 226 | + SysTick->CTRL = 0; |
| 227 | + SysTick->LOAD = 0; |
| 228 | + SysTick->VAL = 0; |
| 229 | + |
| 230 | + // Clear Interrupt Enable Register & Interrupt Pending Register |
| 231 | + for (uint8_t i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { |
| 232 | + NVIC->ICER[i] = 0xFFFFFFFF; |
| 233 | + NVIC->ICPR[i] = 0xFFFFFFFF; |
| 234 | + } |
| 235 | + |
| 236 | + SYSCFG->MEMRMP = 0x01; |
| 237 | + |
| 238 | +#if defined(STM32F4XX) |
| 239 | + volatile uint32_t addr = 0x1FFF0000; |
| 240 | +#elif defined(STM32F7XX) |
| 241 | + volatile uint32_t addr = 0x1FF00000; |
| 242 | +#endif |
| 243 | + |
| 244 | + void (*SysMemBootJump)(void); |
| 245 | + SysMemBootJump = (void (*)(void))(*((uint32_t *)(addr + 4))); |
| 246 | + __set_MSP(*(uint32_t *)addr); |
| 247 | + SysMemBootJump(); |
| 248 | +} |
200 | 249 |
|
201 | 250 | int main() |
202 | 251 | { |
| 252 | + // does the configuration page contain the request bootloader flag? |
| 253 | + if ((STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0xFFFFFFFFU) && (STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0x00U)) { |
| 254 | + uint8_t bootloadMode = (STM32_CNF_PAGE[STM32_CNF_PAGE_24] >> 8) & 0xFFU; |
| 255 | + if ((bootloadMode & 0x20U) == 0x20U) { |
| 256 | + // we unfortunately need to discard the configuration area entirely for bootloader mode... |
| 257 | + FLASH_Unlock(); |
| 258 | + FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPERR); |
| 259 | + |
| 260 | +#if defined(STM32F4XX) || defined(STM32F7XX) |
| 261 | + if (FLASH_EraseSector(STM32_CNF_SECTOR, VoltageRange_3) != FLASH_COMPLETE) { |
| 262 | + FLASH_Lock(); |
| 263 | + return RSN_FAILED_ERASE_FLASH; |
| 264 | + } |
| 265 | +#elif defined(STM32F10X_MD) |
| 266 | + if (FLASH_ErasePage(STM32_CNF_PAGE_ADDR) != FLASH_COMPLETE) { |
| 267 | + FLASH_Lock(); |
| 268 | + return RSN_FAILED_ERASE_FLASH; |
| 269 | + } |
| 270 | +#endif |
| 271 | + jumpToBootLoader(); |
| 272 | + } |
| 273 | + } |
| 274 | + |
203 | 275 | setup(); |
204 | 276 |
|
205 | 277 | for (;;) |
|
0 commit comments