📄 bulk_only.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 + -