📄 scsi.lst
字号:
198 void Ep2SendData(void)
199 {
200 1 if(Ep2DataLength==0) //如果需要发送的数据长度为0
201 1 {
202 2 if(TransportStage==DATA_STAGE) //并且处于数据阶段
203 2 {
204 3 //则直接进入状态阶段
205 3 TransportStage=STATUS_STAGE;
206 3 Ep2DataLength=sizeof(CSW); //数据长度为CSW的大小
207 3 pEp2SendData=CSW; //返回的数据为CSW
208 3 }
209 2 else
210 2 {
211 3 return; //如果是状态阶段的数据发送完毕,则返回
212 3 }
213 2 }
214 1
215 1 #ifdef DEBUG0
if(TransportStage==STATUS_STAGE)
{
Prints("状态阶段。\r\n");
}
#endif
221 1
222 1 //如果要发送的长度比端点2最大包长要多,则分多个包发送
223 1 if(Ep2DataLength>EP2_SIZE)
224 1 {
225 2 //发送端点2最大长度字节
226 2 D12WriteEndpointBuffer(5,EP2_SIZE,pEp2SendData);
227 2 //指针移动EP2_SIZE字节
228 2 pEp2SendData+=EP2_SIZE;
229 2 Ep2DataLength-=EP2_SIZE;
230 2 //如果是READ(10)命令,并且是数据阶段,则需要获取磁盘数据
231 2 if((CBW[15]==READ_10)&&(TransportStage==DATA_STAGE))
232 2 {
233 3 GetDiskData(); //获取磁盘数据
234 3 }
235 2 }
236 1 else
237 1 {
238 2 //可以全部发送完
239 2 D12WriteEndpointBuffer(5,(uint8)Ep2DataLength,pEp2SendData);
240 2 Ep2DataLength=0; //传输长度为0
241 2 //如果是数据发送完毕,则进入仅批量传输协议的状态阶段
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 5
242 2 if(TransportStage==DATA_STAGE)
243 2 {
244 3 TransportStage=STATUS_STAGE;
245 3 Ep2DataLength=sizeof(CSW); //数据长度为CSW的大小
246 3 pEp2SendData=CSW; //返回的数据为CSW
247 3 }
248 2 else if(TransportStage==STATUS_STAGE) //如果是状态阶段完毕,则进入到命令阶段
249 2 {
250 3 TransportStage=COMMAND_STAGE; //进入到命令阶段
251 3 }
252 2 }
253 1 }
254 ////////////////////////End of function//////////////////////////////
255
256 /********************************************************************
257 函数功能:处理SCSI命令的函数。
258 入口参数:无。
259 返 回:无。
260 备 注:虽然叫SCSI命令,但是实际使用的是UFI命令。
261 ********************************************************************/
262 void ProcScsiCommand(void)
263 {
264 1 TransportStage=DATA_STAGE; //进入到数据阶段
265 1
266 1 //CBW中偏移量为15的字段为命令的类型
267 1 switch(CBW[15])
268 1 {
269 2 case INQUIRY: //INQUIRY命令
270 2 #ifdef DEBUG0
Prints("查询命令。返回数据:\r\n");
#endif
273 2 pEp2SendData=DiskInf; //返回磁盘信息
274 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
275 2 SetCsw(Ep2DataLength-sizeof(DiskInf),0); //设置剩余字节数以及状态成功
276 2 if(Ep2DataLength>sizeof(DiskInf)) //如果请求的数据比实际的要长
277 2 {
278 3 Ep2DataLength=sizeof(DiskInf); //则只返回实际的长度
279 3 }
280 2 Ep2SendData(); //返回数据
281 2 break;
282 2
283 2 case READ_FORMAT_CAPACITIES: //读格式化容量
284 2 #ifdef DEBUG0
Prints("读格式化容量命令。返回数据:\r\n");
#endif
287 2 pEp2SendData=MaximumCapacity; //返回最大格式化容量信息
288 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
289 2 SetCsw(Ep2DataLength-sizeof(MaximumCapacity),0); //设置剩余字节数以及状态成功
290 2 if(Ep2DataLength>sizeof(MaximumCapacity)) //如果请求的数据比实际的要长
291 2 {
292 3 Ep2DataLength=sizeof(MaximumCapacity); //则只返回实际的长度
293 3 }
294 2 Ep2SendData(); //返回数据
295 2 break;
296 2
297 2 case READ_CAPACITY: //读容量命令
298 2 #ifdef DEBUG0
Prints("读容量命令。返回数据:\r\n");
#endif
301 2 pEp2SendData=DiskCapacity; //返回磁盘容量
302 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
303 2 SetCsw(Ep2DataLength-sizeof(DiskCapacity),0); //设置剩余字节数以及状态成功
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 6
304 2 if(Ep2DataLength>sizeof(DiskCapacity)) //如果请求的数据比实际的要长
305 2 {
306 3 Ep2DataLength=sizeof(DiskCapacity); //则只返回实际的长度
307 3 }
308 2 Ep2SendData(); //返回数据
309 2 break;
310 2
311 2 case READ_10: //READ(10)命令
312 2 #ifdef DEBUG0
Prints("READ(10)命令。返回数据:\r\n");
#endif
315 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
316 2 ByteAddr=GetLba()*512; //获取字节地址,字节地址为逻辑块地址乘以每块大小
317 2 SetCsw(0,0); //设置剩余字节数为0,状态成功
318 2 GetDiskData(); //获取需要返回的数据
319 2 Ep2SendData(); //返回数据
320 2 break;
321 2
322 2 case WRITE_10: //WRITE(10)命令
323 2 #ifdef DEBUG0
Prints("WRITE(10)命令。输出数据:\r\n");
#endif
326 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
327 2 SetCsw(0,0); //设置剩余字节数为0,状态成功
328 2 break;
329 2
330 2 case REQUEST_SENSE: //该命令询问前一个命令执行失败的原因
331 2 #ifdef DEBUG0
Prints("REQUEST SENSE命令。返回SENSE数据(无效命令):\r\n");
#endif
334 2 pEp2SendData=SenseData; //返回探测数据
335 2 Ep2DataLength=GetDataTransferLength(); //获取需要返回的长度
336 2 SetCsw(Ep2DataLength-sizeof(SenseData),0); //设置剩余字节数以及状态成功
337 2 if(Ep2DataLength>sizeof(SenseData)) //如果请求的数据比实际的要长
338 2 {
339 3 Ep2DataLength=sizeof(SenseData); //则只返回实际的长度
340 3 }
341 2 Ep2SendData(); //返回数据
342 2 break;
343 2
344 2 case TEST_UNIT_READY: //测试磁盘是否准备好
345 2 Ep2DataLength=0; //设置长度为0,发送数据将返回CSW
346 2 SetCsw(0,0); //设置CSW为成功
347 2 Ep2SendData(); //返回CSW
348 2 break;
349 2
350 2 default: //其它命令不认,返回执行失败
351 2 if(CBW[12]&0x80) Ep2DataLength=1; //如果为输入请求,则随便返回1字节
352 2 else Ep2DataLength=0; //否则为输出请求,则设置长度为0,直接返回CSW
353 2 SetCsw(GetDataTransferLength()-Ep2DataLength,1); //设置CSW为失败
354 2 Ep2SendData(); //返回CSW
355 2 break;
356 2 }
357 1 }
358 ////////////////////////End of function//////////////////////////////
359
360 /********************************************************************
361 函数功能:处理输出数据。
362 入口参数:无。
363 返 回:无。
364 备 注:无。
365 ********************************************************************/
C51 COMPILER V7.06 SCSI 11/16/2008 16:00:19 PAGE 7
366 void ProcScsiOutData(void)
367 {
368 1 uint8 Len;
369 1 //读端点2数据
370 1 Len=D12ReadEndpointBuffer(4,EP2_SIZE,Ep2Buffer);
371 1 Ep2DataLength-=Len;
372 1 //清除端点缓冲区
373 1 D12ClearBuffer();
374 1 //由于没有存储器,这里将缓冲区清0模拟数据处理
375 1 while(Len)
376 1 {
377 2 Ep2Buffer[Len]=0; //缓冲区清0
378 2 Len--;
379 2 }
380 1
381 1 //数据传输完毕,进入到状态阶段
382 1 if(Ep2DataLength==0)
383 1 {
384 2 //此时Ep2DataLength为0,并且处于数据阶段,调用发送数据函数将返回CSW
385 2 Ep2SendData();
386 2 }
387 1 }
388 ////////////////////////End of function//////////////////////////////
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1486 ----
CONSTANT SIZE = 74 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 11 14
IDATA SIZE = 64 ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -