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

📄 ch375.c

📁 CH375按照从设备外置固件模式
💻 C
📖 第 1 页 / 共 3 页
字号:

int DataRW(BYTE usbaddr, BYTE epaddr, WORD wPayload, WORD wLen, unsigned char *pData)
{
	 BYTE pid ;
	 pid=usbaddr;
	 pid=wPayload;

	 if(epaddr & 0x80)	// get direction of transfer
	   {
	    rd_usb_data(pData);	   
	   }
	else
	  send_data( wLen,pData);
	
	return TRUE;
}


/*=============================================================
2007-12-15 使用CH375的从机模拟,模拟U盘,实现文件系统的读写操作。
2007-12-25 因为K9F1208的处理复杂,暂时以2M内存来模拟
2008- 2 - 27  通过使用打印板验证,将CH375V芯片换成CH375A芯片,增加适当延时处理。
2008-2-28 可以实现U盘功能,但是使用2M内存空间后,实际上系统是FAT12
	      准备用UCFS管理NAND,之前先生成FAT16格式数据
===============================================================*/

unsigned char USBDISK[2*1024*1024];

unsigned char SystemBuffer[520];
unsigned char  UsbBuffer[2048];
unsigned char  SystemStatus;
unsigned int   UsbReadPoint,UsbWritePoint;
unsigned char  dCBWTag[4];
unsigned int dCBWDataTransferLength;
unsigned char  CBWCBLength;
unsigned int   LBA_adder,Block,Page;
unsigned short BlockLength;
unsigned char  SendFlag,NewAddr=0;

//================外置固件设备模式===================
unsigned char mVarSetupRequest; // USB请求码
unsigned char mVarSetupLength;  // 后续数据长度
unsigned char * VarSetupDescr;  // 描述符偏移地址
unsigned char OldAddress=0,VarUsbAddress=0;	// 暂存主机分来的地址
unsigned char CH375CONFLAG;		// 配置标志

mREQUEST_PACKET		Request;
unsigned char  DevDes[]={
				      0x12			//描述符大小			
				    , 0x01			//常数DEVICE
					, 0x10			//USB规范版本信息
				    , 0x01
					, 0x00			//类别码,
					, 0x00			//子类别码	
					, 0x00			//协议码
					, 0x08			//端点0的最大信息包大小
					, 0x8f			//厂商ID
					, 0x05
					, 0x80			//产品ID	
					, 0x93
					, 0x00			//设备版本信息
					, 0x02
					, 0x00			//索引值	
					, 0x00
					, 0x00
					, 0x01			//可能配置的数目	
					};
//配置描述符
unsigned char  ConDes[]={
			   0x09, 	   //描述符大小
			   0x02, 	   //配置描述符
			   0x2e, 0x00, //此配置所返回的所有数据大小	
			   0x01,	   //此配置支持的接口数	
			   0x01, 	   //Set_Configration中的参数
			   0x00, 	   //描述此配置的字符串索引值
			   0x80,  	   //供电模式的选择
			   0x32,	   //设备从总线提取的最大电流50ma
		       0x09, 	   //描述符大小
		       0x04, 	   //接口描述符	
		       0x00, 	   //该接口编号	
		       0x00, 	   //该接口使用的端点数,不算端点0	
		       0x04, 	   //该接口使用的端点数,不算端点0
		       0x08, 	   //接口类型 Mass Storage Class	
		       0x06,	   //接口子类型 存储介质
		       0x50, 	   //协议代码 BULK-ONLY TRANSPORT
		       0x00, 	   //描述该接口的字符串索引值
			   0x07,0x05,0x82, 0x02, 0x40, 0x00, 0x00,
			   0x07,0x05,0x02, 0x02, 0x40, 0x00, 0x00,
			   0x07,0x05,0x81, 0x03, 0x08, 0x00, 0x01,
			   0x07,0x05,0x01, 0x02, 0x08, 0x00, 0x00,
			};
			
