Initial bootloader implementation

Took a publicly available XMODEM bootloader and made it work on HK32F.

Known issues:
- Erase is super slow on this MCU. The upload routine erases all flash before loading, which means the first packet seems to hang. This also erases possibly persistent data stored in unused pages on flash.
This commit is contained in:
true
2023-06-25 01:41:36 -07:00
parent 861caf8bce
commit a47cfa7fa5
83 changed files with 39624 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
#include "systick_delay.h"
#include "hk32f030m.h"
static uint32_t fac_us = 0;
static uint32_t fac_ms = 0;
/*******************************************************************************
* Function Name : SysTick_Init
* Description : SysTick Initialize
* Input : none
* Output : none
* Return : none
* Set SysTick clock source to 1/8 of HCLK
*******************************************************************************/
void SysTick_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us = SystemCoreClock / 8000000;
fac_ms = SystemCoreClock / 8000;
}
/*******************************************************************************
* Function Name : SysTick_DelayUs
* Description : delay by microseconds
* Input : nus -- number of microseconds
* Output : none
* Return : none
*******************************************************************************/
void SysTick_DelayUs(uint32_t nus)
{
uint32_t temp;
if (nus > 0)
{
SysTick->LOAD = nus * fac_us; // Set Reload Value
SysTick->VAL = 0x00; // Set Current Value to 0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // Start counter
// Block when SysTick is running and counter flag not set
do
{
temp = SysTick->CTRL;
}
while ((temp & SysTick_CTRL_ENABLE_Msk) && !(temp & SysTick_CTRL_COUNTFLAG_Msk));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // Stop counter
}
}
/*******************************************************************************
* Function Name : SysTick_DelayMs
* Description : Delay by milliseconds
SysTick->LOAD is 24-bit so the max delay = 0xFFFFFF*8*1000 / SYSCLK
* Input : nms -- number of milliseconds
*******************************************************************************/
void SysTick_DelayMs(uint16_t nms)
{
uint32_t temp;
if (nms > 0)
{
SysTick->LOAD = nms * fac_ms; // Set Reload Value (24-bit)
SysTick->VAL = 0x00; // Set Current Value to 0
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // Start counter
// Block when SysTick is running and counter flag not set
do
{
temp = SysTick->CTRL;
}
while ((temp & SysTick_CTRL_ENABLE_Msk) && !(temp & SysTick_CTRL_COUNTFLAG_Msk));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // Stop counter
}
}

View File

@@ -0,0 +1,10 @@
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "hk32f030m.h"
void SysTick_Init(void);
void SysTick_DelayUs(uint32_t nus);
void SysTick_DelayMs(uint16_t nms);
#endif

View File

@@ -0,0 +1,115 @@
#include "uart_printf.h"
#define UART_PRINTF_BAUDRATE 115200
uint8_t HEX_TABLE[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void UART_PrintfInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
#if UART_PORTx == UART_PORT_TX_A3_RX_D6
// Enable GPIO and UART clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// AF config
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_1);
// PA3 As USART TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PD6 As USART RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);
#elif UART_PORTx == UART_PORT_TX_A3_RX_B4
// Enable GPIO and UART clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// AF config
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); // TX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4); // RX
// PA3 As USART TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PB4 As USART RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#endif
USART_InitStructure.USART_BaudRate = UART_PRINTF_BAUDRATE;
// 8-bit, 1 stop bit, no parity, no hardware flow control
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// Enable Tx
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
// Init and enable UART1
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void UART_SendByte(uint8_t ch)
{
/* Send one byte to USART */
USART_SendData(USART1, ch);
/* Block till tx empty flag is set */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void UART_SendArray(uint8_t *array, uint16_t num)
{
uint8_t i;
for (i = 0; i < num; i++)
{
UART_SendByte(array[i]);
}
/* Block till transmission is completed */
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}
void UART_SendString(char *str)
{
while (*str)
{
UART_SendByte(*str++);
}
/* Block till transmission is completed */
while (USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
void UART_TxHex(uint8_t *hex, uint8_t len)
{
while (len--)
{
UART_SendByte(HEX_TABLE[*(hex + len) >> 4 & 0xF]);
UART_SendByte(HEX_TABLE[*(hex + len) & 0xF]);
}
}
int __io_putchar(int ch)
{
UART_SendByte((uint8_t)ch);
return ch;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}

View File

@@ -0,0 +1,18 @@
#ifndef __UART_PRINTF_H
#define __UART_PRINTF_H
#include "hk32f030m.h"
#include "stdio.h"
#define UART_PORT_TX_A3_RX_D6 0
#define UART_PORT_TX_A3_RX_B4 1
#define UART_PORTx UART_PORT_TX_A3_RX_D6
void UART_PrintfInit(void);
void UART_SendByte(uint8_t ch);
void UART_SendHalfWord(uint16_t ch);
void UART_SendArray(uint8_t *array, uint16_t num);
void UART_SendString(char *str);
void UART_TxHex(uint8_t *hex, uint8_t len);
#endif