94 lines
2.6 KiB
C
94 lines
2.6 KiB
C
|
/*
|
||
|
* 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)
|
||
|
{
|
||
|
uint8_t btn;
|
||
|
//volatile uint16_t timeout = 0xffff;
|
||
|
|
||
|
// ensure the bootloader is write protected
|
||
|
// TODO
|
||
|
|
||
|
// configure button and LED
|
||
|
user_io_init();
|
||
|
|
||
|
// need a small delay to ensure the button pullup/down will charge/discharge pin capacitance
|
||
|
//while (--timeout);
|
||
|
|
||
|
// get button state
|
||
|
btn = BTN_PORT->IDR & (1 << BTN_PIN);
|
||
|
#if BTN_ACT_DIR == 0
|
||
|
btn = (btn == 0) ? 1 : 0;
|
||
|
#endif
|
||
|
|
||
|
// bootloader activation methods
|
||
|
if (btn // button pushed
|
||
|
|| (*(volatile uint32_t *)USER_APP_START_ADDR) == 0x00000000 // flash empty
|
||
|
|| (*(volatile uint32_t *)USER_APP_START_ADDR) == 0xFFFFFFFF) { // flash empty
|
||
|
|
||
|
// bootloader is activated, show it
|
||
|
user_led_init();
|
||
|
|
||
|
// configure serial comms and print welcome banner
|
||
|
// todo: implement autobaud?
|
||
|
comm_init();
|
||
|
|
||
|
const uint8_t *banner_bar = (uint8_t *)"\r\n================================================\r\n";
|
||
|
comm_tx_str((uint8_t *)banner_bar);
|
||
|
comm_tx_str((uint8_t *)"trueControl HK32F XMODEM Flash Bootloader v0.0.1");
|
||
|
comm_tx_str((uint8_t *)banner_bar);
|
||
|
|
||
|
// wait for firmware load or reset
|
||
|
while(1) {
|
||
|
comm_tx_str((uint8_t*)"\r\nsend binary file using XMODEM to update firmware");
|
||
|
comm_tx_str((uint8_t*)"\r\nthe first data block will take time. it's normal\r\n\r\n");
|
||
|
xmodem_receive();
|
||
|
|
||
|
// if xmodem exits, there was a failure. repeat the process.
|
||
|
comm_tx_str((uint8_t*)"\r\nfailed to update. try again.\r\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// bootloader is 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 */
|