|
73 | 73 |
|
74 | 74 | void setup() |
75 | 75 | { |
| 76 | + io.init(); |
| 77 | + |
76 | 78 | serial.start(); |
77 | 79 | } |
78 | 80 |
|
@@ -121,9 +123,68 @@ void loop() |
121 | 123 | // --------------------------------------------------------------------------- |
122 | 124 | // Firmware Entry Point |
123 | 125 | // --------------------------------------------------------------------------- |
| 126 | +#include <stm32f10x_flash.h> |
| 127 | + |
| 128 | +#define STM32_CNF_PAGE_ADDR (uint32_t)0x0800FC00 |
| 129 | +#define STM32_CNF_PAGE ((uint32_t *)0x0800FC00) |
| 130 | +#define STM32_CNF_PAGE_24 24U |
| 131 | + |
| 132 | +void jumpToBootLoader() |
| 133 | +{ |
| 134 | + // Disable RCC, set it to default (after reset) settings Internal clock, no PLL, etc. |
| 135 | + RCC_DeInit(); |
| 136 | + USART_DeInit(USART1); |
| 137 | + USART_DeInit(UART5); |
| 138 | + |
| 139 | + // Disable Systick timer |
| 140 | + SysTick->CTRL = 0; |
| 141 | + SysTick->LOAD = 0; |
| 142 | + SysTick->VAL = 0; |
| 143 | + |
| 144 | + // Clear Interrupt Enable Register & Interrupt Pending Register |
| 145 | + for (uint8_t i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) { |
| 146 | + NVIC->ICER[i] = 0xFFFFFFFF; |
| 147 | + NVIC->ICPR[i] = 0xFFFFFFFF; |
| 148 | + } |
| 149 | + |
| 150 | +#if defined(STM32F10X_MD) |
| 151 | + volatile uint32_t addr = 0x1FFFF000; |
| 152 | +#endif |
| 153 | + |
| 154 | + // Update the NVIC's vector |
| 155 | + SCB->VTOR = addr; |
| 156 | + |
| 157 | + void (*SysMemBootJump)(void); |
| 158 | + SysMemBootJump = (void (*)(void))(*((uint32_t *)(addr + 4))); |
| 159 | + __ASM volatile ("MSR msp, %0" : : "r" (*(uint32_t *)addr) : "sp"); // __set_MSP |
| 160 | + SysMemBootJump(); |
| 161 | +} |
124 | 162 |
|
125 | 163 | int main() |
126 | 164 | { |
| 165 | + // does the configuration page contain the request bootloader flag? |
| 166 | + if ((STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0xFFFFFFFFU) && (STM32_CNF_PAGE[STM32_CNF_PAGE_24] != 0x00U)) { |
| 167 | + uint8_t bootloadMode = (STM32_CNF_PAGE[STM32_CNF_PAGE_24] >> 8) & 0xFFU; |
| 168 | + if ((bootloadMode & 0x20U) == 0x20U) { |
| 169 | + // we unfortunately need to discard the configuration area entirely for bootloader mode... |
| 170 | + FLASH_Unlock(); |
| 171 | + FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); |
| 172 | + |
| 173 | +#if defined(STM32F4XX) || defined(STM32F7XX) |
| 174 | + if (FLASH_EraseSector(STM32_CNF_SECTOR, VoltageRange_3) != FLASH_COMPLETE) { |
| 175 | + FLASH_Lock(); |
| 176 | + return RSN_FAILED_ERASE_FLASH; |
| 177 | + } |
| 178 | +#elif defined(STM32F10X_MD) |
| 179 | + if (FLASH_ErasePage(STM32_CNF_PAGE_ADDR) != FLASH_COMPLETE) { |
| 180 | + FLASH_Lock(); |
| 181 | + return RSN_FAILED_ERASE_FLASH; |
| 182 | + } |
| 183 | +#endif |
| 184 | + jumpToBootLoader(); |
| 185 | + } |
| 186 | + } |
| 187 | + |
127 | 188 | setup(); |
128 | 189 |
|
129 | 190 | for (;;) |
|
0 commit comments