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

📄 bulk_only.c

📁 这个是一个完整的MP3项目
💻 C
字号:
/*
* Copyright (c) 2004,北京博创兴业科技有限公司
* All rights reserved.
* 
* 文件名称:bulk_only.c
* 文件标识:bulk_only
* 摘    要:批量传输函数定义
* 
* 当前版本:2.0
* 作    者:Kent
* 完成日期:2004年5月20日
*
* 取代版本:1.1 
* 原作者  :Frank
* 完成日期:2003年8月10日
*/

//this file to process the request about bulk_only
#include <string.h>

#include "bulk_only.h"
#include "fat16.h"
#include "usbdisk.h"
#include "uart.h"
#include "flash.h"

//extern unsigned char  EpBuf[];

long unsigned int dDataResiduce = 0;
unsigned char bulk_state = 0;		//当前传送状态
unsigned char *pCurrentBuf;		//数据传送指针
long int nBufCount = 0;		//传送数据当前位置


unsigned char MSC_dCBWSignature[] = {0x55, 0x53, 0x42, 0x43};
unsigned char MSC_dCSWSignature[] = {0x55, 0x53, 0x42, 0x53};

#define Format_Unit 				0x04
#define Inquiry 					0x12 
#define Mode_Select 				0x55 
#define Mode_Sense 				0x1A 
#define Medium_Removal			0x1E
#define Read10 					0x28 
#define Read12 					0xA8 
#define Read_Capacity 			0x25 
#define Read_Format_Capacities 	0x23 
#define Request_Sense			0x03 
#define Rezero 					0x01 
#define Seek10 					0x2B 
#define Send_Diag 				0x1D 
#define Start_Stop_Unit 			0x1B 
#define Test_Unit_Ready 			0x00 
#define Verify 					0x2F 
#define Write10 					0x2A 
#define Write12 					0xAA 
#define Write_And_Verify 			0x2E 




#define SCSI_MSPGCD_TPP		0x1c
#define SCSI_MSPGCD_RETALL		0x3f

unsigned char Bulk_Out_Buf[64];
unsigned char Page_Buf[512];


short int Transfer_Length;
long int Logical_Block_Address;
long int nCurrentPage,nBeginPage;
long int nCurrentBlock;
code unsigned char B_InquiryData[] = {
							0x00,	//Direct Access Device
							0x80,	//RMB
							0x00,	//ISO/ECMA/ANSI
							0x01,	//Response Data Format
							0x1f,	//Additional Length
							0x00,	//Reserved
							0x00,	//Reserved
							0x00,	//Reserved
							'U', 'P', '-', 'T', 'E', 'C', 'H', ' ',	//Vendor Information
							'M', 'P', '3', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', 'V', '1', '.', '0', '0',//Product Identification
							0, 0, 0, 0};	//Product Revision Level n.nn

code unsigned char CapactiyLstHd[] = {0x00, 0x00, 0x00, 0x10};
code unsigned char bBlockLength[] = {0x00, 0x02, 0x00};		//512 Byte
code unsigned char nLastLBAddr[] = {0x00, 0x01, 0xf3, 0xff};	//Last  Logical Block Address for 64MB
code unsigned char B_Read_Format_capacities[] = {0x00, 0x00, 0x00, 0x10,	//capacity list header
									0x00, 0x00, 0x04, 0x00,	0x01,		0x00, 0x02, 0x00,	//capacity descriptor
								//	Number of Blocks =1024,unformatted media,blocklength = 512Bytes
									0x00, 0x00, 0x04, 0x00,	0x00,		0x00, 0x02, 0x00	//Formattable Capacity Descriptors
									};

code unsigned char B_Read_Capacity[] = {
								0x00, 0x00, 0xff, 0xe0,	//Last  Logical Block Address for 64MB
								0x00, 0x00, 0x02, 0x00	//block length in bytes
								};

								/*
code unsigned char B_Mode_Sense_ALL[]={0x00,0x3e,//Mode Data Length
							0x00,	//Medium Type Code
							0,//write enabled
							0,0,0,0,//reserved
							//Read-Write Eroor Recovery Page
							0x01,	//Page Code of Read-Write Error Recovery Page
							0x0a,	//Page Length
							0,		//Error Recovery Parameters
							3,		//Read Retry Count
							0,0,0,0,
							3,		//Write Retry Count
							0,0,0,
							//Flexible Disk Page
							0x05,	//Page Code of Flexible Disk Page
							0x1e,	//Page Length
							0x13,0x88,	//Transfer Rate = 512kbps
							0,	//Number of Heads磁头数
							0,	//Sectors per Track每磁道扇区数
							0x02,0x00,	//Data bytes per Sector每扇区字节数
							0x00,0x00,	//Number of Cuylinders柱面数
							0,0,0,0,0,0,0,0,0,//Reserved 保留
							1,		//motor On Delay
							0xff,	//motor Off Delay=Never
							0,0,0,0,0,0,0,//Reserved 保留
							0x00,0x00,	//Medium Rotation Rate介质旋转速率=300rpm
							0,0,	//Reserved 保留
							//Removable Block Access Capabilities Page
							0x1b,	//Page Code
							0x0a,	//Page Length
							0,//0x80,	//SFLP=1
							0x01,	//TLUN=1
							0,0,0,0,0,0,0,0//Reserved 保留
							};
*/

