#include "stm32f10x.h"
#include "Iwdg_hard_dri.h"
#include "Flash_module.h"
#include "Printf.h"
#include <string.h>
#include <stdio.h>
u8 M3_UPDATA_SUCESS[20] ="SUCCESS_UPDATA_M3APP";
u8 RtoWbuf[PAGE_SIZE];
u16 Page_nu;
u16 Byte_nu;
void MYRCC_DeInit(void)
{
RCC->APB1RSTR = 0x00000000;//復位結束
RCC->APB2RSTR = 0x00000000;
RCC->AHBENR = 0x00000014; //睡眠模式閃存和SRAM時鐘使能.其他關閉.
RCC->APB2ENR = 0x00000000; //外設時鐘關閉.
RCC->APB1ENR = 0x00000000;
RCC->CR |= 0x00000001; //使能內部高速時鐘HSION
RCC->CFGR &= 0xF8FF0000; //復位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC->CR &= 0xFEF6FFFF; //復位HSEON,CSSON,PLLON
RCC->CR &= 0xFFFBFFFF; //復位HSEBYP
RCC->CFGR &= 0xFF80FFFF; //復位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
RCC->CIR = 0x00000000; //關閉所有中斷
//配置向量表
}
int AppProgramRun(void)
{
u32 AppSpInitVal; //App程序的SP初值.
u32 AppJumpAddr; //APP程序的跳轉地址.即,APP程序的入口.
void (*pAppFun)(void); //定義一個函數指針.用於指向APP程序入口.
AppSpInitVal = *(u32 *)RUN_M3APP_ADDR_START; //取APP的SP初值.
if (AppSpInitVal & 0XFFFF0000 != 0X20000000) //APP未寫入.不能跳.
{
// FaceEnterDialog (&OpFailDialog);
return 1;
}
AppJumpAddr = *( u32 *)(RUN_M3APP_ADDR_START + 4); //取程序入口.
if ((AppJumpAddr & 0Xfff80000) != 0X08000000) //APP無效.不能跳.
{
// FaceEnterDialog (&OpFailDialog);
return 2;
}
MYRCC_DeInit(); //恢復NVIC爲復位狀態.使中斷不再發生.
//__MSR_MSP(AppSpInitVal); //設置SP.
__set_MSP(AppSpInitVal);
pAppFun = (void (*)(void))AppJumpAddr; //生成跳轉函數.
(*pAppFun)(); //跳轉.不再返回.
return 0;
}
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;
// MYRCC_DeInit(); //復位並配置向量表
RCC->CR|=0x00010000; //外部高速時鐘使能HSEON
while(!(RCC->CR>>17));//等待外部時鐘就緒
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2;//抵消2個單位
RCC->CFGR|=PLL<<18; //設置PLL值 2~16
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x32; //FLASH 2個延時週期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待PLL鎖定
RCC->CFGR|=0x00000002;//PLL作爲系統時鐘
while(temp!=0x02) //等待PLL作爲系統時鐘設置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
int main(void)
{
u16 buf[2];
u32 BACK_M3ADDR;
u32 RUN_M3ADDR;
u16 i;
MYRCC_DeInit();
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0); //復位向量表
Stm32_Clock_Init(9); //初始化時鐘 72mhz
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶佔優先級,2位響應優先級
Printf_Debug_Init(UART_Thou); //初始化調試口串口4
//初始化看門狗4s
IWDG_Init(6,625);
printf("now is in bootloader \r\n");
#if 1
if(memcmp((u32*)ARMAPP_upstatus,"UPDATA_M3_APP",strlen("UPDATA_M3_APP")) == 0)
{
// printf("no updatastatus ,go to app\r\n");
//喂狗
IWDG_Feed();
STMFLASH_ReadHalfWord_buf(BACK_M3APP_ADDR_START -4 , buf, 2);
Page_nu = buf[0];
Byte_nu = buf[1];
BACK_M3ADDR = BACK_M3APP_ADDR_START;
RUN_M3ADDR = RUN_M3APP_ADDR_START;
printf(" Page_nu is %d\r\n", Page_nu);
printf(" Byte_nu is %d\r\n", Byte_nu);
if(Page_nu > 0)
{
for(i = 0;i<Page_nu;i++)
{
STMFLASH_ReadByte_buf(BACK_M3ADDR, RtoWbuf,PAGE_SIZE);
STMFLASH_WriteByte_buf(RUN_M3ADDR , RtoWbuf , PAGE_SIZE);
BACK_M3ADDR += PAGE_SIZE;
RUN_M3ADDR += PAGE_SIZE;
}
}
STMFLASH_ReadByte_buf(BACK_M3ADDR, RtoWbuf,Byte_nu);
STMFLASH_WriteByte_buf(RUN_M3ADDR , RtoWbuf ,Byte_nu);
//寫上升級完成標誌位
STMFLASH_WriteByte_buf(ARMAPP_upstatus ,M3_UPDATA_SUCESS , strlen(M3_UPDATA_SUCESS ));
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000); //設置APP的向量表
AppProgramRun();
}
else
{
//喂狗
IWDG_Feed();
printf("no updatastatus ,go to app\r\n");
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000); //設置APP的向量表
AppProgramRun();
}
#endif
}