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

📄 bulk_only.c

📁 基于MCU的U盘源码
💻 C
字号:
///////////////////////////////////////////////////////////////// 
//
// Copyright (c) 2004 
// All rights reserved
// 
// Author	:	frank_wang     frank_wang@263.net
// Created	:	JUN 23th 2004
// Modified	:
// Revision	:	ARM7+D12,
// Usage	:	 USB DISK ,SCSI-2
/////////////////////////////////////////////////////////////////

//this file to process the request about bulk_only
//#include "..\inc\44blib.h"
#include "bulk_only.h"
#include "def.h"
#include "fat16.h"
#include "Main.h"
#include "string.h"

extern EPPFLAGS bEPPflags;
extern unsigned char  EpBuf[];

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

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

U8 Bulk_Out_Buf[528];
U8 Bulk_In_Buf[528];

U8 Flash_One_Page[512*32+16*32];

U16 Transfer_Length;
U32 Logical_Block_Address;
U32 nCurrentPage,nBeginPage;
U32 nCurrentBlock;
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',0,	//Vendor Information
							'U','P','-','N','E','T','A','R','M','3','0','0',0,0,0,0,//Product Identification
							0,0,0,0};	//Product Revision Level n.nn

unsigned char CapactiyLstHd[]={0x00,0x00,0x00,0x10};
unsigned char bBlockLength[]={0x00,0x02,0x00};		//512 Byte
unsigned char nLastLBAddr[]={0x00,0x01,0xf3,0xff};	//Last  Logical Block Address for 64MB
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
									};

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

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
							8,	//Number of Heads磁头数
							32,	//Sectors per Track每磁道扇区数
							0x02,0x00,	//Data bytes per Sector每扇区字节数
							0x01,0xf4,	//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 保留
							0x01,0x2c,	//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 保留
							};

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

};
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;

	
	bulk_CSW[4]				=	EpBuf[4];
	bulk_CSW[5]				=	EpBuf[5];
	bulk_CSW[6]				=	EpBuf[6];
	bulk_CSW[7]				=	EpBuf[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]				=	EpBuf[i+15];

	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()
{
	unsigned char Logical_Unit_Number,Page_Code,Allocation_Length;
//	Logical_Unit_Number = bulk_CBW.CBWCB[1]&0xe0;
//	Page_Code = bulk_CBW.CBWCB[2];
//	Allocation_Length = bulk_CBW.CBWCB[4];

	if(bulk_CBW.CBWCB[4]==0)
		return;
//	Uart_Printf("\nInquiryData %d bytes have benn Send!",sizeof(InquiryData));
	if(sizeof(B_InquiryData) > 0x40) {
		dDataResiduce=bulk_CBW.dCBWDataTransferLength-0x40;
		bulk_state = BULK_REQEST_TRANS;
		pCurrentBuf = B_InquiryData;
		D12_WriteEndpoint(5, 64, B_InquiryData);
		nBufCount +=0x40;
		Uart_Printf("\nData Can't Be Transmitted in one time!");
		}
	else {
		bulk_state = BULK_DATA_END;
		D12_WriteEndpoint(5, sizeof(B_InquiryData), B_InquiryData);
		dDataResiduce = 0;
		}
	
}
void UFI_Read_Format_Capacities()
{
	unsigned char i,*pchar;
	
	if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)
		return;
	if(sizeof(B_Read_Format_capacities) > 0x40) {
		dDataResiduce=bulk_CBW.dCBWDataTransferLength-0x40;
		bulk_state = BULK_REQEST_TRANS;
		pCurrentBuf = B_Read_Format_capacities;
		D12_WriteEndpoint(5, 64, B_Read_Format_capacities);
		nBufCount +=0x40;
		Uart_Printf("\nData Can't Be Transmitted in one time!");
		}
	else {
		bulk_state = BULK_DATA_END;
		D12_WriteEndpoint(5, sizeof(B_Read_Format_capacities), B_Read_Format_capacities);
		dDataResiduce = 0;
		
		}
}
void UFI_Read_Capacity()
{
	if(sizeof(B_Read_Canpacity) > 0x40) {
		dDataResiduce=bulk_CBW.dCBWDataTransferLength-0x40;
		bulk_state = BULK_REQEST_TRANS;
		pCurrentBuf = B_Read_Canpacity;
		D12_WriteEndpoint(5, 64, B_Read_Canpacity);
		nBufCount +=0x40;
		Uart_Printf("\nData Can't Be Transmitted in one time!");
		}
	else {
		bulk_state = BULK_DATA_END;
		D12_WriteEndpoint(5, sizeof(B_Read_Canpacity), B_Read_Canpacity);
		dDataResiduce = 0;
		}
	
}

