打印

请问有做过U盘高手,write10(scsi_2)应该怎样写好?

[复制链接]
3348|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小小电子|  楼主 | 2007-5-3 20:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用的是128M的flash,由于单片机的数据存储器容量有限,所以我有4次读写完成1 page 的操作.下面这样写可以吗?
void Write10(void)

  unsigned long int  ByteCount;
  unsigned int Transfer_Length;
  unsigned int address;
  unsigned char rank;
  unsigned long Logical_Block_Address;
  Logical_Block_Address=cbw.CBWCB[2]*0x1000000;
  Logical_Block_Address+=cbw.CBWCB[3]*0x10000;
  Logical_Block_Address+=cbw.CBWCB[4]*0x100;
  Logical_Block_Address+=cbw.CBWCB[5];
  Transfer_Length=cbw.CBWCB[7]*256+cbw.CBWCB[8];//the number of page(block).
  while(Transfer_Length--)
  {
   for(rank=1;rank<=4;rank++)
   {
      ByteCount=512;address=0;
      while(ByteCount>MAX_BULK_DATA_SIZE)
      {
        read_endpoint_buff(1,MAX_BULK_DATA_SIZE,&buffer[address]);
     ByteCount-=MAX_BULK_DATA_SIZE;
        address+=MAX_BULK_DATA_SIZE;
     }
    read_endpoint_buff(1,ByteCount,&buffer[address]);
    Flash_page_program(rank,Logical_Block_Address,&buffer);
    }
   Flash_reflash();
   Logical_Block_Address++;
    }
  Return_CSW(0,SUCCESS);
}

相关帖子

沙发
小小电子|  楼主 | 2007-5-3 20:14 | 只看该作者

高手们帮帮忙,没什么时间了.

高手们帮帮忙,没什么时间了.

使用特权

评论回复
板凳
coke| | 2007-5-4 09:56 | 只看该作者

我用ARM做电子盘的代码.

/*----------------------------------------------------------------------------
 *               Exec_UFI_Command
 *
 *  Mass storage UFI command
 *  Input: Non
 *  Output: None 
 *  Remark: After the Houst get the get LUN comman. then requir the command
 *    1: INQUIRY    2-->READ CAPACITY  3-->Read   4-->MODE SENSE ....... N:READ
 *  Send a CSW command when complete data transimit
 *---------------------------------------------------------------------------*/