code unsigned char B_Mode_Sense_ALL[] = {0x0b, 0x00,//Mode Data Length
							0x00, 0x08, 0x00, 0x00,
							0x7d, 0, 0, 0, 0x02, 0x00
							};
/*
code unsigned char B_Mode_Sense_TPP[]={0x00,0x0d,//Mode Data Length
							0x00,	//Medium Type Code
							0,//write enabled
							0,0,0,0,//reserved
							0x1c,0x06,0,0x05,0,0,0,0
							};
*/
code unsigned char B_Mode_Sense_TPP[] = {0xf0,0x00,//Mode Data Length
							05, 00, 00, 00, 00, 0x0b, 00, 00, 00, 00, 0x24, 00, 00, 00, 00, 00
							};
code unsigned char B_Mode_Sense_ZERO[] = {0x00, 0x06,//Mode Data Length
							0x00,	//Medium Type Code
							0,//write enabled
							0, 0, 0, 0//reserved
};
unsigned char bulk_CSW[] = {0x55, 0x53, 0x42, 0x53,	// bytes 4 dCSWSignature
					0x00, 0x00, 0x00, 0x00,	//bytes 4  dCSWTag
					0, 0, 0, 0,		//bytes 4 dDataResiduce
					0x00
					};			//bCSWStatus  00=good state.
					

typedef struct _STRUCT_CBW
{
	unsigned char dCBWSignature[4];
	unsigned char dCBWTag[4];	//dCBWTag of CBW
	long unsigned int dCBWDataTransferLength;//dCBWDataTransferLength of CBW
	unsigned char bmCBWFlags;
	unsigned char bCBWLUN;
	unsigned char bCBWCBLength;
	unsigned char CBWCB[12];//for UFI Command all have 12bit
} struct_CBW;

struct_CBW bulk_CBW;

void InterpretCBW()
{
	int i;
//	printu("InterpretCBW");

	
	bulk_CSW[4]				=	Bulk_Out_Buf[4];
	bulk_CSW[5]				=	Bulk_Out_Buf[5];
	bulk_CSW[6]				=	Bulk_Out_Buf[6];
	bulk_CSW[7]				=	Bulk_Out_Buf[7];
	
//	for(i=0;i<4;i++) bulk_CBW.dCBWDataTransferLength = (bulk_CBW.dCBWDataTransferLength<<8) +*(EpBuf+11-i);
//	bulk_CBW.bmCBWFlags			=	*(EpBuf+12);
//	bulk_CBW.bCBWLUN				=	*(EpBuf+13)&0x0f;
//	bulk_CBW.bCBWCBLength			=	*(EpBuf+14)&0x1f;

	for (i=0; i<12; i++)
	bulk_CBW.CBWCB	[i]				=	Bulk_Out_Buf[i+15];
//	printu("\n\nSCSI:");
//	for(j=0;j<12;j++) {printuf("%x ",bulk_CBW.CBWCB[j]);}

	switch (bulk_CBW.CBWCB[0])
	{
//		case 0x04						: UFI_Reserved(); break;
		case Inquiry					: UFI_Inquiry(); break;
//		case 0x55						: UFI_Reserved();break;
		case Mode_Sense					: UFI_Mode_Sense(); break;
		case Read10						: UFI_Read10(); break;
//		case 0xA8						: UFI_Reserved();break;
		case Read_Capacity				: UFI_Read_Capacity(); break;
		case Read_Format_Capacities		: UFI_Read_Format_Capacities(); break;
//		case 0x03						: UFI_Reserved();break;
//		case 0x01						: UFI_Reserved();break;
//		case 0x2B						: UFI_Reserved();break;
//		case 0x1D						: UFI_Reserved();break;
//		case 0x1B						: UFI_Reserved();break;
		case Test_Unit_Ready			: UFI_Test_Unit_Ready(); break;
		case Verify						: UFI_Verify(); break;
		case Write10					: UFI_Write10(); break;
//		case 0xAA						: UFI_Reserved(); break;
//		case 0x2E						: UFI_Reserved(); break;
		case Medium_Removal				: UFI_Medium_Removal(); break;
		default							: UFI_Reserved(); break;
	}
		
}

void UFI_Inquiry()
{
	if (bulk_CBW.CBWCB[4] == 0)
		return;
		bulk_state = BULK_DATA_END;
		WriteEpBulk(1, sizeof (B_InquiryData), B_InquiryData);

}


