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