shuichan_old/V1.4/STM32F103_BootLoader/Src/main.c

194 lines
5.9 KiB
C
Raw Normal View History

/**
* BootLoader
*
* :
* 1.
* 2. W25Q64 Flash OTA
* 3. :
* - DOWNLOADED: APP1
* - INSTALLED: APP 退
* - ROLLBACK: 退
* - : APP1
* 4. BootLoader VTOR (0x08000000)
*
* Flash (STM32F103RCT6 256KB):
* 0x08000000 BootLoader (32KB)
* 0x08008000 APP1 (224KB)
*
* W25Q64 Flash :
* 0x000000 A: (256KB)
* 0x040000 B: (256KB)
* 0x080000 A (4KB)
* 0x081000 B (4KB)
*/
#include "main.h"
#include "ota_boot.h"
#include "../HardWare/W25Q64/w25q64.h"
#include "../HardWare/LOG/log.h"
/* 串口句柄 */
UART_HandleTypeDef huart1; /* USART1: 调试日志输出 */
UART_HandleTypeDef huart3; /* USART3: OTA 数据通信 */
DMA_HandleTypeDef hdma_usart3_rx; /* USART3 RX DMA */
IWDG_HandleTypeDef hiwdg; /* 独立看门狗:防止擦写/拷贝流程卡死 */
/* OTA 协议接收缓冲区 */
uint8_t Rx_Flag = 0; /* 收到一帧数据标志 */
uint16_t Rx_Len = 0; /* 当前帧数据长度 */
uint8_t Rx_Buf[Rx_Max] = {0}; /* DMA 接收缓冲区 */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_IWDG_Init(void);
/**
* @brief BootLoader
*
* :
* DMA
* 1OTA数据 APP1
*
* @note BootLoader VTOR (0x08000000)
*/
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
/* USART3: 启动 DMA + IDLE 中断接收 OTA 数据帧 */
HAL_UART_Receive_DMA(&huart3, Rx_Buf, Rx_Max);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
/* 启动独立看门狗:跳转 APP 后由 APP 继续喂狗 */
MX_IWDG_Init();
/* 核心启动逻辑 */
if (W25Q64_Init() != 0) {
log_error("[BL] W25Q64 init fail!");
}
Start_BootLoader();
}
/**
* @brief : HSE(8MHz) PLL×9 72MHz SYSCLK
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) Error_Handler();
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) Error_Handler();
}
/**
* @brief USART1 : , PA9(TX)/PA10(RX), 115200-8N1
*/
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) Error_Handler();
}
/**
* @brief USART3 : OTA , PB10(TX)/PB11(RX), 921600-8N1, DMA+IDLE
* @note APP 4G (AT+IPR=921600)
*/
static void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 921600;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK) Error_Handler();
}
/**
* @brief DMA : USART3 RX 使 DMA1 3
*/
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
/**
* @brief GPIO : GPIOA/USART1, GPIOB/USART3 , GPIOD/
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef g = {0};
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();
/* 关闭 JTAG保留 SWD释放 PA15/PB3/PB4 给 W25Q64 */
__HAL_AFIO_REMAP_SWJ_NOJTAG();
/* PC13(LED2):外部看门狗 TPL5010 的 DONE 喂狗引脚 */
g.Pin = GPIO_PIN_13;
g.Mode = GPIO_MODE_OUTPUT_PP;
g.Pull = GPIO_NOPULL;
g.Speed = GPIO_SPEED_FREQ_LOW; /* PC13 驱动能力弱,只能低速 */
HAL_GPIO_Init(GPIOC, &g);
}
/**
* @brief : LSI(~40kHz) / 256 / 4095 26s
* @note LSI 30~60kHz 17s
* W25Q64 5s
*/
static void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
hiwdg.Init.Reload = 4095;
if (HAL_IWDG_Init(&hiwdg) != HAL_OK) Error_Handler();
}
void Error_Handler(void)
{
/* 初始化失败:停在这里,避免带着未就绪的硬件继续运行 */
__disable_irq();
while (1)
{
}
}