/* * main.c * * Created on: Jun 23, 2023 * Author: true * * UART bootloader for HK32F030M MCU. Tested on HK32F030MF4P6. * Button or no-code activation. Otherwise instant jump to user code. * Should be easy to port to other platforms. Needs less than 2K RAM. * * Just a couple days before completing this, LCSC removed this part... * it likely won't be very common now, so what's the point? =( */ #include "hk32f030m.h" #include "flash.h" #include "usart.h" #include "user_io.h" #include "xmodem.h" int main(void) { uint32_t i; uint32_t btn; // ensure the bootloader is write protected // TODO // configure button and LED user_io_init(); // get button state btn = BTN_PORT->IDR & (1 << BTN_PIN); #if BTN_ACT_DIR == 0 btn = (btn == 0) ? 1 : 0; #endif // bootloader activation methods i = *(volatile uint32_t *)USER_APP_START_ADDR; // first byte of user flash if (btn || (i == 0x00000000) || (i = 0xffffffff)) { // is button pushed, or flash empty? // bootloader is activated; configure systick to flash LED user_led_init(); // configure serial comms and print welcome banner // todo: implement autobaud? comm_init(); comm_tx_byte('\r'); comm_tx_byte('\n'); for (i = 0; i < 31; i++) { comm_tx_byte('='); } comm_tx_str("\r\ntrueControl HK32F Loader v0.0.2\r\n"); for (i = 0; i < 31; i++) { comm_tx_byte('='); } // wait for firmware load or reset while(1) { // announce bootloader start comm_tx_str("\r\n\r\nsend firmware file using XMODEM\r\n\r\n"); // start listening for data and letting user know to send XMODEM data if (xmodem_receive() == X_OK) { comm_tx_str("\r\nflash updated; booting.\r\n\r\n"); break; } // if xmodem exits, there was a failure. repeat the process. comm_tx_str("\r\nfailed to update; try again.\r\n"); } } // bootloader is either done not activated; jump to user code jump_to_user_app(); } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char* file , uint32_t line) { /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /* USE_FULL_ASSERT */