📄 fw.c
字号:
//-----------------------------------------------------------------------------
// 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 + -