📄 scsi.lst
字号:
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE SCSI
OBJECT MODULE PLACED IN SCSI.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE SCSI.c BROWSE DEBUG OBJECTEXTEND TABS(1)
stmt level source
1 /******************************************************************
2 本程序只供学习使用,未经作者许可,不得用于其它任何用途
3
4 欢迎访问我的USB专区:http://group.ednchina.com/93/
5 欢迎访问我的blog: http://www.ednchina.com/blog/computer00
6 http://computer00.21ic.org
7
8 感谢PCB赞助商——电子园: http://bbs.cepark.com/
9
10 SCSI.c file
11
12 作者:电脑圈圈
13 建立日期: 2008.08.15
14 修改日期: 2008.08.20
15 版本:V1.1
16 版权所有,盗版必究。
17 Copyright(C) 电脑圈圈 2008-2018
18 All rights reserved
19 *******************************************************************/
20
21
22 #include "MyType.H"
23 #include "UsbCore.h"
24 #include "PDIUSBD12.h"
25 #include "SCSI.h"
26 #include "Uart.h"
27 #include "config.h"
28 #include "FAT.h"
29
30 //定义端点2最大包长度为64字节
31 #define EP2_SIZE 64
32
33 //处理端点2数据的缓冲区
34 idata uint8 Ep2Buffer[EP2_SIZE];
35
36 uint32 ByteAddr; //字节地址
37
38 //INQUIRY命令需要返回的数据
39 //请对照书中INQUIRY命令响应数据格式
40 code uint8 DiskInf[36]=
41 {
42 0x00, //磁盘设备
43 0x00, //其中最高位D7为RMB。RMB=0,表示不可移除设备。如果RMB=1,则为可移除设备。
44 0x00, //各种版本号0
45 0x01, //数据响应格式
46 0x1F, //附加数据长度,为31字节
47 0x00, //保留
48 0x00, //保留
49 0x00, //保留
50 0xB5,0xE7,0XC4,0xD4,0xC8,0xA6,0xC8,0xA6, //厂商标识,为字符串“电脑圈圈”
51
52 //产品标识,为字符串“自己做的假U盘”
53 0xD7,0xD4,0xBC,0xBA,0xD7,0xF6,0xB5,0xC4,0xBC,0xD9,0x55,0xC5,0xCC,0x00,0x00,0x00,
54 0x31,0x2E,0x30,0x31 //产品版本号,为1.01
55 };
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 2
56
57 //READ_FORMAT_CAPACITIES命令需要返回的数据
58 //请对照书中READ_FORMAT_CAPACITIES命令响应数据格式
59 code uint8 MaximumCapacity[12]=
60 {
61 0x00, 0x00, 0x00, //保留
62 0x08, //容量列表长度
63 0x01, 0x00, 0x00, 0x00, //块数(最大支持8GB)
64 0x03, //描述符代码为3,表示最大支持的格式化容量
65 0x00, 0x02, 0x00 //每块大小为512字节
66 };
67
68 //READ_CAPACITY命令需要返回的数据
69 code uint8 DiskCapacity[8]=
70 {
71 0x00,0x03,0xFF,0xFF, //能够访问的最大逻辑块地址
72 0x00,0x00,0x02,0x00 //块的长度
73 //所以该磁盘的容量为
74 //(0x3FFFF+1)*0x200 = 0x8000000 = 128*1024*1024 = 128MB.
75 };
76
77 //REQUEST SENSE命令需要返回的数据,这里固定为无效命令
78 //请参看书总数据结构的解释
79 code uint8 SenseData[18]=
80 {
81 0x70, //错误代码,固定为0x70
82 0x00, //保留
83 0x05, //Sense Key为0x05,表示无效请求(ILLEGAL REQUEST)
84 0x00, 0x00, 0x00, 0x00, //Information为0
85 0x0A, //附加数据长度为10字节
86 0x00, 0x00, 0x00, 0x00, //保留
87 0x20, //Additional Sense Code(ASC)为0x20,表示无效命令操作码(INVALID COMMAND OPERATION CODE)
88 0x00, //Additional Sense Code Qualifier(ASCQ)为0
89 0x00, 0x00, 0x00, 0x00 //保留
90 };
91
92 uint8 * pEp2SendData;
93 uint32 Ep2DataLength;
94
95 /********************************************************************
96 函数功能:从CBW中获取传输数据的字节数。
97 入口参数:无。
98 返 回:需要传输的字节数。
99 备 注:无。
100 ********************************************************************/
101 uint32 GetDataTransferLength(void)
102 {
103 1 uint32 Len;
104 1
105 1 //CBW[8]~CBW[11]为传输长度(小端结构)
106 1
107 1 Len=CBW[11];
108 1 Len=Len*256+CBW[10];
109 1 Len=Len*256+CBW[9];
110 1 Len=Len*256+CBW[8];
111 1
112 1 return Len;
113 1 }
114 ////////////////////////End of function//////////////////////////////
115
116 /********************************************************************
117 函数功能:从CBW中获取逻辑块地址LBA的字节数。
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 3
118 入口参数:无。
119 返 回:逻辑块地址LBA。
120 备 注:无。
121 ********************************************************************/
122 uint32 GetLba(void)
123 {
124 1 uint32 Lba;
125 1
126 1 //读和写命令时,CBW[17]~CBW[20]为逻辑块地址(大端结构)
127 1
128 1 Lba=CBW[17];
129 1 Lba=Lba*256+CBW[18];
130 1 Lba=Lba*256+CBW[19];
131 1 Lba=Lba*256+CBW[20];
132 1
133 1 return Lba;
134 1 }
135 ////////////////////////End of function//////////////////////////////
136
137 /********************************************************************
138 函数功能:填充CSW。
139 入口参数:Residue:剩余字节数;Status:命令执行的状态。
140 返 回:无。
141 备 注:无。
142 ********************************************************************/
143 void SetCsw(uint32 Residue, uint8 Status)
144 {
145 1 //设置CSW的签名,其实可以不用每次都设置的,
146 1 //开始初始化设置一次就行了,这里每次都设置
147 1 CSW[0]='U';
148 1 CSW[1]='S';
149 1 CSW[2]='B';
150 1 CSW[3]='S';
151 1
152 1 //复制dCBWTag到CSW的dCSWTag中去
153 1 CSW[4]=CBW[4];
154 1 CSW[5]=CBW[5];
155 1 CSW[6]=CBW[6];
156 1 CSW[7]=CBW[7];
157 1
158 1 //剩余字节数
159 1 CSW[8]=Residue&0xFF;
160 1 CSW[9]=(Residue>>8)&0xFF;
161 1 CSW[10]=(Residue>>16)&0xFF;
162 1 CSW[11]=(Residue>>24)&0xFF;
163 1
164 1 //命令执行的状态,0表示成功,1表示失败。
165 1 CSW[12]=Status;
166 1 }
167 ////////////////////////End of function//////////////////////////////
168
169 /********************************************************************
170 函数功能:获取磁盘数据函数。
171 入口参数:无。
172 返 回:无。
173 备 注:无。
174 ********************************************************************/
175 void GetDiskData(void)
176 {
177 1 //判断该返回什么数据
178 1 if(ByteAddr==0) pEp2SendData=Dbr; //返回DBR
179 1 if(ByteAddr==512) pEp2SendData=Fat; //返回FAT
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 4
180 1 if((ByteAddr>=576)&&(ByteAddr<16896)) pEp2SendData=Zeros;
181 1 if(ByteAddr==16896) pEp2SendData=Fat; //返回FAT(备份FAT)
182 1 if((ByteAddr>=16960)&&(ByteAddr<33280)) pEp2SendData=Zeros;
183 1 if(ByteAddr==33280) pEp2SendData=RootDir; //返回根目录
184 1 if((ByteAddr>=33344)&&(ByteAddr<49664)) pEp2SendData=Zeros;
185 1 if(ByteAddr==49664) pEp2SendData=TestFileData; //返回文件数据
186 1 if(ByteAddr>50175) pEp2SendData=Zeros;
187 1
188 1 ByteAddr+=EP2_SIZE; //调整字节地址,每次发送最大包长度的数据
189 1 }
190 ////////////////////////End of function//////////////////////////////
191
192 /********************************************************************
193 函数功能:将数据通过端点2发送。
194 入口参数:无。
195 返 回:无。
196 备 注:当发送数据长度为0,并且处于数据阶段时,将自动发送CSW。
197 ********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -