📄 ch375.c
字号:
#include "DSP28_Device.h"
#define CH375_COM port57FF
#define CH375_DAT port57FE
ioport unsigned char CH375_COM;
ioport unsigned char CH375_DAT;
extern unsigned char UsbIntFlag;
extern unsigned char DBUF[BUFFER_LENGTH];
extern unsigned int DirStartCluster;
unsigned char num = 0;
unsigned char out[0x20];
SYS_INFO_BLOCK DeviceInfo;
FILE_INFO ThisFile;
FLAGS bFlags;
ShowFileName_Def ShowFileName[MaxLFNum]; //long file struct
/* 延时2微秒,请根据单片机速度 */
void mDelay1uS( )
{
unsigned char i;
for ( i = 2; i != 0; i -- );
}
/* 延时2微秒,请根据单片机速度 */
void mDelay2uS( )
{
unsigned char i;
for ( i = 4; i != 0; i -- );
}
/* 向CH375命令端口写命令数据 */
void WrCmdTo375( Uint16 cmd )
{
mDelay1uS( );
CH375_COM = cmd;
mDelay2uS( ); /* 至少延时2uS */
}
/* 向CH375数据端口写数据 */
void WrDatTo375( Uint16 dat )
{
CH375_DAT = dat;
mDelay1uS( );
}
/* 从CH375端口读数据 */
unsigned char RdDatFrom375( )
{
unsigned char Temp;
mDelay1uS( );
Temp = CH375_DAT & 0xFF;
return Temp;
}
/* 延时毫秒,不精确 */
void DelayMs(Uint16 nFactor)
{
Uint16 i;
Uint16 j;
for(i=0; i<nFactor; i++) for(j=0;j<1000;j++) j=j;
}
/* 等待CH375中断并获取状态 */
unsigned char mWaitInterrupt( )
{
unsigned char c;
ll:
if (UsbIntFlag == 1) goto ll;
// while ( UsbIntFlag!=0 ); /* 如果CH375的中断引脚输出高电平则等待 */
WrCmdTo375( CMD_GET_STATUS); /* 获取当前中断状态 */
DelayMs(2);
c = RdDatFrom375(); /* 返回中断状态 */
UsbIntFlag = 1;
return( c );
}
/* 设置CH375为USB主机方式 */
unsigned char mCH375Init( )
{
unsigned char i,t;
WrCmdTo375(CMD_RESET_ALL);
DelayMs(50);
WrCmdTo375(CMD_GET_IC_VER); /* 获取芯片及固件版本 */
i = RdDatFrom375( ); /* 版本 */
if ( i < 0xA2 ) return FALSE; /* 不支持该芯片 */
WrCmdTo375( CMD_SET_USB_MODE); /* 设置USB工作模式 */
DelayMs(2);
WrDatTo375 (6); /* 模式代码,自动检测USB设备连接 */
DelayMs(2);
for ( i = 0xff; i != 0; i -- )
{ /* 等待操作成功,通常需要等待10uS-20uS */
t = RdDatFrom375() & 0xFF ;
if ( t == CMD_RET_SUCCESS ) return TRUE; /* 操作成功 */
}
return FALSE; /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */
}
/* 初始化磁盘 */
unsigned char mInitDisk( )
{
unsigned char mIntStatus;
WrCmdTo375(CMD_DISK_INIT); /* 初始化USB存储器 */
DelayMs(100);
mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
if ( mIntStatus == USB_INT_SUCCESS )
return TRUE; /* U盘已经成功初始化 */
return FALSE; /* 出现错误 */
}
unsigned char ReadCapacity(void)
{
unsigned char *buf;
Uint16 mIntStatus,mLength;
WrCmdTo375( CMD_DISK_SIZE); /* 读取容量 */
buf=DBUF;
DelayMs(100);
mIntStatus = mWaitInterrupt( );
if ( mIntStatus == USB_INT_SUCCESS )
{
WrCmdTo375(CMD_RD_USB_DATA); /* 从CH375缓冲区读取数据块 */
mLength = RdDatFrom375(); /* 后续数据的长度 */
while ( mLength )
{ /* 根据长度读取数据 */
*buf = RdDatFrom375(); /* 读出数据并保存 */
buf ++;
mLength --;
}
return TRUE;
}
return FALSE;
}
unsigned long SwapINT32(unsigned long dData)
{
dData = (dData&0xff)<<24|(dData&0xff00)<<8|(dData&0xff000000)>>24|(dData&0xff0000)>>8;
return dData;
}
unsigned char SwapINT16(unsigned char dData)
{
dData = (dData&0xff00)>>8|(dData&0x00ff)<<8;
return dData;
}
unsigned char LSwapINT16(unsigned char dData1,unsigned char dData2)
{
unsigned char dData;
dData = ((dData2<<8)&0xff00)|(dData1&0x00ff);
return dData;
}
unsigned long LSwapINT32(unsigned long dData1,unsigned long dData2,unsigned long dData3,unsigned long dData4)
{
unsigned long dData;
dData = ((dData4<<24)&0xff000000)|((dData3<<16)&0xff0000)|((dData2<<8)&0xff00)|(dData1&0xff);
return dData;
}
/* 从U盘中读取多个扇区的数据块到缓冲区中 */
unsigned char RBC_Read(unsigned long lba, unsigned char len,unsigned char *mBufferPoint)
{
unsigned char mIntStatus;
unsigned char mBlockCount;
unsigned char mLength;
WrCmdTo375(CMD_DISK_READ); /* 从USB存储器读数据块 */
DelayMs(2);
WrDatTo375((unsigned char)(lba & 0xFF)); /* LBA的最低8位 */
WrDatTo375((unsigned char)((lba >> 8) & 0xFF ));
WrDatTo375((unsigned char)((lba >> 16) & 0xFF ));
WrDatTo375((unsigned char )((lba >> 24) & 0xFF )); /* LBA的最高8位 */
WrDatTo375( len & 0XFF); /* 扇区数 */
DelayMs(100);
for ( mBlockCount = len * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- )
{
mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
if ( mIntStatus == USB_INT_DISK_READ )
{
WrCmdTo375(CMD_RD_USB_DATA); /* 从CH375缓冲区读取数据块 */
mLength = RdDatFrom375 ( ); /* 后续数据的长度 */
if ( mLength )
{ /* 根据长度读取数据 */
do { // 对于C51,这个DO+WHILE结构效率高,速度快
*mBufferPoint = RdDatFrom375(); /* 读出数据并保存 */
mBufferPoint ++;
} while ( -- mLength );
}
WrCmdTo375( CMD_DISK_RD_GO); /* 继续执行USB存储器的读操作 */
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 )
{
mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
if ( mIntStatus == USB_INT_SUCCESS ) return 1; /* 操作成功 */
}
return 0; /* 操作失败 */
}
/* 将缓冲区中的多个扇区的数据块写入U盘 */
unsigned char RBC_Write( unsigned long lba, unsigned char len,unsigned char *pBuffer )
/* iLbaStart 是写入的线起始性扇区号, iSectorCount 是写入的扇区数 */
{
unsigned char mIntStatus;
unsigned char mBlockCount;
unsigned char mLength,Temp,i;
WrCmdTo375( CMD_DISK_WRITE); /* 向USB存储器写数据块 */
DelayMs(2);
WrDatTo375((unsigned char)(lba & 0xFF)); /* LBA的最低8位 */
WrDatTo375((unsigned char)((lba >> 8) & 0xFF ));
WrDatTo375((unsigned char)((lba >> 16) & 0xFF ));
WrDatTo375((unsigned char )((lba >> 24) & 0xFF )); /* LBA的最高8位 */
WrDatTo375( len & 0Xff); /* 扇区数 */
DelayMs(100);
for ( mBlockCount = len * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- )
{ /* 数据块计数 */
mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
num++;
if ( mIntStatus == USB_INT_DISK_WRITE )
{ /* USB存储器写数据块,请求数据写入 */
WrCmdTo375( CMD_WR_USB_DATA7); /* 向CH375缓冲区写入数据块 */
mLength = CH375_BLOCK_SIZE;
WrDatTo375(mLength); /* 后续数据的长度 */
for(i=0;i<mLength;i++)
{
Temp = *pBuffer++;
WrDatTo375(Temp); /* 将数据写入 */
}
WrCmdTo375( CMD_DISK_WR_GO); /* 继续执行USB存储器的写操作 */
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 ) {
mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
if ( mIntStatus == USB_INT_SUCCESS ) return 1; /* 操作成功 */
}
return 0; /* 操作失败 */
}
unsigned char SPC_RequestSense(void)
{
WrCmdTo375( CMD_DISK_R_SENSE);
DelayMs(50);
if ( mWaitInterrupt( ) == USB_INT_SUCCESS ) return TRUE;
return FALSE;
}
unsigned char SPC_TestUnit(void)
{
WrCmdTo375( CMD_DISK_READY);
DelayMs(50);
if ( mWaitInterrupt( ) == USB_INT_SUCCESS ) return TRUE;
return FALSE;
}
unsigned char SPC_LockMedia(void)
{
return TRUE;
}
/////////////////////////////////////////////
unsigned char EnumMassDev(void)
{
unsigned int ReservedSectorsNum;
if(!mInitDisk( ))
return FALSE; /* 初始化USB存储器 */
if(!SPC_LockMedia())
return FALSE;
if(!SPC_RequestSense())
return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!ReadCapacity())
return FALSE;
DirStartCluster = 0;
DeviceInfo.BPB_BytesPerSec=512; //暂假设为512
DelayMs(50);
////////////////////////////////////////////////////
if(!RBC_Read(0x00,1,DBUF))
return FALSE;
DBUF[0] = DBUF[0] & 0xFF;
//////////////////////////////////
if(DBUF[0]==0xeb||DBUF[0]==0xe9)
{
DeviceInfo.StartSector=0;
}
else
{
DeviceInfo.StartSector=LSwapINT32(DBUF[454],DBUF[455],DBUF[456],DBUF[457]);
}
///////////////////////////////////////////////////////
DelayMs(50);
if(!RBC_Read(DeviceInfo.StartSector,1,DBUF))
return FALSE;
DeviceInfo.BPB_BytesPerSec=LSwapINT16(DBUF[11],DBUF[12]);
DeviceInfo.BPB_SecPerClus=DBUF[13];
ReservedSectorsNum=LSwapINT16(DBUF[14],DBUF[15]);
DeviceInfo.BPB_NumFATs=DBUF[16];
if(DBUF[82]=='F'&&DBUF[83]=='A'&&DBUF[84]=='T'&&DBUF[85]=='3'&&DBUF[86]=='2')
{
return 0;
}
else
{
DeviceInfo.BPB_RootEntCnt=LSwapINT16(DBUF[17],DBUF[18]);
DeviceInfo.BPB_RootEntCnt=(DeviceInfo.BPB_RootEntCnt)*32/DeviceInfo.BPB_BytesPerSec;
DeviceInfo.BPB_TotSec16=LSwapINT16(DBUF[19],DBUF[20]);
DeviceInfo.BPB_FATSz16=LSwapINT16(DBUF[22],DBUF[23]);
DeviceInfo.FatStartSector=DeviceInfo.StartSector+ReservedSectorsNum;
DeviceInfo.RootStartSector=DeviceInfo.StartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz16+ReservedSectorsNum;
DeviceInfo.FirstDataSector=DeviceInfo.FatStartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz16+DeviceInfo.BPB_RootEntCnt;
DeviceInfo.FAT=0;
}
///////////////////////////////////////////////////////
ThisFile.bFileOpen=0;
///////////////////////////////////////////////////////
return TRUE;
}
//===========================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -