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

📄 scsi.lst

📁 单片机上实现U盘功能
💻 LST
📖 第 1 页 / 共 2 页
字号:
 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 + -