LCD_QSPIBoot/asw/bootapp.c
2025-05-26 10:37:37 +08:00

324 lines
8.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************************
* the includes
******************************************************************************/
#include "bootapp.h"
#include "norflash.h"
#include "stm32l4xx_hal_crc.h"
#include "stm32l4xx_hal_dma.h"
#include "stm32l4xx_hal_gpio.h"
#include "stm32l4xx_hal_uart.h"
#include "uartapp.h"
#include "stdio.h"
#include "hardware.h"
#include <stdint.h>
#include <stdio.h>
/*******************************************************************************
* the defines
******************************************************************************/
#define ENABLE_INT() __set_PRIMASK(0) /* 使能全局中断 */
#define DISABLE_INT() __set_PRIMASK(1) /* 禁止全局中断 */
/*******************************************************************************
* the typedefs
******************************************************************************/
typedef struct
{
uint32_t startflag;
uint32_t len;
uint32_t AppCRC;
uint32_t reverse;
} APPCRC_type;
typedef struct
{
uint32_t startflag;
uint32_t sBootloader_Req;
uint32_t reboot_times;
uint32_t hardfault_data;
uint32_t reverse[12];
}NO_INIT_DATA_Type;
typedef struct
{
uint8_t reqFlag;
uint8_t eraseState;
uint8_t eraseLen;
uint8_t eraseStep;
}EraseReq_Type;
typedef enum {
BOOT_INIT,
BOOT_WAIT,
BOOT_APP_CHECK,
BOOT_APP_JUMP,
BOOT_STOP,
BOOT_ERASE,
BOOT_STATE_NUM,
}BOOT_STATE_Type;
/*******************************************************************************
* the globals
******************************************************************************/
volatile NO_INIT_DATA_Type noInitData __attribute__((section(".boot_flags")));
static uint8_t bootflag = 0;
static BOOT_STATE_Type bootState = BOOT_INIT;
extern UART_HandleTypeDef huart1;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern CRC_HandleTypeDef hcrc;
static EraseReq_Type eraseReq;
/*******************************************************************************
* the const
******************************************************************************/
/*******************************************************************************
* the functions
******************************************************************************/
static void bootApp_EraseTask(void);
static void BspQspiBoot_JumpToApp(void)
{
uint32_t i = 0;
void (*AppJump)(void); /* 声明一个函数指针 */
__IO uint32_t AppAddr = EX_FLASH_APP_ADDR; /* APP 地址 */
/* 关闭全局中断 */
DISABLE_INT();
/* 设置所有时钟到默认状态使用HSI时钟 */
HAL_RCC_DeInit();
HAL_UART_DeInit(&huart1);
HAL_DMA_DeInit(&hdma_usart1_rx);
HAL_CRC_DeInit(&hcrc);
// __HAL_RCC_SPI1_FORCE_RESET();
// __HAL_RCC_SPI1_RELEASE_RESET();
// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_5);
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
/* 使能全局中断 */
ENABLE_INT();
/* 跳转到应用程序首地址是MSP地址+4是复位中断服务程序地址 */
AppJump = (void (*)(void))(*((uint32_t*)(AppAddr + 4)));
/* 设置主堆栈指针 */
__set_MSP(*(uint32_t*)AppAddr);
/* 在RTOS工程这条语句很重要设置为特权级模式使用MSP指针 */
__set_CONTROL(0);
/* 跳转到系统BootLoader */
AppJump();
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
}
void WriteCRCInfo(uint32_t len, uint32_t crc)
{
APPCRC_type appcrc;
appcrc.startflag = 0xAA5555AA;
appcrc.len = len;
appcrc.AppCRC = crc;
appcrc.reverse = 0xAAAAAAAA;
NORFLASH_Write_NoCheck((uint8_t*)&appcrc, W26Q64_CRC_ADDR, 0x10);
}
uint8_t ReadCRCInfo(uint32_t* len, uint32_t* crc)
{
APPCRC_type* appcrc = (APPCRC_type*)EX_FLASH_CRC_ADDR;
if (appcrc->startflag == 0xAA5555AA)
{
*len = appcrc->len;
*crc = appcrc->AppCRC;
return 1;
}
else
{
return 0;
}
}
uint8_t Boot_checkApp(void)
{
uint32_t len, crc;
if (ReadCRCInfo(&len, &crc) == 1)
{
if (crc_calc(EX_FLASH_APPINFO_ADDR, len) == crc)
{
return 1;
}
else
{
return 0;
}
}
return 0;
}
void bootApp_init(void)
{
if (noInitData.startflag != 0xAA5555AA) {
printf("init bootflag\n");
noInitData.startflag = 0xAA5555AA;
noInitData.sBootloader_Req = 0;
noInitData.reboot_times = 0;
noInitData.hardfault_data = 0;
}
else {
noInitData.reboot_times++;
printf("reboot_times = %d\n", noInitData.reboot_times);
if (noInitData.sBootloader_Req == 0x778899AA) {
noInitData.sBootloader_Req = 0;
bootflag = 1;
}
else {//if(noInitData.sBootloader_Req != 0)
printf("bootreq = %lx\n",noInitData.sBootloader_Req);
}
if (noInitData.hardfault_data != 0) {
printf("hardfault_data = %lx\n", noInitData.hardfault_data);
}
}
}
void bootApp_mainTask(void)//1ms
{
static uint16_t timeout_count = 0,bootkey_delay=0;
switch (bootState) {
case BOOT_INIT: {
bootState = BOOT_WAIT;
break;
}
case BOOT_WAIT: {
if (bootflag == 1) {
bootState = BOOT_STOP;
printf("get_bootreq,stop in boot\n");
break;
}
if (timeout_count++ > 100) {//100ms
timeout_count = 0;
bootState = BOOT_APP_CHECK;
NORFLASH_MemroyMapMode();
break;
}
if (get_BOOTKEY() == 1) {
bootkey_delay++;
if (bootkey_delay > 5) {//5ms
bootkey_delay = 0;
bootState = BOOT_STOP;
printf("get_BOOTKEY,stop in boot\n");
break;
}
}
else {
bootkey_delay = 0;
}
break;
}
case BOOT_APP_CHECK: {
if (Boot_checkApp() == 1) {
bootState = BOOT_APP_JUMP;
break;
}
else {
printf("app not found\n");
NORFLASH_QuitMemroyMapMode();
bootState = BOOT_STOP;
break;
}
}
case BOOT_APP_JUMP: {
printf("jump to app\n");
BspQspiBoot_JumpToApp();
break;
}
case BOOT_STOP: {
timeout_count++;
if (timeout_count >= 10) {//1000ms
timeout_count = 0;
bootApp_EraseTask();
}
break;
}
default: {
break;
}
}
}
void bootApp_WriteHardFaultData(uint32_t data)
{
noInitData.hardfault_data = data;
}
void bootApp_ReqErase(uint8_t block_len)
{
if (block_len > 128) {
printf("block_len error\n");
return;
}
if (eraseReq.eraseState != 0) {
printf("erase is running\n");
return;
}
if (block_len == 0) {
NORFLASH_Erase_Chip();
}
else {
NORFLASH_Erase_Block(0);
}
eraseReq.reqFlag = 1;
eraseReq.eraseState = 1;
eraseReq.eraseLen = block_len;
eraseReq.eraseStep = 0;
}
static void bootApp_EraseTask(void)//10ms task
{
static uint32_t erase_count = 0;
if (eraseReq.reqFlag == 1) {
if (NORFLASH_Check_Busy() == 0) {
eraseReq.eraseStep++;
if (eraseReq.eraseStep > eraseReq.eraseLen) {
eraseReq.reqFlag = 0;
eraseReq.eraseState = 0;
eraseReq.eraseLen = 0;
printf("erase finashed %d ms\n",erase_count*10);
}
else {
NORFLASH_Erase_Block(eraseReq.eraseStep);
}
}
erase_count++;
if (erase_count % 400 == 0) {
printf("wait erase\n");
}
if (erase_count > 3000) {
erase_count = 0;
eraseReq.reqFlag = 0;
eraseReq.eraseState = 0;
eraseReq.eraseLen = 0;
printf("erase timeout\n");
}
}
else {
erase_count = 0;
}
}