void Exec_UFI_Command()
{
    U32  cnt=0, len=0;
    U32  Addr=0, tmp=0, sum=0, old=0;    
    U8*  p_buff,*p_temp,*p_save;
    Format_list *p_format_desc;
    
    switch(pufi1->bOpCode)    
    {                        
        case TEST_UNIT_READY:             //0X00 TEST UNIT READY  测试单元准备直接回复CSW
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;            
             USB_Send_Data(13,(U8*)&csw1);    
             break;
             
        case Request_Sense:             //0X03 REQUEST SENSE 请求判断
             ReqSense[ 0] = 0x70;       // Response Code 
               ReqSense[ 1] = 0x00;
               ReqSense[ 2] = 0x02;       // Sense Key 
               ReqSense[ 3] = 0x00;
               ReqSense[ 4] = 0x00;
               ReqSense[ 5] = 0x00;
               ReqSense[ 6] = 0x00;
               ReqSense[ 7] = 0x0A;       // Additional Length 
               ReqSense[ 8] = 0x00;
               ReqSense[ 9] = 0x00;
               ReqSense[10] = 0x00;
               ReqSense[11] = 0x00;
               ReqSense[12] = 0x30;       // ASC 
               ReqSense[13] = 0x01;       // ASCQ 
               ReqSense[14] = 0x00;
               ReqSense[15] = 0x00;
               ReqSense[16] = 0x00;
               ReqSense[17] = 0x00;
                              
             USB_Send_Data(18,ReqSense);
             break;
                  
        case INQUIRY:                    //0x12 INQUIRY 查询
             USB_Send_Data(36,query_ret);                          
             csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - 0x24; 
             csw1.bCSWStatus = 0x00;
             USB_Send_Data(13,(U8*)&csw1);        
             break;
        
        case FORMAT_UNIT:             //FORMAT
             if((pufi1->bLun & 0x1F!=0x17)    || (cbw1.bCBWLUN > Disk_number))                           
                     csw1.bCSWStatus = 0x01;
             else
                     {
                     sum  = pufi1->wLength[1];
                     sum  = sum << 8;
                     sum += pufi1->wLength[0];
                     
                     p_buff=RX_BUFF;
                     while(!(event_table & EVT_USB_BULK_RX));          //waitting for the RX flag
                        clear_event(EVT_USB_BULK_RX);                      //clear the RX flag ordor to receive the data in loop
                        USB_bulk_fast_read(TX_BULK_EP_FIFO_SIZE,p_buff);
                        p_format_desc=(Format_list*)p_buff;
                        if((p_format_desc->Number_block != partition_table[cbw1.bCBWLUN]->total_sector)||(p_format_desc->Block_length != partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector))
                         ReqSense[2] = 0x01;     //sense data : SENSE
                     else
                         {
                         ReqSense[2] = 0x00;     //sense data : NO SENSE 
                         FAT_FORMAT(cbw1.bCBWLUN);  
                         }
                     }                  
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;            
             USB_Send_Data(13,(U8*)&csw1);
             break;
            
        case MODE_SELECT6:             //MODE SELECT
             ReqSense[2] = 0x00;     //sense data : NO SENSE 
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;        
             USB_Send_Data(13,(U8*)&csw1);    
             break;
            
        case MODE_SENSE6:              //0x1A
                USB_Send_Data(4,MODE00_RET);                            
             csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - DevModePage.MediumType[1] - 2; 
             csw1.bCSWStatus = 0x00;    
             USB_Send_Data(13,(U8*)&csw1); 
             break;    
        
        case MODE_SENSE10:             //0x5A MODE SENSE(10)     模式判别              
               SendBuf[ 0] = 0x00;
               SendBuf[ 1] = 0x06;    //Mode data length in byte(not include itself)
               SendBuf[ 2] = 0x00;    //Medium type code
               SendBuf[ 3] = 0x00;
               SendBuf[ 4] = 0x00;
               SendBuf[ 5] = 0x00;
               SendBuf[ 6] = 0x00;
               SendBuf[ 7] = 0x00;  
                          
             USB_Send_Data(8,SendBuf);          
             csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - DevModePage.MediumType[1] - 2; 
             csw1.bCSWStatus = 0x00;        
             USB_Send_Data(13,(U8*)&csw1); 
             break;
        
        case Read_Format_Capacity:     //0x23 READ FORMAT CAPACITIES 读格式化容量
             SendBuf[0] = 0x00;        //reserved
             SendBuf[1] = 0x00;        //reserved
             SendBuf[2] = 0x00;        //reserved
             SendBuf[3] = 0x08;        //Capacity List Length 
             // Block Count 
             SendBuf[4] = ((partition_table[cbw1.bCBWLUN]->total_sector ) >> 24) & 0xFF;            //BIT[4..7] number of sector 
             SendBuf[5] = ((partition_table[cbw1.bCBWLUN]->total_sector ) >> 16) & 0xFF;
             SendBuf[6] = ((partition_table[cbw1.bCBWLUN]->total_sector ) >>  8) & 0xFF;
             SendBuf[7] = ((partition_table[cbw1.bCBWLUN]->total_sector ) >>  0) & 0xFF;
             
             SendBuf[8] = 0x02;     //Descriptor Code: Formatted Media 
              // Block Length 
             SendBuf[9]  = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >> 16) & 0xFF;;     //bytes per sector 
             SendBuf[10] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >>  8) & 0xFF;;
             SendBuf[11] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >>  0) & 0xFF;;             
             USB_Send_Data(12,(U8*)SendBuf);
             
             csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - 12; 
             csw1.bCSWStatus = 0x00;
            
             USB_Send_Data(13,(U8*)&csw1);
             break;        
        
        case READ_CAPACITY:         //0x25 读容量 SendBuf[0-3]:returned logic block address  SendBuf[4-7]: Block length in byte             
             SendBuf[0] = ((partition_table[cbw1.bCBWLUN]->total_sector - 1) >> 24) & 0xFF;
             SendBuf[1] = ((partition_table[cbw1.bCBWLUN]->total_sector - 1) >> 16) & 0xFF;
             SendBuf[2] = ((partition_table[cbw1.bCBWLUN]->total_sector - 1) >>  8) & 0xFF;
             SendBuf[3] = ((partition_table[cbw1.bCBWLUN]->total_sector - 1) >>  0) & 0xFF;     //max block number is 0xfff.暂时使用K9K1G nand flash=128M bytes = 128*1024/32(每蔟=64扇*1page)=0x1000
             
             SendBuf[4] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >> 24) & 0xFF;
             SendBuf[5] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >> 16) & 0xFF;
             SendBuf[6] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >>  8) & 0xFF;
             SendBuf[7] = (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector >>  0) & 0xFF;         //Block length 每block = 512bytes

             USB_Send_Data(8,(U8*)SendBuf);
             
             csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - 0x08;    
             csw1.bCSWStatus = 0x00;    
             USB_Send_Data(13,(U8*)&csw1);
             break;        
            
        case PREVENT_ALLOW:         //PREVENT-ALLOW MEDIUM REMOVAL 直接回复CSW.
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;                 
             USB_Send_Data(13,(U8*)&csw1);            
             break;
            
        case READ10:         //0x28 READ(10)                          //把相应地址的数据一直发送完,最后送一个CSW             
             if(MSC_RWSetup())
             {                        
                 old  =  Length * (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector);            //length of data to receive (in byte)
                 p_buff=A_malloc(old);
                 p_save=p_buff;
                 p_temp=p_buff; 
                 sum=Offset + partition_table[cbw1.bCBWLUN]->offset_sector;                
                 fnIDE_BufferSector((WORD*)p_save,sum,Length);
                 for(len=0;len < Length<<3; len++)
                     {                                 
                       USB_Send_Data(64,p_temp);                        //写数据到端点2    
                       p_temp += 64;                        
                       } 
                   A_free(p_buff);
                ReqSense[2] = 0x00;                                 //sense data : NO SENSE 
                csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - old; 
                csw1.bCSWStatus = 0x00;            
                USB_Send_Data(13,(U8*)&csw1);                        //send CSW command and complite this SCSI
            }
            else
            {
                 csw1.dCSWDataResidue = 0; 
                 csw1.bCSWStatus = 0x01;            
                 USB_Send_Data(13,(U8*)&csw1);    
            }    
            break;
            
        case WRITE10: //0x2A  WRITE(10) 
             if(MSC_RWSetup())
                 { 
                 old  =  Length * (partition_table[cbw1.bCBWLUN]->fs->bpb.byte_per_sector);            //length of data to receive (in byte)
                 p_buff=A_malloc(old);
                 p_save=p_buff;
                 p_temp=p_buff;
                 sum=Offset + partition_table[cbw1.bCBWLUN]->offset_sector;    
                    for(len=0;len < Length<<3; len++)
                           {                           
                            while(!(event_table & EVT_USB_BULK_RX));  //waitting for the RX flag
                            clear_event(EVT_USB_BULK_RX);              //clear the RX flag ordor to receive the data in loop
                            USB_bulk_fast_read(64,p_save);
                           p_save += 64;       
                           } 
                   fnIDE_WriteBufferSector((WORD*)p_temp,sum,Length);
                   A_free(p_buff);
                                  
                 ReqSense[2] = 0x00; //sense data : NO SENSE
                 csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - sum;
                 csw1.bCSWStatus = 0x00;            
                 USB_Send_Data(13,(U8*)&csw1);                 
             }
             else
             {
                 csw1.dCSWDataResidue = 0; 
                 csw1.bCSWStatus = 0x01;            
                 USB_Send_Data(13,(U8*)&csw1);    
             }
             break;            
        
        case Verify: //0x2F 验证
             if(MSC_RWSetup())
                 {            
                 ReqSense[2] = 0x00;                                 //sense data : NO SENSE 
                 csw1.dCSWDataResidue = 0; 
                 csw1.bCSWStatus = 0x00;            
                 USB_Send_Data(13,(U8*)&csw1);    
                 }
             else
                 {
                 csw1.dCSWDataResidue = 0; 
                 csw1.bCSWStatus = 0x01;            
                 USB_Send_Data(13,(U8*)&csw1);
                 }
             break;
        
        case REZERO_UNIT:         //REZERO UNIT
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;
            
             USB_Send_Data(13,(U8*)&csw1);    
             break;
            
        case SEEK10:             //SEEK
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;
            
             USB_Send_Data(13,(U8*)&csw1);    
             break;
            
        case SEND_DIAGNOSTIC:     //SEND DIAGNOSTIC
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;
            
             USB_Send_Data(13,(U8*)&csw1);            
             break;
            
        case Star_Stop:         //START-STOP UNIT
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x00;
            
             USB_Send_Data(13,(U8*)&csw1);
             break;
                                         
        default://Error
             csw1.dCSWDataResidue = 0; 
             csw1.bCSWStatus = 0x01;            
             USB_Send_Data(13,(U8*)&csw1);    
             break;        
    }
}

