⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fw.c

📁 汽车记录仪元代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//	File:		fw.c
//	Contents:	Firmware frameworks task dispatcher and device request parser
//				source.
//
//	Copyright (c) 2002 Cypress Semiconductor, Inc. All rights reserved
//
// $Archive: /USB/ez811/firmware/Emb_Host/fw.c $
// $Date: 4/03/02 4:32p $
// $Revision: 1 $
//-----------------------------------------------------------------------------
//#include "ezusb.h"
//#include "ezregs.h"
#include "host_811.h"
#include "string.h"
#include "AT89X52.H"
#include "intrins.h"





//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------

void TD_Init(void);
BYTE  host_sl811(BYTE *fname,BYTE *dname,BYTE year,BYTE mon,BYTE day,BYTE hour,BYTE min,BYTE sec,BYTE writetimes);
//I2C ->U DISK
BYTE  hostwrite_i2c(BYTE *fname,BYTE *dname,BYTE type);
//U DISK ->I2C	type 1:U DISK授权 2:U DISK基本信息下载
BYTE init_file(BYTE *name,BYTE attri,BYTE year,BYTE mon,BYTE day,BYTE hour,BYTE min,BYTE sec,BYTE writetimes);
//初始化文件/目录
BYTE search_name(BYTE *name,WORD dir_star,WORD dir_end);
//查询名称(文件/目录),如果找到目录,把pfiles.star_unit赋值
WORD search_space(BYTE attr);
//查询空间(连续)
//BYTE deletfile(BYTE *name,WORD dir_star,WORD dir_end);
//删除文件
WORD write_FAT(BYTE attr);
//写FAT表
BYTE write_name(WORD DIR_star,WORD DIR_end,BYTE attr);
//写名称(文件/目录)
BYTE write_dir2(WORD dir2star);
//写二级目录头部
BYTE write_file(WORD file_star);
//写文件内容
//BYTE read_file(WORD file_star);
//读文件内容,写入I2C
BYTE Renamefile ( BYTE *name, WORD dir_star, WORD dir_end );
//重命名文件
BYTE ULIS ();
//U盘授权
BYTE UDown ();
//U盘下载基本信息

extern void	kick_watchdog();

//extern EZUSB_Delay(int i);
extern int EnumUsbDev(BYTE usbaddr);
extern int unit_ready();
extern int med_rem(BYTE flag);
extern int slave_detect(void);
extern int read_disk(WORD LB_addrH,WORD LB_addrL,WORD TR_length);
extern int write_disk8(WORD I2CLBA,WORD LB_addrH,WORD LB_addrL,WORD TR_length);
extern int write_pro();		//0: error;		1: not protect;		2: protect
extern int inquiry_disk(BYTE ALL_length);
extern xdata BYTE 			DBUF[512];
//xdata BYTE dname[8] _at_ 0x8830;//="A123   ";
//xdata BYTE fname[8] _at_ 0x883a;//="zhang  ";

#define K 1024		//没用到

#define file_length 65536

xdata pfile pfiles;		//结构,便于组成文件
//xdata DWORD file_length;	//文件长度
//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------

// Task dispatcher

BYTE FATcase;
WORD start_FATsect;		//FAT表开始的扇区
BYTE sectpunit;			//每个簇有多少个扇区
BYTE file_unsize;		//文件占几个簇
BYTE FAT_sect_Num;		//FAT表占几个扇区
BYTE Attr;				//属性	0:文件;	1:目录

extern void initialize_iic(void);
extern void i2c_chuli();
extern void i2c_write(unsigned int address,unsigned char datt);
extern unsigned char i2c_read(unsigned int address);
	

