/** ****************************************************************************** * File Name : exfuns.c * Description : This file provides code for the configuration * of the External Functions instances. ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include #include "malloc.h" #include "exfuns.h" //#include "fattester.h" #include "usart.h" #define FILE_MAX_TYPE_NUM 7 //Most FILE_MAX_TYPE_NUM categories #define FILE_MAX_SUBT_NUM 4 //Up to FILE_MAX_SUBT_NUM a small class //File types list char * const FILE_TYPE_TBL[FILE_MAX_TYPE_NUM][FILE_MAX_SUBT_NUM]= { {"BIN"}, //BIN file {"LRC"}, //LRC files {"NES"}, //NES file {"TXT","C","H"}, //Text file {"WAV","MP3","APE","FLAC"},//Supported music files {"BMP","JPG","JPEG","GIF"},//Picture files {"AVI"}, //Video file }; ///////////////////////////////Public files area, when using the malloc//////////////////////////////////////////// FATFS *fs[_VOLUMES]; //Logical disk. FIL *file; //File 1 FIL *ftemp; //File 2. UINT br,bw; //Read and write variables FILINFO fileinfo; //File information DIR dir; //Directory uint8_t *fatbuf; //SD card data buffer /////////////////////////////////////////////////////////////////////////////////////// //Exfuns for the memory //Return values: 0-success // 1 failure uint8_t exfuns_init(void) { uint8_t i; for (i = 0; i < _VOLUMES; i++) { fs[i] = (FATFS*)mymalloc(sizeof(FATFS)); //Applications for disk I workspace memory if (!fs[i]) break; } file = (FIL*)mymalloc(sizeof(FIL)); //Applications for file memory ftemp = (FIL*)mymalloc(sizeof(FIL)); //Ftemp application memory fatbuf = (uint8_t*) mymalloc(512); //Fatbuf for the memory if (i == _VOLUMES && file && ftemp && fatbuf) return 0; //Success else return 1; //Failed } //Lowercase letters to uppercase letters if numbers remained unchanged. uint8_t char_upper(uint8_t c) { if (c < 'A') return c; //Numbers remain the same. if (c >= 'a') return c - 0x20; //Uppercase. else return c; //Capital, remains unchanged } //Report file type //Fname: file name //Return value: 0XFF, said it could not identify the type of file number. // Other four member categories, low said four member categories. uint8_t f_typetell(uint8_t *fname) { uint8_t tbuf[5]; uint8_t *attr = (uint8_t*)'\0';//Extension name uint8_t i=0,j; while(i<250) { i++; if(*fname=='\0')break;//Offset at the end of the. fname++; } if(i==250)return 0XFF;//Error string. for(i=0;i<5;i++)//Get extension { fname--; if(*fname=='.') { fname++; attr=fname; break; } } strcpy((char *)tbuf,(const char*)attr);//copy for(i=0;i<4;i++)tbuf[i]=char_upper(tbuf[i]);//All uppercase for(i=0;in_fatent-2)*fs1->csize; //Total number of sectors fre_sect=fre_clust*fs1->csize; //Get number of spare sectors #if _MAX_SS!=512 //Sector size other than 512 bytes, then the conversion is 512 bytes tot_sect*=fs1->ssize/512; fre_sect*=fs1->ssize/512; #endif *total=tot_sect>>1; //Unit is KB *free=fre_sect>>1; //Unit is KB } return res; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //File replication //Note the file size should not exceed 4GB. //The pSrc file, copy to pdst. //fcpymsg,A function pointer to implement copy information display // pname:File/folder name // pct:Percentage // mode: // [0]:Update file name // [1]:Update percentage of PCT // [2]:Update folder // [3~7]:Reservation //psrc,pdst:Source and target files //totsize:Total size (when totsize 0 when says just to copy a single file) //cpdsize:The size of replicated. //fwmode:File in write mode //0:Do not overwrite existing file //1:Overwrite the original file //Return values: 0 normal, // Other, errors, 0XFF, force quit uint8_t exf_copy(uint8_t(*fcpymsg)(uint8_t*pname,uint8_t pct,uint8_t mode),uint8_t *psrc,uint8_t *pdst,uint32_t totsize,uint32_t cpdsize,uint8_t fwmode) { uint8_t res; uint16_t br=0; uint16_t bw=0; FIL *fsrc=0; FIL *fdst=0; uint8_t *fbuf=0; uint8_t curpct=0; fsrc=(FIL*)mymalloc(sizeof(FIL));//For the memory fdst=(FIL*)mymalloc(sizeof(FIL)); fbuf=(uint8_t *)mymalloc(8192); if(fsrc==NULL||fdst==NULL||fbuf==NULL)res=100;//Front left fatfs else { if(fwmode==0)fwmode=FA_CREATE_NEW;//Do not overwrite else fwmode=FA_CREATE_ALWAYS; //Overwrite the existing file res=f_open(fsrc,(const TCHAR*)psrc,FA_READ|FA_OPEN_EXISTING); //Open a read-only file if(res==0)res=f_open(fdst,(const TCHAR*)pdst,FA_WRITE|fwmode); //First open success, began to open the second if(res==0)//Both open succeeded { if(totsize==0)//Only is a single file copy { totsize=fsrc->obj.objsize; cpdsize=0; curpct=0; }else curpct=(cpdsize*100)/totsize; //Percentage of new fcpymsg(psrc,curpct,0X02); //Update percentage while(res==0)//Start copying { res=f_read(fsrc,fbuf,8192,(UINT*)&br); //The source read 512 bytes if(res||br==0)break; res=f_write(fdst,fbuf,(UINT)br,(UINT*)&bw); //Write destination file cpdsize+=bw; if(curpct!=(cpdsize*100)/totsize)//Do you need to update the percentage { curpct=(cpdsize*100)/totsize; if(fcpymsg(psrc,curpct,0X02))//Update percentage { res=0XFF;//Force quit break; } } if(res||bwfsize = _MAX_LFN * 2 + 1; pathname = mymalloc(MAX_PATHNAME_DEPTH); if(finfo->fname == NULL || pathname == NULL) res=101; if(res==0) { pathname[0]=0; strcat((char*)pathname,(const char*)fdname); //Copy path res=f_opendir(fddir,(const TCHAR*)fdname); //Open source directory if(res==0)//Open Directory successfully { while(res==0)//Start copying folders inside stuff { res=f_readdir(fddir,finfo); //Read a file directory if(res!=FR_OK||finfo->fname[0]==0)break; //Errors/to the end of the exit if(finfo->fname[0]=='.')continue; //Ignoring superior directory if(finfo->fattrib&0X10)//Is the subdirectory (file attributes, 0X20, archive; 0X10, subdirectories;) { fn=(uint8_t*)(finfo->fname);//Get file name pathlen=strlen((const char*)pathname); //Get the current path length strcat((char*)pathname,(const char*)"/"); //Add a slash strcat((char*)pathname,(const char*)fn); //Source path and directory name //printf("\r\nsub folder:%s\r\n",pathname); //Print a directory name fdsize+=exf_fdsize(pathname); //Get directory size, recursive calls pathname[pathlen]=0; //Join the terminator } else fdsize+=finfo->fsize; //Non-catalog direct plus the size of the file } } myfree(pathname); } } myfree(fddir); myfree(finfo); if(res)return 0; else return fdsize; } //Folder replication //Note the folder size not to exceed 4GB. //The pSrc folder, copy to pdst folder. //Pdst: must be shaped like "x:"/"X:XX"/"X:XX/XX" or something like that. but also the confirm folder one level up //Fcpymsg, function pointer, used to implement a copy of information display // pname:File/folder name // pct:Percentage // mode: // [0]:Update file name // [1]:Update percentage of PCT // [2]:Update folder // [3~7]:Reservation //psrc,pdst:Source and destination folders //totsize:Total size (when totsize 0 when says just to copy a single file) //cpdsize:Total size of the copied. //fwmode:File in write mode //0:Do not overwrite existing file //1:Overwrite the original file //Return values: 0-success // Other error code 0XFF, a forced exit uint8_t exf_fdcopy(uint8_t(*fcpymsg)(uint8_t*pname,uint8_t pct,uint8_t mode),uint8_t *psrc,uint8_t *pdst,uint32_t *totsize,uint32_t *cpdsize,uint8_t fwmode) { #define MAX_PATHNAME_DEPTH 512+1 //Maximum depth of target file path + file name uint8_t res=0; DIR *srcdir=0; //The source directory DIR *dstdir=0; //The destination directory FILINFO *finfo=0; //File information uint8_t *fn=0; //Long file names uint8_t * dstpathname=0; //destination folder path + file name uint8_t * srcpathname=0; //Source folder path + filename uint16_t dstpathlen=0; //Destination path length uint16_t srcpathlen=0; //Source path length srcdir=(DIR*)mymalloc(sizeof(DIR));//For the memory dstdir=(DIR*)mymalloc(sizeof(DIR)); finfo=(FILINFO*)mymalloc(sizeof(FILINFO)); if(srcdir==NULL||dstdir==NULL||finfo==NULL)res=100; if(res==0) { finfo->fsize=_MAX_LFN*2+1; dstpathname=mymalloc(MAX_PATHNAME_DEPTH); srcpathname=mymalloc(MAX_PATHNAME_DEPTH); if(finfo->fname==NULL||dstpathname==NULL||srcpathname==NULL)res=101; if(res==0) { dstpathname[0]=0; srcpathname[0]=0; strcat((char*)srcpathname,(const char*)psrc); //A copy of the original source file path strcat((char*)dstpathname,(const char*)pdst); //A copy of the original target file path res=f_opendir(srcdir,(const TCHAR*)psrc); //Open source directory if(res==0)//Open Directory successfully { strcat((char*)dstpathname,(const char*)"/");//Join slash fn=exf_get_src_dname(psrc); if(fn==0)//Label copy { dstpathlen=strlen((const char*)dstpathname); dstpathname[dstpathlen]=psrc[0]; //Record label dstpathname[dstpathlen+1]=0; //Terminator } else strcat((char*)dstpathname,(const char*)fn);//Add filename fcpymsg(fn,0,0X04);//Update the folder name res=f_mkdir((const TCHAR*)dstpathname);//If the folder already exists, is not created. create a new folder if it does not exist. if(res==FR_EXIST)res=0; while(res==0)//Start copying folders inside stuff { res=f_readdir(srcdir,finfo); //Read a file directory if(res!=FR_OK||finfo->fname[0]==0)break; //Errors/to the end of the exit if(finfo->fname[0]=='.')continue; //Ignoring superior directory fn=(uint8_t*)(finfo->fname); //Get file name dstpathlen=strlen((const char*)dstpathname); //Get the length of the path to the current target srcpathlen=strlen((const char*)srcpathname); //Get the source path length strcat((char*)srcpathname,(const char*)"/");//Source path in slash if(finfo->fattrib&0X10)//Is the subdirectory (file attributes, 0X20, archive; 0X10, subdirectories;) { strcat((char*)srcpathname,(const char*)fn); //Source path and directory name res=exf_fdcopy(fcpymsg,srcpathname,dstpathname,totsize,cpdsize,fwmode); //Copy folder } else //Non-catalog { strcat((char*)dstpathname,(const char*)"/");//Target path in slash strcat((char*)dstpathname,(const char*)fn); //Destination path and file name strcat((char*)srcpathname,(const char*)fn); //Source path and file name fcpymsg(fn,0,0X01);//Update file name res=exf_copy(fcpymsg,srcpathname,dstpathname,*totsize,*cpdsize,fwmode);//Copy the files *cpdsize+=finfo->fsize;//Add a file size } srcpathname[srcpathlen]=0;//Join the terminator dstpathname[dstpathlen]=0;//Join the terminator } } myfree(dstpathname); myfree(srcpathname); } } myfree(srcdir); myfree(dstdir); myfree(finfo); return res; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////