使用特权

评论回复
地板
262063258| | 2007-5-4 19:24 | 只看该作者

请问一下coke:

你用的方法是查询的还是中断的?
read10,write10,中未传数据通过返回CSW给host后,要求HOST再传送吗?
那处理函数是另外在写,还是也用read10/write10呢?
nand flash 在写操作之前不是要察除吗?
我就是在write10这些操作上有点问题,能否给点意见!
谢谢!!

使用特权

评论回复
5
coke| | 2007-5-5 08:52 | 只看该作者

RE

你用的方法是查询的还是中断的? 
==============================
read10. write10命令是主机用USB发命令给slave的. 在USB接收中断中设标志位.在主程序中查询该标志.

read10,write10,中未传数据通过返回CSW给host后,要求HOST再传送吗?
===================================================
不需要

那处理函数是另外在写,还是也用read10/write10呢?
==================================
不明白你的意思. read10就是host要读你slave的存储盘的资料信息和数据. write10就是要将数据和信息写到你的存储器中. 读写地址.大小都在host发给slave的信息中.你根据你的BPB/MBR转换就可以操作你的nand flash了.

nand flash 在写操作之前不是要察除吗?
================================
是. 以扇为单位察除

使用特权

评论回复
6
262063258| | 2007-5-5 10:53 | 只看该作者