//端点0数据上传
void mCh375Ep0Up(void)
{
	unsigned char i,len;
	if(mVarSetupLength)
	{												//长度不为0传输具体长度的数据
		if(mVarSetupLength<=8)
		{
			len=mVarSetupLength;
			mVarSetupLength=0;
			
        }	//长度小于8则长输要求的长度
		else
		{
			len=8;
			mVarSetupLength-=8;
		}							                        		//长度大于8则传输8个,切总长度减8
	    CH375_WR_CMD_PORT(CMD_WR_USB_DATA3);						//发出写端点0的命令
	    
       	CH375_WR_DAT_PORT(len);										//写入长度
    	for(i=0;i!=len;i++)
    	{
    	  // Uart_Printf("%02x ",Request.buffer[i]);
    	  delay2us();
           CH375_WR_DAT_PORT(Request.buffer[i]);	              		//循环写入数据
        }
        //Uart_Printf("\n");
    }
	else
	{
		CH375_WR_CMD_PORT(CMD_WR_USB_DATA3);						//发出写端点0的命令
		CH375_WR_DAT_PORT(0);					                   //上传0长度数据,这是一个状态阶段
	}
}

//复制描述符以便上传
void mCh375DesUp(void)
{
	unsigned char k;        
	for (k=0; k!=8; k++ ) 
	{
         Request.buffer[k]=*VarSetupDescr;  								//依次复制8个描述符,
         VarSetupDescr++;
    }
}			
//===================================================

//INIT ch375
void CH375_Init( void )
{
 	 unsigned char i, k;
	 unsigned char RD_Data;
	 Uart_Printf("Ch375 init ...\n");
	 for( k=10; k!=0; k-- )
	 {
	  CH375_COMM=CMD_RESET_ALL;
	  EZUSB_Delay(100);
	  CH375_COMM=CMD_CHECK_EXIST;
	  EZUSB_Delay(1);
	  i = 0xa5;
	  CH375_DATA= i;
	  EZUSB_Delay(1);
	  i = ~i;
	  RD_Data = CH375_DATA;
	  EZUSB_Delay(1);
	  if ( RD_Data != i )
	  {
         for ( i=5; i!=0; i-- )
         CH375_COMM=CMD_RESET_ALL;
		 EZUSB_Delay(100);
      }
      else
	     {
		  Uart_Printf("init successed!\n");
         break;
		 }
      }
     if( k==0 )
      {
         Uart_Printf("init falure!\n");
      }
      //CH375_COMM=CMD_GET_IC_VER;
      EZUSB_Delay(100);
      //Uart_Printf("Ver=%d\n",CH375_DATA);
      CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
      EZUSB_Delay(2);
	  CH375_WR_DAT_PORT( 1 );  	/* 设置为使用外置固件的USB设备方式 */
	  for ( ;; ) 
	  {  											/* 等待操作成功,通常需要等待10uS-20uS */
		if ( CH375_RD_DAT_PORT( )==CMD_RET_SUCCESS ) break;
	  }
	  Uart_Printf("Set device mode done!\n");
	  SystemStatus = CBWIdle;
	  
}


unsigned char Inquiry_tab[36]=
{
	0x00,//[0]外设类型 00-直接访问设备
	0x80,//[1]可移动设备 支持热插拔
	0x00,//[2]保持UFI=0
	0x01,//[3]响应数据格式固定为01
	0x1f,//[4]附加长度31字节
	0x00,0x00,0x00,//[5]~[7]保留
	'P','e','r','l','o','n','g',0x00,//[8]~[15]厂商信息
	0xC8,0xAB,0xD7,0xD4,0xB6,0xAF,0xC3,
	0xB8,0xC3,0xE2,0xB7,0xD6,0xCE,0xF6,0xD2,0xC7,//[16]~[31]产品标识
	0x30,0x2e,0x30,0x30//[32]~[35]版本号
};
/*
使用k9f1208做测试,
1 Page = 528 Bytes
1 Block = 528 B x 32 Pages= (16K + 512) Bytes
1 Device = 528B x 32Pages x 4,096 Blocks= 528 Mbits
LBA = 32*4096=0x20000 -1 = 0x1ffff

共0x20000个扇区,文件按簇来分配,因为每簇仅一个扇区,所以认为一个扇区为最小分配单位
在FAT中,每个分配记录占2个字节,所以(0x20000*2)/512=512个扇区,也就是说每个FAT占用
512个扇区,但是由于16 位分配表最多能管理65536(即2 的16 次方)个簇,
又由于每个簇的存储空间最大只有32KB,所以在使用FAT16 管理硬盘时,每个分区的最大
存储容量只有(65536×32 KB)即2048MB,也就是我们常说的2G。

实验时使用的K9F1208为32M字节的NAND FLASH,由此规定每个簇大小为1K,也就是2个扇区
总簇数=(32*4096)/2=65536,FAT最大为65536个,占用(65536*2)/512=256个扇区,按照当
前k9f1208的设定,合计256/32=8 blocks

测试时按照2M内存来虚拟 (2*1024*1024)j/512=4096个扇区,FAT表占用(4096*2)/512=16扇区


*/

unsigned char request_tab3[]=//0x03
{
0xf0,0x00,0x05,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x20,0x00
};
//eb 3c 90 
//4d 53 44 4f 53 35 2e 30 
//00 02 
//01
//08 00---有8个保留扇区
//02 
//00 02---根目录有512个
//00 10 ---1000个扇区,共2M字节
//f8 
//0c 00 
//01 00 
//01 00 
//00 00 00 00 
//00 00 00 00 
//00 
//00 
//29 
//55 3b 5b 2c U;[,
//4e 4f 20 4e 41 4d 45 20 20 20 20 NO NAME
//46 41 54 31 32 20 20 20 33 c9 
//2008-2-28 保留扇区1个
//(2*1024*1024)/512=4096(全部内存空间所占用的扇区数)
//4096*2=8192个字节的FAT空间
//8192/512=16个扇区的FAT
//1个保留扇区+16个FAT+16个FAT备份+32扇区(512个根目录)=65
//2*1024*1024-65*512=2063872=1.96M字节
unsigned char boot_loader[]=
{
0xeb,0x3c,0x90,							//[0]JMP instruction to boot code 
'O', 'E', 'M', ' ', 'N', 'A', 'M', 'E', //[3]OEM name
0x00,0x02,  							//[11]第扇区字节数 512
0x01,									//[13]每簇扇区数   1		
0x01,0x00,  							//[14]保留扇区数   1
0x02, 									//[16]此卷中FAT的份数  2
0x00,0x02,								//[17]512个根目录,占32个扇区
0x00,0x10,								//[19]此卷的扇区总数65535,超出0x10000,后面指定
0xf8,									//[21]介质类型:硬盘类型
0x0c,0x00,  							//[22]每个分区表占4个扇区 共1024个扇区,所以分区表占4个扇区
0x01,0x00,								//[24]每道扇区数
0x01,0x00,								//[26]磁头数
0x01,0x00,0x00,0x00,					//[28]此FAT 表所在的分区前面的隐藏扇区数
0x00,0x10,0x00,0x00,					//[32]扇区总数0x1ffff  ?
0x80,									//[36]操作系统有关参数
0x00,									//[37]保留(供NT 使用)。必须为0。
0x29,									//[38]扩展引导标记(0x29)。此标记用来指示其后的三个域可用
0x38,0x12,0xd4,0x12,					//[39]卷的序列号
'P','e','r','l','o','n','g',0x20,0x20,0x20,0x20,//[43]11个字节长的卷标
0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20,//[53]FAT16此域仅仅是一个标志,
0xf1,									//[62]引导代码
0x7d
,0xfa,0x33,0xc9,0x8e,0xd1,0xbc,0xfc,0x7b
,0x16,0x07,0xbd,0x78,0x00,0xc5,0x76,0x00
,0x1e,0x56,0x16,0x55,0xbf,0x22,0x05,0x89
,0x7e,0x00,0x89,0x4e,0x02,0xb1,0x0b,0xfc
,0xf3,0xa4,0x06,0x1f,0xbd,0x00,0x7c,0xc6
,0x45,0xfe,0x0f,0x8b,0x46,0x18,0x88,0x45
,0xf9,0xfb,0x38,0x66,0x24,0x7c,0x04,0xcd
,0x13,0x72,0x3c,0x8a,0x46,0x10,0x98,0xf7
,0x66,0x16,0x03,0x46,0x1c,0x13,0x56,0x1e
,0x03,0x46,0x0e,0x13,0xd1,0x50,0x52,0x89
,0x46,0xfc,0x89,0x56,0xfe,0xb8,0x20,0x00
,0x8b,0x76,0x11,0xf7,0xe6,0x8b,0x5e,0x0b
,0x03,0xc3,0x48,0xf7,0xf3,0x01,0x46,0xfc
,0x11,0x4e,0xfe,0x5a,0x58,0xbb,0x00,0x07
,0x8b,0xfb,0xb1,0x01,0xe8,0x94,0x00,0x72
,0x47,0x38,0x2d,0x74,0x19,0xb1,0x0b,0x56
,0x8b,0x76,0x3e,0xf3,0xa6,0x5e,0x74,0x4a
,0x4e,0x74,0x0b,0x03,0xf9,0x83,0xc7,0x15
,0x3b,0xfb,0x72,0xe5,0xeb,0xd7,0x2b,0xc9
,0xb8,0xd8,0x7d,0x87,0x46,0x3e,0x3c,0xd8
,0x75,0x99,0xbe,0x80,0x7d,0xac,0x98,0x03
,0xf0,0xac,0x84,0xc0,0x74,0x17,0x3c,0xff
,0x74,0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd
,0x10,0xeb,0xee,0xbe,0x83,0x7d,0xeb,0xe5
,0xbe,0x81,0x7d,0xeb,0xe0,0x33,0xc0,0xcd
,0x16,0x5e,0x1f,0x8f,0x04,0x8f,0x44,0x02
,0xcd,0x19,0xbe,0x82,0x7d,0x8b,0x7d,0x0f
,0x83,0xff,0x02,0x72,0xc8,0x8b,0xc7,0x48
,0x48,0x8a,0x4e,0x0d,0xf7,0xe1,0x03,0x46
,0xfc,0x13,0x56,0xfe,0xbb,0x00,0x07,0x53
,0xb1,0x04,0xe8,0x16,0x00,0x5b,0x72,0xc8
,0x81,0x3f,0x4d,0x5a,0x75,0xa7,0x81,0xbf
,0x00,0x02,0x42,0x4a,0x75,0x9f,0xea,0x00
,0x02,0x70,0x00,0x50,0x52,0x51,0x91,0x92
,0x33,0xd2,0xf7,0x76,0x18,0x91,0xf7,0x76
,0x18,0x42,0x87,0xca,0xf7,0x76,0x1a,0x8a
,0xf2,0x8a,0x56,0x24,0x8a,0xe8,0xd0,0xcc
,0xd0,0xcc,0x0a,0xcc,0xb8,0x01,0x02,0xcd
,0x13,0x59,0x5a,0x58,0x72,0x09,0x40,0x75
,0x01,0x42,0x03,0x5e,0x0b,0xe2,0xcc,0xc3
,0x03,0x18,0x01,0x27,0x0d,0x0a,0x49,0x6e
,0x76,0x61,0x6c,0x69,0x64,0x20,0x73,0x79
,0x73,0x74,0x65,0x6d,0x20,0x64,0x69,0x73
,0x6b,0xff,0x0d,0x0a,0x44,0x69,0x73,0x6b
,0x20,0x49,0x2f,0x4f,0x20,0x65,0x72,0x72
,0x6f,0x72,0xff,0x0d,0x0a,0x52,0x65,0x70
,0x6c,0x61,0x63,0x65,0x20,0x74,0x68,0x65
,0x20,0x64,0x69,0x73,0x6b,0x2c,0x20,0x61
,0x6e,0x64,0x20,0x74,0x68,0x65,0x6e,0x20
,0x70,0x72,0x65,0x73,0x73,0x20,0x61,0x6e
,0x79,0x20,0x6b,0x65,0x79,0x0d,0x0a,0x00
,0x49,0x4f,0x20,0x20,0x20,0x20,0x20,0x20
,0x53,0x59,0x53,0x4d,0x53,0x44,0x4f,0x53
,0x20,0x20,0x20,0x53,0x59,0x53,0x80,0x01
,0x00,0x57,0x49,0x4e,0x42,0x4f,0x4f,0x54
,0x20,0x53,0x59,0x53,0x00,0x00,0x55,0xaa
};

