#include "fontupd.h" #include "ff.h" #include "w25qxx.h" #include "ili93xx.h" #include "string.h" #include "malloc.h" #include "delay.h" #include "usart.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F407开发板 //字库更新 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2014/5/15 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //字库区域占用的总扇区数大小(3个字库+unigbk表+字库信息=3238700字节,约占791个W25QXX扇区) #define FONTSECSIZE 791 //字库存放起始地址 #define FONTINFOADDR 1024*1024*12 //Explorer STM32F4是从12M地址以后开始存放字库 //前面12M被fatfs占用了. //12M以后紧跟3个字库+UNIGBK.BIN,总大小3.09M,被字库占用了,不能动! //15.10M以后,用户可以自由使用.建议用最后的100K字节比较好. //用来保存字库基本信息,地址,大小等 _font_info ftinfo; //字库存放在磁盘中的路径 u8*const GBK24_PATH="/SYSTEM/FONT/GBK24.FON"; //GBK24的存放位置 u8*const GBK16_PATH="/SYSTEM/FONT/GBK16.FON"; //GBK16的存放位置 u8*const GBK12_PATH="/SYSTEM/FONT/GBK12.FON"; //GBK12的存放位置 u8*const UNIGBK_PATH="/SYSTEM/FONT/UNIGBK.BIN"; //UNIGBK.BIN的存放位置 //显示当前字体更新进度 //x,y:坐标 //size:字体大小 //fsize:整个文件大小 //pos:当前文件指针位置 u32 fupd_prog(u16 x,u16 y,u8 size,u32 fsize,u32 pos) { float prog; u8 t=0XFF; prog=(float)pos/fsize; prog*=100; if(t!=prog) { LCD_ShowString(x+3*size/2,y,240,320,size,"%"); t=prog; if(t>100)t=100; LCD_ShowNum(x,y,t,3,size);//显示数值 } return 0; } //更新某一个 //x,y:坐标 //size:字体大小 //fxpath:路径 //fx:更新的内容 0,ungbk;1,gbk12;2,gbk16;3,gbk24; //返回值:0,成功;其他,失败. u8 updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath,u8 fx) { u32 flashaddr=0; FIL * fftemp; u8 *tempbuf; u8 res; u16 bread; u32 offx=0; u8 rval=0; fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存 if(fftemp==NULL)rval=1; tempbuf=mymalloc(SRAMIN,4096); //分配4096个字节空间 if(tempbuf==NULL)rval=1; res=f_open(fftemp,(const TCHAR*)fxpath,FA_READ); if(res)rval=2;//打开文件失败 if(rval==0) { switch(fx) { case 0: //更新UNIGBK.BIN ftinfo.ugbkaddr=FONTINFOADDR+sizeof(ftinfo); //信息头之后,紧跟UNIGBK转换码表 ftinfo.ugbksize=fftemp->fsize; //UNIGBK大小 flashaddr=ftinfo.ugbkaddr; break; case 1: ftinfo.f12addr=ftinfo.ugbkaddr+ftinfo.ugbksize; //UNIGBK之后,紧跟GBK12字库 ftinfo.gbk12size=fftemp->fsize; //GBK12字库大小 flashaddr=ftinfo.f12addr; //GBK12的起始地址 break; case 2: ftinfo.f16addr=ftinfo.f12addr+ftinfo.gbk12size; //GBK12之后,紧跟GBK16字库 ftinfo.gbk16size=fftemp->fsize; //GBK16字库大小 flashaddr=ftinfo.f16addr; //GBK16的起始地址 break; case 3: ftinfo.f24addr=ftinfo.f16addr+ftinfo.gbk16size; //GBK16之后,紧跟GBK24字库 ftinfo.gkb24size=fftemp->fsize; //GBK24字库大小 flashaddr=ftinfo.f24addr; //GBK24的起始地址 break; } while(res==FR_OK)//死循环执行 { res=f_read(fftemp,tempbuf,4096,(UINT *)&bread); //读取数据 if(res!=FR_OK)break; //执行错误 W25QXX_Write(tempbuf,offx+flashaddr,4096); //从0开始写入4096个数据 offx+=bread; fupd_prog(x,y,size,fftemp->fsize,offx); //进度显示 if(bread!=4096)break; //读完了. } f_close(fftemp); } myfree(SRAMIN,fftemp); //释放内存 myfree(SRAMIN,tempbuf); //释放内存 return res; } //更新字体文件,UNIGBK,GBK12,GBK16,GBK24一起更新 //x,y:提示信息的显示地址 //size:字体大小 //src:字库来源磁盘."0:",SD卡;"1:",FLASH盘,"2:",U盘. //提示信息字体大小 //返回值:0,更新成功; // 其他,错误代码. u8 update_font(u16 x,u16 y,u8 size,u8* src) { u8 *pname; u32 *buf; u8 res=0; u16 i,j; FIL *fftemp; u8 rval=0; res=0XFF; ftinfo.fontok=0XFF; pname=mymalloc(SRAMIN,100); //申请100字节内存 buf=mymalloc(SRAMIN,4096); //申请4K字节内存 fftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //分配内存 if(buf==NULL||pname==NULL||fftemp==NULL) { myfree(SRAMIN,fftemp); myfree(SRAMIN,pname); myfree(SRAMIN,buf); return 5; //内存申请失败 } //先查找文件是否正常 strcpy((char*)pname,(char*)src); //copy src内容到pname strcat((char*)pname,(char*)UNIGBK_PATH); res=f_open(fftemp,(const TCHAR*)pname,FA_READ); if(res)rval|=1<<4;//打开文件失败 strcpy((char*)pname,(char*)src); //copy src内容到pname strcat((char*)pname,(char*)GBK12_PATH); res=f_open(fftemp,(const TCHAR*)pname,FA_READ); if(res)rval|=1<<5;//打开文件失败 strcpy((char*)pname,(char*)src); //copy src内容到pname strcat((char*)pname,(char*)GBK16_PATH); res=f_open(fftemp,(const TCHAR*)pname,FA_READ); if(res)rval|=1<<6;//打开文件失败 strcpy((char*)pname,(char*)src); //copy src内容到pname strcat((char*)pname,(char*)GBK24_PATH); res=f_open(fftemp,(const TCHAR*)pname,FA_READ); if(res)rval|=1<<7;//打开文件失败 myfree(SRAMIN,fftemp);//释放内存 if(rval==0)//字库文件都存在. { LCD_ShowString(x,y,240,320,size,"Erasing sectors... ");//提示正在擦除扇区 for(i=0;i