void UFI_Read_Format_Capacities()
{
		if (bulk_CBW.CBWCB[7] == 0 && bulk_CBW.CBWCB[8] == 0)
			return;
		bulk_state = BULK_DATA_END;
		WriteEpBulk(1, sizeof (B_Read_Format_capacities), B_Read_Format_capacities);

}


void UFI_Read_Capacity()
{

		bulk_state = BULK_DATA_END;
		WriteEpBulk(1, sizeof (B_Read_Capacity), B_Read_Capacity);

}

void UFI_Read10()
{
	int i;
//	printu("UFI_Read10__1\n");	

	for (i=0; i<4; i++) 
	{
		Logical_Block_Address = (Logical_Block_Address << 8) + bulk_CBW.CBWCB[2 + i];//要传的数据的起始簇
	}
	Transfer_Length = bulk_CBW.CBWCB[7] * 256 + bulk_CBW.CBWCB[8];						//要传的扇区数

	nCurrentPage = Logical_Block_Address % 0x20;		//由逻辑地址块取真实扇区
	nCurrentBlock = Logical_Block_Address = Logical_Block_Address / 0x20 + Root_Cluster;	//由逻辑地址块取簇


	nBufCount = 0;		//传送数据当前位置

	ReadPage(Logical_Block_Address, nCurrentPage, Page_Buf);

	Transfer_Length--;
	nCurrentPage++;		//指向下一扇区

	bulk_state = BULK_DATA_TRANS;
	pCurrentBuf = Page_Buf;

	WriteEpBulk(1, 64, pCurrentBuf);//传第一个64字节

}

void TransDataGoOn()
{
//	int i;
	if (nBufCount < 0x1c0)
	{	//如果一个扇区未传完
		nBufCount += 0x40;
		WriteEpBulk(1, 64, pCurrentBuf + nBufCount);
	}
	
	else if (Transfer_Length > 0)
	{				//如果总扇区未传完,

		if (nCurrentPage == 0x20) 
		{
			nCurrentBlock++;
			nCurrentPage = 0;
		}

		ReadPage(nCurrentBlock, nCurrentPage, Page_Buf);	//读新的一个扇区
		nCurrentPage++;									//指向下一扇区
		Transfer_Length--;


		nBufCount = 0;									//重新计另一扁区
		pCurrentBuf = Page_Buf;
		bulk_state = BULK_DATA_TRANS;
		WriteEpBulk(1, 64, pCurrentBuf);			//写第一次
	}
	
	else 
	{
		bulk_state = BULK_DATA_END;

		nBufCount =0;									//重新计另一扁区
		TransmitCSW();
	}
}

void UFI_Write10()
{
	int i;
	for (i=0; i<4; i++) 
	{
		Logical_Block_Address = (Logical_Block_Address << 8) + bulk_CBW.CBWCB[2 + i];	//要传的数据的起始簇
	}
	Transfer_Length = bulk_CBW.CBWCB[7] * 256 + bulk_CBW.CBWCB[8];						//要传的扇区数

	nBeginPage = nCurrentPage = Logical_Block_Address % 0x20;		//由逻辑地址块取真实扇区
	nCurrentBlock = Logical_Block_Address = Logical_Block_Address / 0x20 + Root_Cluster;	//由逻辑地址块取簇

	
	bulk_state = BULK_DATA_RECIEVE;
//	Erase_Cluster(3);//Erase The Buf
	if ((nCurrentBlock < 6) || nBeginPage)  Erase_Cluster(2040);//Erase The Buf
	else  Erase_Cluster(nCurrentBlock);//Erase The Block to be write
}

	
void Trans_Data2PC()
{
	int i;
//	printuf("E:%x\n",nBufCount/0x40);
	memcpy(Page_Buf + nBufCount, Bulk_Out_Buf, 64);//将Bulk_Out端点中的64bytes的数据移入528的Page_buf中共8次
	dDataResiduce -= 0x40;
	nBufCount += 0x40;



//	if((Transfer_Length==1) &&(dDataResiduce==0x40))  WriteEpBulk(1, sizeof(bulk_CSW), bulk_CSW);

	if (((nBufCount%0x200 == 0) && nBufCount >= 0x200) \
		|| (nBufCount == 0x00))
	{

		if ((nCurrentBlock<6) || nBeginPage)
		{
			WritePage(2040, nCurrentPage, Page_Buf);
		}
		else 
		{
			WritePage(nCurrentBlock, nCurrentPage, Page_Buf);//Write to Flash Directlly
		}

			
		nCurrentPage++;		//指向下一扇区
		Transfer_Length--;	//已传输扇区减1
		nBufCount = 0;		//准备下一个扇区接

⌨️ 快捷键说明

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