void UFI_Read10()
{
	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];						//要传的扇区数

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

//	Uart_Printf("\n%4x,		%4x",Logical_Block_Address,Transfer_Length);
		

	ReadPage(Logical_Block_Address,nCurrentPage,Bulk_Out_Buf);
	Transfer_Length--;
	nCurrentPage++;		//指向下一扇区
	dDataResiduce=bulk_CBW.dCBWDataTransferLength;//要传的总字节

	dDataResiduce -= 0x40;
	bulk_state = BULK_DATA_TRANS;
	pCurrentBuf = Bulk_Out_Buf;
	D12_WriteEndpoint(5, 64, pCurrentBuf);//传第一个64字节
	nBufCount +=0x40;	//指向下一次要传输的64个字节

}

void TransDataGoOn()
{
	if(nBufCount < 0x200) {	//如果一个扇区未传完
		dDataResiduce -= 0x40;
//		bulk_state = BULK_DATA_TRANS;
		D12_WriteEndpoint(5, 64, pCurrentBuf+nBufCount);
		nBufCount +=0x40;
	}
	
//	else if(Transfer_Length>0) {				//如果总扇区未传完,
	else if(Transfer_Length>0) {				//如果总扇区未传完,

//		if(((Transfer_Length%0x20) ==0) && (Transfer_Length>=0x20)&&(nCurrentPage==0x20)) {
		if(nCurrentPage==0x20) {
			nCurrentBlock++;
			nCurrentPage = 0;
			}

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

		dDataResiduce -= 0x40;							//已传输的总字节数减64
//		bulk_state = BULK_DATA_TRANS;					//设置传输状态
		nBufCount =0;									//重新计另一扁区
		pCurrentBuf = Bulk_Out_Buf;
		D12_WriteEndpoint(5, 64, pCurrentBuf);			//写第一次
		nBufCount +=0x40;									//指向下一次要传输的64个字节
	}
	
	else {
		bulk_state = BULK_DATA_END;
		dDataResiduce = 0;
		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];						//要传的扇区数
//	Uart_Printf("\nWriteTo:%4x,%4x",Logical_Block_Address,Transfer_Length);

	nBeginPage = nCurrentPage = Logical_Block_Address%0x20;		//由逻辑地址块取真实扇区
	nCurrentBlock=Logical_Block_Address =Logical_Block_Address/0x20 +Root_Cluster;	//由逻辑地址块取簇
	dDataResiduce=bulk_CBW.dCBWDataTransferLength;//要传的总字节

//	nBufCount=0x40;
//	Uart_Printf("\nWriteTo:%4x,%4x,%4x\n",Logical_Block_Address,nCurrentPage,Transfer_Length);
	
	bulk_state = BULK_DATA_RECIEVE;


}

void Trans_Data2PC()
{
	int i;
	memcpy(Bulk_In_Buf+nBufCount,EpBuf,64);//将64bytes的数据移入528的Page中共8次
	dDataResiduce -=0x40;
	nBufCount+=0x40;
/*
	for(i=0;i<4;i++) Uart_Printf("\n%x %x %x %x - %x %x %x %x - %x %x %x %x - %x %x %x %x",\
				EpBuf[0+16*i],EpBuf[1+16*i],EpBuf[2+16*i],EpBuf[3+16*i],\
				EpBuf[4+16*i],EpBuf[5+16*i],EpBuf[6+16*i],EpBuf[7+16*i],\
				EpBuf[8+16*i],EpBuf[9+16*i],EpBuf[10+16*i],EpBuf[11+16*i],\
				EpBuf[12+16*i],EpBuf[13+16*i],EpBuf[14+16*i],EpBuf[15+16*i]);

*/
	if((Transfer_Length==1) &&(dDataResiduce==0x40))  D12_WriteEndpoint(5, sizeof(bulk_CSW), bulk_CSW);

	if(((nBufCount%0x200 ==0) && nBufCount>=0x200)\
		||(nBufCount==0x00)){
		memcpy(Flash_One_Page+nCurrentPage*528,Bulk_In_Buf,528);//将528的内容移入32K的缓存,共64次
		nCurrentPage++;		//指向下一扇区
		Transfer_Length--;	//已传输扇区减1
		nBufCount =0;		//准备下一个扇区接?
//		Uart_SendByte('B');
		}

//	if(((Transfer_Length%0x20)==0) && (Transfer_Length>=0x20)&&(nCurrentPage == 0x20)){
	if((Transfer_Length>0) && (nCurrentPage == 0x20)){
		nBufCount =0;
		Write2Flash(nCurrentBlock,nBeginPage,nCurrentPage-1,Flash_One_Page);
		nCurrentBlock ++;
		nCurrentPage = 0;
		nBeginPage = 0;
		
//		Uart_Printf("%x\n",Transfer_Length);
		}
	if(Transfer_Length==0){
		nBufCount =0;
		Write2Flash(nCurrentBlock,nBeginPage,nCurrentPage-1,Flash_One_Page);
//		Uart_Printf("%x",Transfer_Length/0x20 );
		TransmitCSW();
		
		}


	
}

void UFI_Mode_Sense()
{
	dDataResiduce=bulk_CBW.dCBWDataTransferLength;
//	Uart_Printf("\nLen:%x,PageCode:%x",dDataResiduce,bulk_CBW.CBWCB[2]);
	if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP){	//Page Code=Timer and Potect Page
		if(dDataResiduce > 0x40) {
			dDataResiduce -=0x40;
			bulk_state = BULK_REQEST_TRANS;
			pCurrentBuf = B_Mode_Sense_TPP;
			D12_WriteEndpoint(5, 64, B_Mode_Sense_TPP);
			nBufCount +=0x40;
			}
		else {
			bulk_state = BULK_DATA_END;
			D12_WriteEndpoint(5, sizeof(B_Mode_Sense_TPP), B_Mode_Sense_TPP);
			dDataResiduce = 0;
			}
	}
	else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL){
		if(dDataResiduce > 0x40) {
			dDataResiduce -=0x40;
			bulk_state = BULK_REQEST_TRANS;
			pCurrentBuf = B_Mode_Sense_ALL;
			D12_WriteEndpoint(5, 64, B_Mode_Sense_ALL);
			nBufCount +=0x40;
			}
		else {
			bulk_state = BULK_DATA_END;
			D12_WriteEndpoint(5, sizeof(B_Mode_Sense_ALL), B_Mode_Sense_ALL);
			dDataResiduce = 0;
			}
	}
	else {
			bulk_state = BULK_DATA_END;
			D12_WriteEndpoint(5, sizeof(B_Mode_Sense_ZERO), B_Mode_Sense_ZERO);
			dDataResiduce = 0;
		}
}

void UFI_Medium_Removal()
{
	//nothing to do with this request
	dDataResiduce = 0;
	TransmitCSW();
}

void UFI_Test_Unit_Ready()
{
	dDataResiduce = 0;
	TransmitCSW();	//Flash Disk are always ready!
	
}


void TransmitCSW()
{
	unsigned char i,*pchar;

//	pchar=(unsigned char*)&dDataResiduce;
//	for(i=0;i<4;i++) bulk_CSW[8+i] = pchar[i];

	D12_WriteEndpoint(5, sizeof(bulk_CSW), bulk_CSW);
//	Uart_Printf("\nCSW %d bytes have benn Send!",sizeof(bulk_CSW));
	bulk_state = BULK_CSW_END;
	}



void TransRequestGoOn()
{
	if(dDataResiduce>0x40) {
		dDataResiduce -= 0x40;
		bulk_state = BULK_REQEST_TRANS;
		D12_WriteEndpoint(5, 64, pCurrentBuf+nBufCount);
		nBufCount +=0x40;
		}
	else {
		bulk_state = BULK_DATA_END;
		D12_WriteEndpoint(5, dDataResiduce, pCurrentBuf+nBufCount);
		dDataResiduce = 0;
		nBufCount=0;	//prepare for nexe into
		}
}



void UFI_Verify()
{
	dDataResiduce = 0;
	TransmitCSW();
}


void UFI_Reserved()
{
	Uart_Printf("\nUFI Function 0x%x doesn't Defined!",bulk_CBW.CBWCB[0]);
	dDataResiduce = 0;
	TransmitCSW();
	
}


⌨️ 快捷键说明

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