#include "base.h" #include "delay.h" #include "flash_manager.h" #include "lcd_pwm.h" #include "lcd_rgb.h" #include "led.h" #include "mymem.h" #include "sdram.h" #include "spi_flash.h" #include "string.h" #include "usart.h" // 定义cmd变量 #define IAP_CMD (*((uint32_t *)0x20000000)) #define IAP_INDEX (*((uint32_t *)0x20000004)) // 定义cmd取值 #define IAP_CMD_UPDATA 0xff000001 // 直接升级user.app #define IAP_CMD_UPINDEX 0xff000002 // 升级指定序号的程序 #define IAP_CMD_SELECT 0xff000003 // 选择启动方式 #define IAP_CMD_NONE 0x00000000 // 定义用于升级的文件名 #define APP_NAME "user.app" // 定义用户程序区的起始地址 #define APP_ADDR (0x08000000 + 128 * 1024) // 定义显示跳跃像素 #define Y_JUMP 16 // 在指定位置显示字符串 static void drawCharsAt(char *txt, int x, int y); static void jump_app(void); static void Init(void); static void FLASH_EraseBySize(uint32_t size); static void FLASH_WriteBySize(uint8_t *buff, uint32_t size); static void FLASH_UpData(uint8_t *buff, uint32_t size); static void iap_cmd_select(void); static void iap_cmd_updata(void); static void iap_cmd_upindex(void); static int x = 0; static int y = -Y_JUMP; int main() { Init(); if (IAP_CMD == IAP_CMD_SELECT) { iap_cmd_select(); } else if (IAP_CMD == IAP_CMD_UPDATA) { iap_cmd_updata(); } else if (IAP_CMD == IAP_CMD_UPINDEX) { iap_cmd_upindex(); } IAP_CMD = IAP_CMD_NONE; jump_app(); while (1) ; } //--------------------------------------------------------------- //--------------------LCD显示相关-------------------------------- static const unsigned char g_asc2_1608[95][16] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/ {0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, /*"!",1*/ {0x00, 0x12, 0x36, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*""",2*/ {0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0xFE, 0x48, 0x48, 0x48, 0xFE, 0x48, 0x48, 0x48, 0x00, 0x00}, /*"#",3*/ {0x00, 0x00, 0x10, 0x38, 0x54, 0x54, 0x50, 0x30, 0x18, 0x14, 0x14, 0x54, 0x54, 0x38, 0x10, 0x10}, /*"$",4*/ {0x00, 0x00, 0x00, 0x44, 0xA4, 0xA8, 0xA8, 0xA8, 0x54, 0x1A, 0x2A, 0x2A, 0x2A, 0x44, 0x00, 0x00}, /*"%",5*/ {0x00, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x50, 0x6E, 0xA4, 0x94, 0x88, 0x89, 0x76, 0x00, 0x00}, /*"&",6*/ {0x00, 0x60, 0x60, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/ {0x00, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00}, /*"(",8*/ {0x00, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00}, /*")",9*/ {0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0xD6, 0x38, 0x38, 0xD6, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00}, /*"*",10*/ {0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00}, /*"+",11*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x20, 0xC0}, /*",",12*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"-",13*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, /*".",14*/ {0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00}, /*"/",15*/ {0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, /*"0",16*/ {0x00, 0x00, 0x00, 0x10, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00}, /*"1",17*/ {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x04, 0x04, 0x08, 0x10, 0x20, 0x42, 0x7E, 0x00, 0x00}, /*"2",18*/ {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x04, 0x18, 0x04, 0x02, 0x02, 0x42, 0x44, 0x38, 0x00, 0x00}, /*"3",19*/ {0x00, 0x00, 0x00, 0x04, 0x0C, 0x14, 0x24, 0x24, 0x44, 0x44, 0x7E, 0x04, 0x04, 0x1E, 0x00, 0x00}, /*"4",20*/ {0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x58, 0x64, 0x02, 0x02, 0x42, 0x44, 0x38, 0x00, 0x00}, /*"5",21*/ {0x00, 0x00, 0x00, 0x1C, 0x24, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, /*"6",22*/ {0x00, 0x00, 0x00, 0x7E, 0x44, 0x44, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00}, /*"7",23*/ {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"8",24*/ {0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x26, 0x1A, 0x02, 0x02, 0x24, 0x38, 0x00, 0x00}, /*"9",25*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, /*":",26*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20}, /*";",27*/ {0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /*"<",28*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"=",29*/ {0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, /*">",30*/ {0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x62, 0x02, 0x04, 0x08, 0x08, 0x00, 0x18, 0x18, 0x00, 0x00}, /*"?",31*/ {0x00, 0x00, 0x00, 0x38, 0x44, 0x5A, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0x42, 0x44, 0x38, 0x00, 0x00}, /*"@",32*/ {0x00, 0x00, 0x00, 0x10, 0x10, 0x18, 0x28, 0x28, 0x24, 0x3C, 0x44, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"A",33*/ {0x00, 0x00, 0x00, 0xF8, 0x44, 0x44, 0x44, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0xF8, 0x00, 0x00}, /*"B",34*/ {0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x80, 0x80, 0x80, 0x80, 0x80, 0x42, 0x44, 0x38, 0x00, 0x00}, /*"C",35*/ {0x00, 0x00, 0x00, 0xF8, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0xF8, 0x00, 0x00}, /*"D",36*/ {0x00, 0x00, 0x00, 0xFC, 0x42, 0x48, 0x48, 0x78, 0x48, 0x48, 0x40, 0x42, 0x42, 0xFC, 0x00, 0x00}, /*"E",37*/ {0x00, 0x00, 0x00, 0xFC, 0x42, 0x48, 0x48, 0x78, 0x48, 0x48, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00}, /*"F",38*/ {0x00, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x80, 0x80, 0x80, 0x8E, 0x84, 0x44, 0x44, 0x38, 0x00, 0x00}, /*"G",39*/ {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"H",40*/ {0x00, 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00}, /*"I",41*/ {0x00, 0x00, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0xF0}, /*"J",42*/ {0x00, 0x00, 0x00, 0xEE, 0x44, 0x48, 0x50, 0x70, 0x50, 0x48, 0x48, 0x44, 0x44, 0xEE, 0x00, 0x00}, /*"K",43*/ {0x00, 0x00, 0x00, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0xFE, 0x00, 0x00}, /*"L",44*/ {0x00, 0x00, 0x00, 0xEE, 0x6C, 0x6C, 0x6C, 0x6C, 0x54, 0x54, 0x54, 0x54, 0x54, 0xD6, 0x00, 0x00}, /*"M",45*/ {0x00, 0x00, 0x00, 0xC7, 0x62, 0x62, 0x52, 0x52, 0x4A, 0x4A, 0x4A, 0x46, 0x46, 0xE2, 0x00, 0x00}, /*"N",46*/ {0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00}, /*"O",47*/ {0x00, 0x00, 0x00, 0xFC, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00}, /*"P",48*/ {0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0xB2, 0xCA, 0x4C, 0x38, 0x06, 0x00}, /*"Q",49*/ {0x00, 0x00, 0x00, 0xFC, 0x42, 0x42, 0x42, 0x7C, 0x48, 0x48, 0x44, 0x44, 0x42, 0xE3, 0x00, 0x00}, /*"R",50*/ {0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x40, 0x20, 0x18, 0x04, 0x02, 0x42, 0x42, 0x7C, 0x00, 0x00}, /*"S",51*/ {0x00, 0x00, 0x00, 0xFE, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00}, /*"T",52*/ {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"U",53*/ {0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x44, 0x24, 0x24, 0x28, 0x28, 0x18, 0x10, 0x10, 0x00, 0x00}, /*"V",54*/ {0x00, 0x00, 0x00, 0xD6, 0x92, 0x92, 0x92, 0x92, 0xAA, 0xAA, 0x6C, 0x44, 0x44, 0x44, 0x00, 0x00}, /*"W",55*/ {0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0xE7, 0x00, 0x00}, /*"X",56*/ {0x00, 0x00, 0x00, 0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00}, /*"Y",57*/ {0x00, 0x00, 0x00, 0x7E, 0x84, 0x04, 0x08, 0x08, 0x10, 0x20, 0x20, 0x42, 0x42, 0xFC, 0x00, 0x00}, /*"Z",58*/ {0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00}, /*"[",59*/ {0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02}, /*"\",60*/ {0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00}, /*"]",61*/ {0x00, 0x1C, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, /*"_",63*/ {0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x1E, 0x22, 0x42, 0x42, 0x3F, 0x00, 0x00}, /*"a",65*/ {0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00}, /*"b",66*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x40, 0x40, 0x40, 0x22, 0x1C, 0x00, 0x00}, /*"c",67*/ {0x00, 0x00, 0x00, 0x06, 0x02, 0x02, 0x02, 0x1E, 0x22, 0x42, 0x42, 0x42, 0x26, 0x1B, 0x00, 0x00}, /*"d",68*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x7E, 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00}, /*"e",69*/ {0x00, 0x00, 0x00, 0x0F, 0x11, 0x10, 0x10, 0x7E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00}, /*"f",70*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x44, 0x44, 0x38, 0x40, 0x3C, 0x42, 0x42, 0x3C}, /*"g",71*/ {0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"h",72*/ {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00}, /*"i",73*/ {0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x78}, /*"j",74*/ {0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x40, 0x4E, 0x48, 0x50, 0x68, 0x48, 0x44, 0xEE, 0x00, 0x00}, /*"k",75*/ {0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00}, /*"l",76*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x49, 0x49, 0x49, 0x49, 0x49, 0xED, 0x00, 0x00}, /*"m",77*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x62, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00}, /*"n",78*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, /*"o",79*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x64, 0x42, 0x42, 0x42, 0x44, 0x78, 0x40, 0xE0}, /*"p",0*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x22, 0x42, 0x42, 0x42, 0x22, 0x1E, 0x02, 0x07}, /*"q",81*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x32, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00}, /*"r",82*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x40, 0x3C, 0x02, 0x42, 0x7C, 0x00, 0x00}, /*"s",83*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00}, /*"t",84*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3B, 0x00, 0x00}, /*"u",85*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x28, 0x10, 0x10, 0x00, 0x00}, /*"v",86*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x92, 0x92, 0xAA, 0xAA, 0x44, 0x44, 0x00, 0x00}, /*"w",87*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x24, 0x18, 0x18, 0x18, 0x24, 0x76, 0x00, 0x00}, /*"x",88*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x28, 0x18, 0x10, 0x10, 0xE0}, /*"y",89*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x44, 0x08, 0x10, 0x10, 0x22, 0x7E, 0x00, 0x00}, /*"z",90*/ {0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00}, /*"{",91*/ {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, /*"|",92*/ {0x00, 0x60, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, 0x00}, /*"}",93*/ {0x30, 0x4C, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"~",94*/ }; static uint32_t drawCharAt16(char c, int x, int y) { uint8_t buff[24 * 2] = {0}; for (int t = 0; t < 16; t++) buff[t] = g_asc2_1608[c - 0x20][t]; for (int j = 0; j < 16; j++) { for (int i = 0; i < 8; i++) { // 只绘制无效窗口内的屏幕 LCD_DrawPointSafe(x + i, y + j, (buff[j] << i) & 0x80); } } return 8; } // 在指定位置显示字符串 static void drawCharsAt(char *txt, int x, int y) { if (txt == 0) return; while (*txt) { if ((*txt & 0x80) == 0) { x += drawCharAt16(*txt, x, y); txt++; } } } static void jump_app(void) { // 定义用户程序的起始地址 void (*user_main)(void); if (((*(vu32 *)APP_ADDR) & 0x2FF00000) == 0x20000000) // 检查栈顶地址是否合法. { NVIC_SetVectorTable(NVIC_VectTab_FLASH, 128 * 1024); user_main = (void (*)(void)) * (vu32 *)(APP_ADDR + 4); // 用户代码区第二个字为程序开始地址(复位地址) __set_MSP( *(vu32 *) APP_ADDR); // 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) user_main(); // 跳转到APP. } else { // 不存在程序,需要升级 IAP_CMD = IAP_CMD_SELECT; NVIC_SystemReset(); } } static void Init(void) { Delay_Init(); USART3_Init(); LED_Init(); Usart_Config(); SDRAM_Init(); mymem_init(); sFLASH_Init(); printf("Loading。。。\r\n"); for (int i = 0; i < 10; i++) { Delay_ms(10); if (USART3_GetKey()) { IAP_CMD = IAP_CMD_SELECT; } } } // 根据文件大小擦除flash static void FLASH_EraseBySize(uint32_t size) { const uint16_t sectors_1[] = { FLASH_Sector_5, FLASH_Sector_6, FLASH_Sector_7, FLASH_Sector_8, FLASH_Sector_9, FLASH_Sector_10, FLASH_Sector_11, 0}; int bank_num = size / (128 * 1024); if (size % (128 * 1024)) bank_num++; // 第一个bank擦除 for (int i = 0; sectors_1[i]; i++) { if (i >= bank_num) break; FLASH_EraseSector(sectors_1[i], VoltageRange_3); // 擦除电压选太高容易失败 } // 第二个bank前面的擦除 if (bank_num >= 8) { FLASH_EraseSector(FLASH_Sector_12, VoltageRange_3); FLASH_EraseSector(FLASH_Sector_13, VoltageRange_3); FLASH_EraseSector(FLASH_Sector_14, VoltageRange_3); FLASH_EraseSector(FLASH_Sector_15, VoltageRange_3); FLASH_EraseSector(FLASH_Sector_16, VoltageRange_3); } const uint16_t sectors_2[] = { FLASH_Sector_17, FLASH_Sector_18, FLASH_Sector_19, FLASH_Sector_20, FLASH_Sector_21, FLASH_Sector_22, FLASH_Sector_23, 0}; // 第二个bank擦除 for (int i = 0; sectors_2[i]; i++) { if (i + 8 >= bank_num) break; FLASH_EraseSector(sectors_2[i], VoltageRange_3); } } // 一次性写入数据 static void FLASH_WriteBySize(uint8_t *buff, uint32_t size) { for (uint32_t i = 0; i < size; i++) { FLASH_ProgramByte(APP_ADDR + i, buff[i]); } } // 升级程序 static void FLASH_UpData(uint8_t *buff, uint32_t size) { // 打标记,记录这是通过IAP升级的程序文件 uint32_t *app = (uint32_t *)buff; app[7] = 0x00000001; // 把rom大小记录在rom中 app[9] = size; drawCharsAt("FLASH Unlock ...", x, y += Y_JUMP); FLASH_Unlock(); drawCharsAt("Eraseing ...", x, y += Y_JUMP); FLASH_EraseBySize(size); drawCharsAt("Programing ...", x, y += Y_JUMP); FLASH_WriteBySize(buff, size); drawCharsAt("FLASH Lock ...", x, y += Y_JUMP); FLASH_Lock(); drawCharsAt("Updata Done, Reboot Later ...", x, y += Y_JUMP); } static void iap_cmd_select(void) { LCD_Init(); LCD_LayerInit(); drawCharsAt("Please Select:", x, y += Y_JUMP); drawCharsAt("00. Boot Now", x, y += Y_JUMP); drawCharsAt("01. Updata user.app File", x, y += Y_JUMP); // 升级flash中存放的程序 int fileNum = FLASH_GetFileNum(); char *txt = mymalloc(256); int *indexInfo = mymalloc(sizeof(int) * fileNum); int appIndex = 0; for (int i = 0; i < fileNum; i++) { FLASH_FileStruct fileInfo = {0}; FLASH_GetFileInfo(i, &fileInfo); int fileNameLen = strlen(fileInfo.FileName); if (strcmp(&fileInfo.FileName[fileNameLen - 4], ".app") == 0) { sprintf(txt, "%02d. Updata %s File", 2 + appIndex, fileInfo.FileName); indexInfo[appIndex] = i; // 记录索引 appIndex++; drawCharsAt(txt, x, y += Y_JUMP); } } char *staitc_txt = "Your Select is:"; int my_select = 0; int select_maxNum = fileNum + 2; drawCharsAt(staitc_txt, x, y += Y_JUMP); while (1) { uint8_t key = USART3_GetKeyPressed(); sprintf(txt, "%02d", my_select); drawCharsAt(txt, x + strlen(staitc_txt) * 8, y); if (key == 0x10) { // 上键 if (my_select > 0) { my_select--; } else { my_select = select_maxNum - 1; } } else if (key == 0x20) { // 下键 if (my_select < select_maxNum - 1) { my_select++; } else { my_select = 0; } } else if (key == 0x04) { // OK键 if (my_select == 0) { break; } else if (my_select == 1) { IAP_CMD = IAP_CMD_UPDATA; NVIC_SystemReset(); } else { IAP_CMD = IAP_CMD_UPINDEX; IAP_INDEX = indexInfo[my_select - 2]; NVIC_SystemReset(); } } } myfree(txt); myfree(indexInfo); } static void iap_cmd_updata(void) { LCD_Init(); LCD_LayerInit(); drawCharsAt("Init Done ...", x, y += Y_JUMP); uint32_t app_size = 0; uint32_t app_exAddr = 0; uint32_t app_addr = 0; drawCharsAt("Find " APP_NAME "...", x, y += Y_JUMP); app_exAddr = FLASH_FindFile(APP_NAME, &app_size); // 申请内存,加一个文件名的余量 int exDataLen = strlen(APP_NAME) + 1; uint8_t *data = mymalloc(app_size + exDataLen); if (app_exAddr && (FLASH_ReadFile(APP_NAME, 0, data, app_size) == app_size)) { // 把文件名信息加在rom中 memcpy(&data[app_size], APP_NAME, exDataLen); uint32_t *app = (uint32_t *)data; app[8] = APP_ADDR + app_size; FLASH_UpData(data, app_size + exDataLen); } else { drawCharsAt("Can't Find " APP_NAME ", Reboot Later ...", x, y += Y_JUMP); } myfree(data); Delay_ms(10 * 1000); } static void iap_cmd_upindex(void) { // 根据索引找到文件 LCD_Init(); LCD_LayerInit(); char *txt_buf = mymalloc(256); drawCharsAt("Init Done ...", x, y += Y_JUMP); uint32_t app_size = 0; uint32_t app_exAddr = 0; uint32_t app_addr = 0; FLASH_FileStruct file = {0}; sprintf(txt_buf, "Find File By Index %d...", IAP_INDEX); drawCharsAt(txt_buf, x, y += Y_JUMP); if (FLASH_GetFileInfo(IAP_INDEX, &file) == 0) { sprintf(txt_buf, "File Name is: %s...", file.FileName); drawCharsAt(txt_buf, x, y += Y_JUMP); app_exAddr = file.Address; app_size = file.FileSize; // 申请内存,加一个文件名的余量 int exDataLen = strlen(file.FileName) + 1; uint8_t *data = mymalloc(app_size + exDataLen); FLASH_ReadFile(file.FileName, 0, data, app_size); // 把文件名信息加在rom中 memcpy(&data[app_size], file.FileName, exDataLen); uint32_t *app = (uint32_t *)data; app[8] = APP_ADDR + app_size; FLASH_UpData(data, app_size + exDataLen); myfree(data); } else { sprintf(txt_buf, "Can't Find File By Index %d...", IAP_INDEX); drawCharsAt(txt_buf, x, y += Y_JUMP); drawCharsAt("Reboot Later ...", x, y += Y_JUMP); } myfree(txt_buf); Delay_ms(10 * 1000); } extern void LTDC_ISR_Handler(void); // 函数:LTDC中断服务函数 // 说明:在emWin_Drive.c里被调用 // void LTDC_IRQHandler(void) { LTDC_ISR_Handler(); }