谢谢你(coke)的回答.我还有些问题请教.

请问:
1.程序中
  csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - old;
  和
  csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - sum;
  得出的结果csw1.dCSWDataResidue都为0吗?
  如果不为0,host会怎样处理呢?
2.在逻辑地址转物理地址上有点弄不清楚:
  sum就是存储起的实际地址吗?offset是文件系统占用的扇区吗?
  你说的根据BPB/MBR转换的,可以说清楚点吗?打个比方.
谢谢!!!
  

使用特权

评论回复
7
262063258| | 2007-5-6 11:17 | 只看该作者

帮帮

请问:
1.程序中
  csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - old;
  和
  csw1.dCSWDataResidue = cbw1.dCBWDataTransferLength - sum;
  得出的结果csw1.dCSWDataResidue都为0吗?
  如果不为0,host会怎样处理呢?
2.在逻辑地址转物理地址上有点弄不清楚:
  sum就是存储起的实际地址吗?offset是文件系统占用的扇区吗?
  你说的根据BPB/MBR转换的,可以说清楚点吗?打个比方.
谢谢!!!
 

使用特权

评论回复
8
zhiwei| | 2012-7-21 20:58 | 只看该作者
最近做U盘控制器遇到一个问题,bulk-out写U盘的时候数据过快,控制器没有写完毕,缓冲区也没有了,该发哪种sensekey给主机以阻塞主机一下呢?

使用特权

评论回复
9
okbohetang| | 2014-6-29 16:47 | 只看该作者
你好,请问bCBWLUN这个字段的用法是什么,如果有多个逻辑单元,要怎么处理?谢谢!

使用特权

评论回复
10
sandy_| | 2015-6-11 15:27 | 只看该作者
zhiwei 发表于 2012-7-21 20:58
最近做U盘控制器遇到一个问题,bulk-out写U盘的时候数据过快,控制器没有写完毕,缓冲区也没有了,该发哪种 ...

这个问题现在知道答案了么,我也遇到同样的问题不知道怎么办

使用特权

评论回复
11
john_lee| | 2015-6-14 00:42 | 只看该作者
sandy_ 发表于 2015-6-11 15:27
这个问题现在知道答案了么,我也遇到同样的问题不知道怎么办

USB 协议本身就是自带流控的,你不设置应答,那么 USB device 控制器是不会接收下一个packet的(会自动向host返回NAK),host 则会在下一个 frame 再次发送这个 packet,直到你设置了应答让 device 接收为止。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

181

帖子

1

粉丝