📄 ch375.c
字号:
#include "ch375.h"
unsigned char usb_rec_buff[64];
unsigned char usb_rec_buflen;
unsigned char diskbuff[512*2];
void m_nop(unsigned char m)
{
while(m--)
_NOP();
_NOP();
}
/* 设置CH37X的工作模式 */
unsigned char set_usb_mode( unsigned char mode )
{
unsigned char i;
unsigned char RD_Data;
usb_cmd=CMD_SET_USB_MODE;
nop();
nop();
nop();
nop();
usb_data=mode;
nop();
for( i=100; i!=0; i-- ) /* 等待设置模式操作完成,不超过30uS */
{
RD_Data=usb_data;
if( RD_Data == CMD_RET_SUCCESS )
return 1;
} /* 成功 */
return 0;
}
unsigned char ch375_init(unsigned char mode)
{
unsigned char i, k;
unsigned char RD_Data;
EIMSK|=0x10;
/* 测试CH375是否正常工作 */
for( k=100; k!=0; k-- )
{
usb_cmd=CMD_CHECK_EXIST ; /* 测试CH375是否正常工作 */
nop();
nop();
nop();
nop();
nop();
usb_data=0x0f; /* 写入测试数据 */
/* 返回数据应该是测试数据取反 */
nop();
i=usb_data;
if ( 0xf0!= i) /* CH375不正常 */
{
for ( i=5; i!=0; i-- )
usb_cmd=CMD_RESET_ALL; /* 多次重复发命令,执行硬件复位 */
delay_ms(50); /* 延时50ms */
}
else
break;
}
if( k==0 )
return 0;
//CH375_WR_CMD_PORT( CMD_SET_USB_ID ); // 设置外部自定义的USB设备VID和PID,可选操作
//CH375_WR_DAT_PORT( (unsigned char)MY_USB_VENDOR_ID ); // 写入厂商ID的低字节
//CH375_WR_DAT_PORT( (unsigned char)(MY_USB_VENDOR_ID>>8) ); // 写入厂商ID的高字节
//CH375_WR_DAT_PORT( (unsigned char)MY_USB_DEVICE_ID ); // 写入设备ID的低字节
//CH375_WR_DAT_PORT( (unsigned char)(MY_USB_DEVICE_ID>>8) ); // 写入设备ID的高字节
/* 设置USB工作模式, 必要操作 */
// set_usb_mode( 1 ); //外部固件模式
return set_usb_mode(mode); //内部固件模式
}
unsigned char get_ver(void)
{ unsigned char ver;
usb_cmd=0x01;
ver=usb_data;
return ver;
}
void _usb_send(unsigned char *pbuff,unsigned char len)
{
unsigned char i,status;
usb_cmd=CMD_WR_USB_DATA7;
nop();
nop();
nop();
usb_data=len;
nop();
for(i=0;i<len;i++)
{
usb_data=pbuff[i];
nop();
}
while(status!=USB_INT_EP2_IN)
{
usb_cmd=CMD_GET_STATUS;
nop();
nop();
nop();
status=usb_data;
nop();
nop();
nop();
}
}
void usb_send_data(unsigned char *pbuff,unsigned int len)
{
unsigned char i,status,r,n;
EIMSK&=~0x10;
r=len/64;
n=len%64;
for(i=0;i<r;i++)
_usb_send((pbuff+i*64),64);
_usb_send((pbuff+i*64),n);
usb_cmd=CMD_UNLOCK_USB;
nop();
EIMSK|=0x10;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// 主机模式
/////////////////////////////////////////////////////////////////////////////////////////////
unsigned char waitint(void)
{
while(PINE&0x10);
usb_cmd=CMD_GET_STATUS;
m_nop(10);
return usb_data;
}
unsigned char InitDisk(void)
{
unsigned char status;
usb_cmd=CMD_GET_STATUS;
m_nop(10);
status=usb_data;
if (status==USB_INT_DISCONNECT) return status;//usb断开
usb_cmd=CMD_DISK_INIT;
status=waitint();
if (status!=USB_INT_SUCCESS) return status;
usb_cmd=CMD_DISK_SIZE;
status=waitint();
if (status!=USB_INT_SUCCESS)
{
delay_ms(250);
usb_cmd=CMD_DISK_SIZE;
status=waitint();
}
if (status!=USB_INT_SUCCESS) return status;
return 1;//u盘初始化成功
}
unsigned char ReadSector(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *oDataBuffer)
{
unsigned int mBlockCount;
unsigned char c;
usb_cmd=CMD_DISK_READ; /* 从USB存储器读数据块 */
m_nop(10);
usb_data=(unsigned char)iLbaStart; /* LBA的最低8位 */
m_nop(2);
usb_data=(unsigned char)(iLbaStart >> 8);
m_nop(2);
usb_data=(unsigned char)(iLbaStart>> 16);
m_nop(2);
usb_data=(unsigned char)(iLbaStart>> 24); /* LBA的最高8位 */
m_nop(2);
usb_data=iSectorCount ; /* 扇区数 */
for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c == USB_INT_DISK_READ )
{ /* 等待中断并获取状态,请求数据读出 */
usb_cmd=CMD_RD_USB_DATA; /* 从CH375缓冲区读取数据块 */
m_nop(10);
c =usb_data; /* 后续数据的长度 */
m_nop(2);
while ( c -- )
{
*oDataBuffer++ = usb_data;
m_nop(2);
}
usb_cmd=CMD_DISK_RD_GO; /* 继续执行USB存储器的读操作 */
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c== USB_INT_SUCCESS ) return( 1 ); /* 操作成功 */
}
return( c ); /* 操作失败 */
}
unsigned char WriteSector(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *oDataBuffer)
{
unsigned int mBlockCount;
unsigned char c;
usb_cmd=CMD_DISK_WRITE; /* 从USB存储器写数据块 */
m_nop(10);
usb_data=(unsigned char)iLbaStart; /* LBA的最低8位 */
m_nop(2);
usb_data=(unsigned char)(iLbaStart >> 8);
m_nop(2);
usb_data=(unsigned char)(iLbaStart>> 16);
m_nop(2);
usb_data=(unsigned char)(iLbaStart>> 24); /* LBA的最高8位 */
m_nop(2);
usb_data =iSectorCount; /* 扇区数 */
for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c == USB_INT_DISK_WRITE )
{ /* 等待中断并获取状态,请求数据写 */
usb_cmd=CMD_WR_USB_DATA7; /* 从CH375缓冲区写数据块 */
m_nop(10);
c=64;
usb_data =c; /* 后续数据的长度 */
m_nop(2);
while ( c -- )
{
usb_data= *oDataBuffer++ ;
m_nop(2);
}
usb_cmd=CMD_DISK_WR_GO; /* 继续执行USB存储器的写操作 */
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c== USB_INT_SUCCESS ) return( 1 ); /* 操作成功 */
}
return( c ); /* 操作失败 */
}
unsigned int WordSwap(unsigned int input)
{
return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}
unsigned int LSwapINT16(unsigned short dData1,unsigned short dData2)
{
unsigned int 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;
}
unsigned char EnumMassDev(void)
{ unsigned char c;
unsigned int ReservedSectorsNum;
/*if(!SPC_Inquiry())
return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!SPC_LockMedia())
return FALSE;
if(!SPC_RequestSense())
return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!RBC_ReadCapacity())
return FALSE;*/
////////////////////////////////////////////////////
DeviceInfo.BPB_BytesPerSec=512; //暂假设为512
/*if(!SPC_RequestSense())
return FALSE;
if(!SPC_TestUnit())
return FALSE;
if(!RBC_ReadCapacity())
return FALSE;*/
////////////////////////////////////////////////////
c=ReadSector(0x0,1,diskbuff);
if(c!=1) return c;
//////////////////////////////////
if(diskbuff[0]==0xeb||diskbuff[0]==0xe9)
{
DeviceInfo.StartSector=0;
}
else
{
DeviceInfo.StartSector=LSwapINT32(diskbuff[454],diskbuff[455],diskbuff[456],diskbuff[457]);
c=ReadSector(DeviceInfo.StartSector,1,diskbuff);
if(c!=1) return c;
}
///////////////////////////////////////////////////////
DeviceInfo.BPB_BytesPerSec=LSwapINT16(diskbuff[11],diskbuff[12]);
DeviceInfo.BPB_SecPerClus=diskbuff[13];
ReservedSectorsNum=LSwapINT16(diskbuff[14],diskbuff[15]);//保留区扇区个数
DeviceInfo.BPB_NumFATs=diskbuff[16];
if(diskbuff[82]=='F'&&diskbuff[83]=='A'&&diskbuff[84]=='T'&&diskbuff[85]=='3'&&diskbuff[86]=='2')
{
DeviceInfo.BPB_TotSec32=LSwapINT32(diskbuff[32],diskbuff[33],diskbuff[34],diskbuff[35]);
DeviceInfo.BPB_FATSz32=LSwapINT32(diskbuff[36],diskbuff[37],diskbuff[38],diskbuff[39]);
DeviceInfo.RootStartCluster=LSwapINT32(diskbuff[44],diskbuff[45],diskbuff[46],diskbuff[47]);
DeviceInfo.FatStartSector=DeviceInfo.StartSector+ReservedSectorsNum;
DeviceInfo.FirstDataSector=DeviceInfo.FatStartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz32;
DeviceInfo.TotCluster=(DeviceInfo.BPB_TotSec32-DeviceInfo.FirstDataSector+1)/DeviceInfo.BPB_SecPerClus+1;
// DirStartCluster32=DeviceInfo.RootStartCluster;
DeviceInfo.FAT=1; //FAT16=0,FAT32=1;
}
else
{
DeviceInfo.BPB_RootEntCnt=LSwapINT16(diskbuff[17],diskbuff[18]);
DeviceInfo.BPB_RootEntCnt=(DeviceInfo.BPB_RootEntCnt)*32/DeviceInfo.BPB_BytesPerSec;
DeviceInfo.BPB_TotSec16=LSwapINT16(diskbuff[19],diskbuff[20]);
DeviceInfo.BPB_FATSz16=LSwapINT16(diskbuff[22],diskbuff[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 1;
}
#pragma interrupt_handler usb_int:iv_INT4
void usb_int(void)
{
unsigned char status,len,i;
usb_cmd=CMD_GET_STATUS;
nop();
nop();
nop();
nop();
nop();
nop();
status=usb_data;
switch(status)
{case USB_INT_EP2_OUT:
usb_cmd=CMD_RD_USB_DATA;
nop();
nop();
nop();
nop();
nop();
nop();
usb_rec_buflen=usb_data;
nop();
if (usb_rec_buflen!=0)
{
for(i=0;i<usb_rec_buflen;i++)
usb_rec_buff[i]=usb_data;
nop();
}
break;
////////////////////////////////////////////////////////////////////////
///主机状态下,检测到usb设备连接
////////////////////////////////////////////////////////////////////////
case USB_INT_CONNECT:
EIMSK&=~0x10;////关usb中断
delay_ms(250);//延时等待u盘进入正常工作状态
//if (InitDisk()!=1) return;//初始化失败返回
// EnumMassDev();
return;
default :
usb_cmd= CMD_UNLOCK_USB;
nop();
nop();
nop();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -