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

📄 ch375.c

📁 AVR单片机系统开发经典实例部分源程序
💻 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 + -