BYTE  host_sl811(BYTE *fname,BYTE *dname,BYTE year,BYTE mon,BYTE day,BYTE hour,BYTE min,BYTE sec,BYTE writetimes)      
{   
    WORD i,unit_starLBA,dir2unit,dir2sLBA,start_sect,dir1_star;  

     year=year/16*10+year%16;		//得到十进制的年月日
     mon=mon/16*10+mon%16;
     day=day/16*10+day%16;
     hour=hour/16*10+hour%16;
     min=min/16*10+min%16;
     sec=sec/16*10+sec%16;	

//     if(writetimes>=5)   return 3; // disk protect  有问题的话!!!
   
     for(i=0;i<4;i++)
       { sl811h_init();			//SL811H初始化
          if(slave_detect())    //设备例举
	        break;    
	   }
	   if(i==4) return 4; // No disk	没有U盘

	i = write_pro();
	if ( i == 0 )   return 0;
    if ( i == 2 )   return 3; // disk protect
	
	for(i=0;i<8;i++)		//文件名、目录名小写改大写(U DISK只认识大写的)
       if((fname[i]>='a')&&(fname[i]<='z'))
         fname[i]=fname[i]-0x20;
   for(i=0;i<8;i++)
       if((dname[i]>='a')&&(dname[i]<='z'))
        dname[i]=dname[i]-0x20; 
//     file_length=0x10000;		//文件长度,可改
    kick_watchdog ();
 	if(!read_disk(0,0x0,1)) return(0);   //read master boot sector	读主扇区(0号)
    
   
    start_sect=DBUF[0x1C6]+(WORD)(DBUF[0x1C7])*256; 		//得到PARTITION 1的开始扇区
    start_FATsect=start_sect+1; 		//得到FAT表的开始扇区
    if(!read_disk(0,start_sect,1)) return(0); //read partition one sector	读1号扇区
    
    FAT_sect_Num=DBUF[0x16]+(WORD)(DBUF[0x17])*256;		//得到FAT表的长度

	if ((DBUF[0x36]==0x46)&&(DBUF[0x37]==0x41)&&(DBUF[0x38]==0x54))
	{
	   	if ((DBUF[0x39]==0x31)&&(DBUF[0x3A]==0x32))
		{
			FATcase = 12;
		}
		else
		{
			if ((DBUF[0x39]==0x31)&&(DBUF[0x3A]==0x36))
			{
				FATcase = 16;
			}
			else
			{
				return (5);	
			}
		}
	}
	else
	{
		return (5);
	}
	//DBUF[54-61]==FAT STYLE; FAT12,FAT16,FAT32 

    sectpunit=DBUF[0x0D];         // sector per unit	每个簇有多少个扇区
    file_unsize=file_length/512/sectpunit;		//文件占几个簇
    dir1_star=start_FATsect+FAT_sect_Num*2;		//一级目录的开始扇区(根目录),长度为20扇区
	unit_starLBA=dir1_star+(DBUF[0x12]<<4)+(DBUF[0x11]>>4);//0x27;   
    
 
    Attr=init_file(dname,0x10,year,mon,day,hour,min,sec,writetimes);	//初始化目录
    if(!search_name(pfiles.names,dir1_star,unit_starLBA))   //判断有无同名目录,无返回0
    {    med_rem(1);		//允许建立目录或文件
         dir2unit=search_space(Attr);     //找磁盘空间,返二级目录的族号;没有就返回零
         
                                          //dir addr
	     if(dir2unit!=0)		//有空间
	     {    
		      dir2sLBA=unit_starLBA+(dir2unit+1-2)*sectpunit;		//文件内容开始扇区
			  if(!write_file(dir2sLBA)) return(0);                //写入文件内容        
             
              pfiles.star_unit=dir2unit;
              dir2sLBA=(dir2unit-2)*sectpunit+unit_starLBA;	//目录开始扇区
              if(!write_dir2(dir2sLBA)) return(0);	//写二级目录的头部
			  Attr=init_file(fname,0x20,year,mon,day,hour,min,sec,writetimes);
			  pfiles.star_unit=dir2unit+1;
			  if(!write_name(dir2sLBA,dir2sLBA+sectpunit,0))return(0); //写入文件名
			  
			  Attr=init_file(dname,0x10,year,mon,day,hour,min,sec,writetimes);
			  pfiles.star_unit=dir2unit;
			  if(!write_name(dir1_star,unit_starLBA,1)) return(0);//在根目录中写目录名(20扇区中)
			  if(write_FAT(1)!=dir2unit) return(0);		//写FAT表
			  med_rem(0);		//不允许建立目录或文件
			  return(1);
		 }
        else{   return(2);//disk full
             }
            


	}
	else         // the dir is already exist
    {      
           
          dir2sLBA=(pfiles.star_unit-2)*sectpunit+unit_starLBA; // 二级目录的地址
		  Attr=init_file(fname,0x20,year,mon,day,hour,min,sec,writetimes); // init file name
          if(search_name(pfiles.names,dir2sLBA,dir2sLBA+sectpunit)) 	//判断有无同名文件
             {if(!Renamefile(pfiles.names,dir2sLBA,dir2sLBA+sectpunit)) return 0; }

           Attr=0;  
	 	   med_rem(1);		//允许建立目录或文件
           dir2unit=search_space(0);          //dir2unit就是文件开始簇(文件内容)
           if(dir2unit!=0)
           {    
		        dir2sLBA=(dir2unit-2)*sectpunit+unit_starLBA;	//文件内容开始扇区
			    if(!write_file(dir2sLBA)) return(0);    //写入文件内容
                
                Attr=init_file(fname,0x20,year,mon,day,hour,min,sec,writetimes); // init file name
                dir2sLBA=(pfiles.star_unit-2)*sectpunit+unit_starLBA; // 二级目录的地址
                pfiles.star_unit=dir2unit; 
                if(!write_name(dir2sLBA,dir2sLBA+sectpunit,0)) return(0); //写入文件名
                if(write_FAT(0)!=dir2unit) return(0);	//写FAT表
				   
				    med_rem(0);		//不允许建立目录或文件
					return(1);
			   
             
            }
            else
             {  return 2; //full
             }
         
        
    }

	
	
}

// init file or direct 's name,date, time, if dir return 1,if file return 0 
BYTE init_file(BYTE *name,BYTE attri,BYTE year,BYTE mon,BYTE day,BYTE hour,BYTE min,BYTE sec,BYTE writetimes)         //1=dir,0=file
//完成pfiles中除star_unit外的所有信息的初始化(有固定格式)
{ WORD YY;
  BYTE i;
  YY=year+2000;
 
  for(i=0;i<8;i++)
 	      pfiles.names[i]=*(name+i);
  for(i=0;i<8;i++)
  if((pfiles.names[i]>='a')&&(pfiles.names[i]<='z'))
        pfiles.names[i]=pfiles.names[i]-0x20;
  if(writetimes>=3)
       { if(attri==0x10) pfiles.names[7]=writetimes+0x30;}
  else  
       { if((writetimes>1)&&(attri!=0x10)) pfiles.names[7]=writetimes+0x30;}
  if(attri==0x10)
  {  pfiles.type[0]=0x20;
     pfiles.type[1]=0x20;
	 pfiles.type[2]=0x20;
  }
  else
  {  pfiles.type[0]='V';
     pfiles.type[1]='R';
	 pfiles.type[2]='2'; 
  }
  pfiles.attri=attri;
  pfiles.time=hour*2048+min*32+sec+2;
  pfiles.date=(YY-1980)*512+mon*32+day;
  
  pfiles.size=file_length;
  if(attri&0x10) return(1);
  else return(0);
}  




//fine if there exist same name file or direct, if find return 1,else return 0
BYTE search_name(BYTE *name,WORD dir_star,WORD dir_end)
{WORD i,j;
    
   for(i=dir_star;i<dir_end;i++)  //DIR have 20h sector
   {  
       if(!read_disk(0,i,1)) return(0);

       for(j=0;j<512;)
       {    if(strncmp(name,&DBUF[j],11)==0)
            {  if(Attr) 	//找到同名目录,就把pfiles.star_unit赋值为该目录的开始簇
                   pfiles.star_unit=(int)(DBUF[j+27])*256+DBUF[j+26];
               return(1);
             }
        j+=32;  
		kick_watchdog();  	//踢看门狗
       }
    }
 return(0);
}

BYTE Renamefile ( BYTE *name, WORD dir_star, WORD dir_end )
{
	bit sname,name9;
	unsigned int i,j,k;
	unsigned int x,y;

	sname = 0;
	name9 = 0;
	x = 0;
	y = 0;

	for ( k = 0; k < 13; k ++ )
	{
		for ( i = dir_star; i < dir_end; i ++ )
		{
			if( !read_disk (0, i, 1 )) return(0);
			for ( j = 0; j < 512; j += 32 )
			{
				if ((strncmp(name,&DBUF[j],11)==0)&&((x!=i)||(y!=j)))
				{
					x = i;
					y = j;
					sname = 1;
					switch ( DBUF[j+8] )
					{
						case 'V':
							DBUF[j+8] = 'B';
							*(name+8) = 'B';
							DBUF[j+9] = 'A';
							*(name+9) = 'A';
							DBUF[j+10] = 'K';
							*(name+10) = 'K';
							break;
						case 'B':
							switch ( DBUF[j+10] )
							{
								case 'K':
									DBUF[j+10] = '0';
									*(name+10) = '0';
									break;
								case '9':
									return (0);
									break;
								default:
									DBUF[j+10] ++;
									*(name+10) = DBUF[j+10];
									break;
							}
							break;
						default:
							break;
					}
					if ( DBUF[j+10] == '9' )
					{
						DBUF[j+8] = 'V';
						DBUF[j+9] = 'R';
						DBUF[j+10] = '2';
						name9 = 1;
					}
					if ( !write_disk (0, i, 1 ) ) return(0);
				}
			}
			kick_watchdog();  	//踢看门狗
		}
	}
	if ( name9 ) return (0);
	if ( sname ) return (1);
	return (0);
}

/*
BYTE deletfile(BYTE *name,WORD dir_star,WORD dir_end)
{WORD i,j;
 BYTE filesunitH,filesunitL,fileunitlong;
 DWORD filelong;  
   for(i=dir_star;i<dir_end;i++)  //DIR have 20h sector
   {  
       if(!read_disk(0,i,1)) return(0);

       for(j=0;j<512;)
       {    if(strncmp(name,&DBUF[j],8)==0)
            {    DBUF[j]=0xe5; 
			     if(!write_disk(0,i,1)) return 0;
                 filesunitH=DBUF[j+27];
                 filesunitL=DBUF[j+26];
                 filelong=(DWORD)(DBUF[j+31])*16777216+(DWORD)DBUF[j+30]*65536+(DWORD)DBUF[j+29]*256+DBUF[j+28];
                 fileunitlong=filelong/512/sectpunit*2;		//得到文件占几个簇
				 if(!read_disk(0,filesunitH+start_FATsect,1)) return(0);
				 //FAT表中高位就是文件在FAT表中的哪个扇区,就读出这个扇区
                 for(i=filesunitL*2;i<filesunitL*2+fileunitlong;i++)
				 //FAT表中低位就是文件在FAT表中每个扇区的(偏移地址/2),就修改相应的值
                   DBUF[i]=0;  
				 if(!write_disk(0,filesunitH+start_FATsect,1)) return(0);	//写回U DISK中
                 return(1);
             }
        j+=32;   
		kick_watchdog();   	//踢看门狗
       }
    }
 return(0);
}
*/