//00 00 00 10  00 01 f4 00  02 00 02 00  00 01 f4 00  ................    6us        16.2.0        
//00 00 02 00 
unsigned char FormatCapacities[]=//0x23
{
	//Capacity List Header 
	0x00,0x00,0x00,0x10,//两个header
	//Maximum Capacity Descriptor
    0x00,0x00,0x10,0x00,//Number of Blocks 最大块数0x20000,格式化可用暂定
    0x02,//DescType 已经格式化
    0x00,0x02,0x00,//lock Length
    0x00,0x00,0x10,0x00,
    0x00,
    0x00,0x02,0x00
};

unsigned char Capacity_tab[8]= //0x25
{
0x00,0x00,0x0f,0xff, //逻辑上最后一个块地址  LBA
0x00,0x00,0x02,0x00  //每个LBA的字节数512

};

unsigned char ModeSense_1c[]=
{
//header
0x00,0x06,//Mode Data Length
0x94,//Medium Type Code
0x00,//WP
0x00,0x00,0x00,0x00,//Reserved
0x1c,//Page Code
0x06,//Page Length
0x00,//Reserved
0x01,//Inactivity Time Multiplier
0x00,0x00,0x00,0x00//Reserved
};

unsigned char ModeSense_3f[]=
{
//Header Media Type and Write Protect 8
//01h Read-Write Error Recovery Page 12
//05h Flexible Disk Page 32
//1Bh Removable Block Access Capacities Page 12
//1Ch Timer and Protect Page 8
//3Fh Return all pages (valid only for the MODE SENSE command) 72
//header
0x00,0x06,//Mode Data Length
0x94,//Medium Type Code
0x00,//WP
0x00,0x00,0x00,0x00,//Reserved
//Read-Write Error Recovery Page
0x01,//Page Code
0x0a,//Page Length
0x00,//Error Recovery Parameters
0x03,//Read Retry Count:
0x00,0x00,0x00,0x00,//Reserved
0x03,//Write Retry Count
0x00,0x00,0x00,//Reserved
// Flexible Disk Page
0x05,//Page Code
0x1e,//Page Length
0x00,0xfa,//Transfer Rate (MSB,lsb)
0x02,//Number of Heads
0x20,//Sectors per Track
0x02,0x00,//Data Bytes per Sector
0x00,0x01,//Number of Cylinders
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//Reserved
0x05,//Motor On Delay
0x1e,//Motor Off Delay
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//Reserved
0x01,0x2c,//Medium Rotation Rate
0x00,0x00,//Reserved
//Removable Block Access Capacities Page
0x1b,//Page Code
0x0a,//Page Length
0x00,
0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//Reserved
//Timer and Protect Page
0x1c,//Page Code
0x06,//Page Length
0x00,//Reserved
0x01,//Inactivity Time Multiplier
0x00,0x00,0x00,0x00//Reserved
};

unsigned char command1a[]=
{
 0x03,0x00,0x00,0x00
};

/*            
MBR : 1 (1)        0
FAT1: 2 (16)       0x200     
FAT2: 17(16)       0x2000
DIR:  33(1)		   0x4000
DATA: 34(4062)	   0x4200
*/

void first_block_init(void)
{
	unsigned int i,j,addr;
	unsigned char buff1[528];
    //MBR
    for (i=0;i<512;i++)
      USBDISK[i] = boot_loader[i];
    for(i=0;i<512;i++)

⌨️ 快捷键说明

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