iap.c 4.13 KB
#include "iap.h" 
#include "crc.h"
#include "flash.h"
#include "delay.h"
#include "usart1.h"    
#include "uart5.h" 
#include "ymodem.h"
#include "string.h"
iapfun 	jump2app; 

extern USART_TypeDef * IAP_Port;
	
#define SEPERATE				"\r\n***********************wisefarm bootloader***********************\r\n\r\n"	
#define WELCOME					"Wisefarm bootloader start.....\r\n"
#define END							"Wisefarm bootloader end.....\r\n"
#define VERSION					"Version: MFGW2.0\r\n"
#define RUN_POINT				"App will be running.....\r\n"
#define INPUT_PONIT			"Press down key \"B\" at least 2S to s in bootloader\r\n"
#define CUTDOWN_PONIT		"Run application after %d second(s)......\r\n"
uint8_t Run_Flash_App(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.
	{
	
		display_bootloader_exit_information();	
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到APP.
		return 1;
	}
	else
	{
		return 0;
	}
}
void display_bootloader_extry_information(void)
{
	GPIO_ResetBits(ARM_LED1_Port,ARM_LED1_Pin);
	GPIO_ResetBits(ARM_LED2_Port,ARM_LED2_Pin);//GPIOF9,F10设置高,灯灭
	GPIO_ResetBits(ARM_LED3_Port,ARM_LED3_Pin);//GPIOF9,F10设置高,灯灭
	GPIO_ResetBits(ARM_LED4_Port,ARM_LED4_Pin);//GPIOF9,F10设置高,灯灭		
	
	printf(SEPERATE);
	printf(WELCOME);
	printf(VERSION);
	
}
void display_bootloader_exit_information(void)
{
	GPIO_SetBits(ARM_LED1_Port,ARM_LED1_Pin);
	GPIO_SetBits(ARM_LED2_Port,ARM_LED2_Pin);//GPIOF9,F10设置高,灯灭
	GPIO_SetBits(ARM_LED3_Port,ARM_LED3_Pin);//GPIOF9,F10设置高,灯灭
	GPIO_SetBits(ARM_LED4_Port,ARM_LED4_Pin);//GPIOF9,F10设置高,灯灭		
	printf(RUN_POINT);		
	printf(END);
	printf(SEPERATE);		
}
uint8_t uart_boot_detect(void)
{
	uint8_t retry_cnt=0;

	char buf_rx5[20]={0};
	char buf_rx1[20]={0};	
	printf(INPUT_PONIT);
	
	for(retry_cnt=0;retry_cnt<LOCAL_WAITE_TIME;retry_cnt++)
	{
		printf(CUTDOWN_PONIT,LOCAL_WAITE_TIME-retry_cnt);
		
		uint32_t timeout =0x100000;	
		
		memset(buf_rx5,0,sizeof(char));
		memset(buf_rx1,0,sizeof(char));		
		uint8_t i=0,j=0;
		while (timeout-- > 0)		
		{
			if (uart5_read_byte((uint8_t *)&buf_rx5[i]) == 1)
			{	
				i++;
				if(i>20)
				{
					i=0;
				}
				
				if((strcmp(buf_rx5,"BBBBBBBBBBBBBBBBBBBB"))==0)
				{
					IAP_Port=UART5;					
					return LOCAL_BOOT_FROM_UART5;				
				}
			}		
			if (usart1_read_byte((uint8_t *)&buf_rx1[j]) == 1)
			{	
				j++;
				if(i>20)
				{
					i=0;
				}				
				
				if((strcmp(buf_rx1,"BBBBBBBBBBBBBBBBBBBB"))==0)
				{
					IAP_Port=USART1;					
					return LOCAL_BOOT_FROM_USART1;				
				}
			}		
		}
		
	}
	return LOCAL_BOOT_NONE;	
}
void uart_boot(void)
{
		uint32_t ret =0;
		printf("Enter bootloader......\r\n");
		if(IAP_Port==USART1)
		{
			printf("Port:USART1\tbaudrate:115200\t\tformat:N-8-1\r\n");
		}
		else
		{
			printf("Port:UART5\tbaudrate:115200\t\tformat:N-8-1\r\n");
		}
		
		printf("please send file to device in y-modem!\r\n");

		printf("Waiting:");		
		ret = Ymodem_Receive(buf_1k,APP_LOAD_ADDR);
		printf("\r\n");		
		
		if(ret >0)
		{
			printf("Received file name:\t\t\t\t%s\r\n",FileName);	
			printf("Received file length:\t\t\t\t%s\r\n",file_size);	
		}
		else
		{
			printf("Failure of ymodem receive!\r\n");	
			assert_param(0);		
		}
		load_process();
}
void load_process(void)
{

	uint32_t flag =0;

	printf("Fireware detected,now loading...\r\n");
	printf("Erasing!\t\t\t\t\t");	
	if(0 == STM_FLASH_Erase(APP_RUN_ADDR))
	{
		printf("failure\r\n");	
		assert_param(0);		
	}
	if(0 == STM_FLASH_Erase(FLAG_BASE_ADDR))
	{
		printf("failure\r\n");
		assert_param(0);		
	}
	printf("success\r\n");
	printf("Programing !\t\t\t\t\t");	
	if(1 == STMFLASH_Write(APP_RUN_ADDR,(uint32_t *)APP_LOAD_ADDR,STM_FLASH_Get_Block_Size(APP_RUN_ADDR)))
	{
			printf("failure!\r\n");
			assert_param(0);	
	}
		flag =BOOTLOADER_RUN;	
	if(1 == STMFLASH_Write(FLAG_BASE_ADDR,&flag,4))
	{
			printf("failure!\r\n");
			assert_param(0);
	}	
	printf("success\r\n");
	
  app_run();	
}
void app_run(void)
{
	if(0==Run_Flash_App(APP_RUN_ADDR))
	{
		printf("Run app failure!the firmware may be damaged!\r\n");	
		uart_boot();
	}
}