// search if there is enough space to store the file,return file name or direct's start unit
WORD search_space(BYTE attr)
{ 
  WORD free;
  WORD i;
  BYTE j;
  WORD FATLBA;
  WORD fdir_unsize;

  switch ( FATcase )
  	{
		case 12:
		  fdir_unsize=file_unsize+attr*2;
		  fdir_unsize=fdir_unsize*3/2;
		  
		  for(FATLBA=0;FATLBA<FAT_sect_Num;FATLBA++)
		  {
		    if(!read_disk(0,FATLBA+start_FATsect,1))
				return(0);

			i = 0;
			while ( i < 512-fdir_unsize )
			{
				if ((FATLBA*512+i)%3==0)
				{
					free=0; 
					for ( j = 0; j < fdir_unsize; j ++ )
					{
						if ( DBUF[i+j] != 0 )
						{
							i += j;
							free = 1;
							break;
						}
					}
			       if(free==0) 
			       { 
			        FATLBA=(FATLBA*512+i)*2/3;
			        return(FATLBA);
			       }
				}
				i ++;
				kick_watchdog();  	//踢看门狗
			}

/*		    for(i=0;i<512-fdir_unsize;i++)      //file file_unit_size + direct 1
		    {
				if ((FATLBA*512+i)%3==0)
				{
					free=0; 
					for(j=0;j<fdir_unsize;j++)
			            free+=DBUF[i+j];
			       if(free==0) 
			       { 
			        FATLBA=(FATLBA*512+i)*2/3;
			        return(FATLBA);
			       }
				}
				kick_watchdog();  	//踢看门狗
		    }
*/
		  }
		  return(0);

		case 16:
		  fdir_unsize=file_unsize+attr;
		  for(FATLBA=0;FATLBA<FAT_sect_Num;FATLBA++)
		  { if(!read_disk(0,FATLBA+start_FATsect,1)) return(0);
		    for(i=0;i<256-fdir_unsize;i++)      //file file_unit_size + direct 1
		    { free=0; 
		       for(j=0;j<fdir_unsize*2;j++)
		           free+=DBUF[i*2+j];
		       if(free==0) 
		       { 
		        FATLBA=FATLBA*256+i;
		        
		        return(FATLBA);
				break;
		       }
	   		   kick_watchdog();  	//踢看门狗
		    }
   		   kick_watchdog();  	//踢看门狗
		  }
		  return(0);

		default:
		  return(0);
  	}
}


WORD write_FAT(BYTE attr)
{
  WORD sectnum;
  WORD free;
  WORD i;
  BYTE j;
  WORD FATLBA;
  WORD fdir_unsize;

  switch ( FATcase )
	{
		case 12:

		  fdir_unsize=file_unsize+attr*2;
		  fdir_unsize=fdir_unsize*3/2;
		  
		  for(FATLBA=0;FATLBA<FAT_sect_Num;FATLBA++)
		  {
		    if(!read_disk(0,FATLBA+start_FATsect,1))
				return(0);

			i = 0;
			while ( i < 512-fdir_unsize )
			{
				if ((FATLBA*512+i)%3==0)
				{
					free=0; 
					for ( j = 0; j < fdir_unsize; j ++ )
					{
						if ( DBUF[i+j] != 0 )
						{
							i += j;
							free = 1;
							break;
						}
					}
					kick_watchdog();  	//踢看门狗
			     	if(free==0) 
			        { 
						if (fdir_unsize%2)
						{
						   	  for(j=0;j<fdir_unsize-3;j+=3)           // file address in FAT table
					          {
								sectnum = (FATLBA*512+i+j)*2/3+1;
								DBUF[i+j] = sectnum % 256;
				  			    DBUF[i+j+1] = sectnum / 256 + ((sectnum+1)%16) * 16;
								DBUF[i+j+2] = (sectnum+1) / 16;
							  }
							  j=fdir_unsize-3;
					          DBUF[i+j]=0xff;
					  	      DBUF[i+j+1]=0x0f;
					  	      DBUF[i+j+2]=0x00;
					  	}
						else
						{
							for(j=0;j<fdir_unsize;j+=3)           // file address in FAT table
					          {
								sectnum = (FATLBA*512+i+j)*2/3+1;
								DBUF[i+j] = sectnum % 256;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -