zoukankan      html  css  js  c++  java
  • LPC1788做U盘的时候对命令的响应

    首先是对于端点的数据处理

    #ifndef __USBEP2_H_

    #define __USBEP2_H_

     

    #include "usb.h"

    #include "usbhw.h"

    #include "msc.h"

    #include "mscuser.h"

     

    void usb_ep2_in_process(void);

     

     

    void usb_ep2_out_process(void);

     

    #endif

     

    #include "usbep2.h"

     

     

     

    //批量输入事件

    void usb_ep2_in_process(void)

    {

        switch (BulkStage)

        {

           

        case MSC_BS_DATA_IN:

          switch (CBW.CB[0])

          {

            case SCSI_READ10:

              MSC_MemoryRead();//读取数据并等待下一次传输

              break;

          }

          break;

         

        case MSC_BS_DATA_IN_LAST:

          MSC_SetCSW();//上一次传输并且传输已经完成

          break;

         

        case MSC_BS_DATA_IN_LAST_STALL:

          USB_SetStallEP(MSC_EP_IN);

          MSC_SetCSW();

          break;

         

        case MSC_BS_CSW:

          BulkStage = MSC_BS_CBW;//简单的进行状态切换

          break;

      }

       

    }

     

    //批量输出事件

    void usb_ep2_out_process(void)

    {

        BulkLen = USB_ReadEP(MSC_EP_OUT, BulkBuf);//读取缓存

        switch (BulkStage)//根据阶段判定

        {

            case MSC_BS_CBW://最开始的阶段必然是命令阶段

                MSC_GetCBW();//获取并处理cbw命令

                break;

            case MSC_BS_DATA_OUT://数据输出阶段

                switch (CBW.CB[0]) //分辨写入指令

                {

                case SCSI_WRITE10:

                    MSC_MemoryWrite();

                    break;

                case SCSI_VERIFY10:

                    MSC_MemoryVerify();

                    break;

                }

            break;

            default://不支持的状态

            USB_SetStallEP(MSC_EP_OUT);

            CSW.bStatus = CSW_PHASE_ERROR;

            MSC_SetCSW();

            break;

        }

    }

     

     

     

    然后再在子程序中对命令详细分析

     

     

    #ifndef __MSCUSER_H_

    #define __MSCUSER_H_

    #include "msc.h"

    #include "usbhw.h"

    #include "memory.h"

     

     

     

    //批量传输节点的最大包长度

    #define MSC_MAX_PACKET  64

     

    //批量传输节点地址

    #define MSC_EP_IN       0x82

    #define MSC_EP_OUT      0x02

     

    extern uint8_t  BulkStage;               //传输状态,指明下一次如何传输

    extern uint8_t  BulkLen;                 //输出接点,主机输出的数据长度

    extern uint8_t  BulkBuf[MSC_MAX_PACKET]; //数据缓存中心

     

    extern MSC_CBW CBW;                     //cbw块

    extern MSC_CSW CSW;                     //csw块

     

    extern uint32_t  MemOK;                   /* 测试mem是否完好 */

     

     

     

    #define MSC_DEBUG   0

     

    #if MSC_DEBUG

    #define msc_debug_printf(format,args...)    printf(format,##args)       //变参宏定义

    #else

    #define  msc_debug_printf(x,...)  while(0);

    #endif

     

     

     

     

    //枚举过程中的重要节点

    extern uint32_t MSC_Reset     (void);

    extern uint32_t MSC_GetMaxLUN (void);

     

    //msc设备的方法

    extern void MSC_GetCBW (void);

     

    extern void MSC_SetCSW (void);

     

    void MSC_MemoryRead (void) ;

     

    void MSC_MemoryWrite(void);

     

    void MSC_MemoryVerify(void);

     

     

    #endif

     

     

     

    #include "mscuser.h"

     

     

    uint32_t  MemOK = __TRUE;                   /* 测试mem是否完好 */

     

    uint32_t Offset;                  /* 读取写入的定位 */

    uint32_t Length;                  /* 读取写入的长度 */

     

    uint8_t  BulkStage;               /* 批量传输的阶段, 数据阶段 命令阶段 状态阶段 */

     

    uint8_t  BulkBuf[MSC_MAX_PACKET]; /* 读取批量端点传输来的数据 */

    uint8_t  BulkLen;                 /* 传输长度 */

     

    MSC_CBW CBW;                   /*CBW结构体 */

    MSC_CSW CSW;                   /*CSW结构体 */

     

     

    #if NORFLASH

    u8 usb_mac_global_buffer[MSC_MAX_PACKET];

    #endif

     

    #if NANDFLASH

    u8 usb_mac_global_buffer[MSC_MAX_PACKET];

    #endif

     

     

    //msc设备复位

    uint32_t MSC_Reset (void)

    {

        BulkStage = MSC_BS_CBW;

        return (__TRUE);

    }

     

    //获取标号

    uint32_t MSC_GetMaxLUN (void)

    {

        EP0Buf[0] = 0;    //0为一个设备

        return (__TRUE);

    }

     

     

    //设备读取数据,在in阶段发送出去

    void MSC_MemoryRead (void)

    {

        uint32_t n;

        if (Length > MSC_MAX_PACKET) //根据长度来计算,不能大于包长度

        {

            n = MSC_MAX_PACKET;

        }

        else

        {

            n = Length;

        }

     

        if ((Offset + n) > MSC_MemorySize) //缓冲区最大长度

        {

            n = MSC_MemorySize - Offset;

            BulkStage = MSC_BS_DATA_IN_LAST_STALL;//传输失败的发送

        }

       

        #if NORFLASH

        NOR_FLASH_Read_Buffer_Mal(Offset,usb_mac_global_buffer,n);//读取数据

        USB_WriteEP(MSC_EP_IN, (u8*)usb_mac_global_buffer, n);

        #endif

       

        #if NANDFLASH

        while(nandReady == 0);

        nandReady = 0;

        NAND_Read_Addr_Mal(Offset,usb_mac_global_buffer,n);

        USB_WriteEP(MSC_EP_IN, (u8*)usb_mac_global_buffer, n);

        nandReady = 1;

        #endif

       

        Offset += n;

        Length -= n;//传输完成后对指针进行相应的处理

     

        CSW.dDataResidue -= n;

     

        if (Length == 0)

        {

            BulkStage = MSC_BS_DATA_IN_LAST;//数据传输成功

        }

     

        if (BulkStage != MSC_BS_DATA_IN) //上一次传输为0 ,命令通过

        {

            CSW.bStatus = CSW_CMD_PASSED;

        }

    }

     

    u8 norflash_buffer[2048] = {0};

     

    //写入数据到设备

    void MSC_MemoryWrite (void)

    {

        if ((Offset + BulkLen) > MSC_MemorySize) //防止超界

        {

            BulkLen = MSC_MemorySize - Offset;

            BulkStage = MSC_BS_CSW;

            USB_SetStallEP(MSC_EP_OUT);

        }

       

        #if NORFLASH

        NOR_FLASH_Write_Mal(Offset,BulkBuf,BulkLen);   

        msc_idle_time_count = 0;//发生写入时,空闲时间设置为0

        #endif

       

        #if NANDFLASH

        while(nandReady == 0);

        nandReady = 0;

        NAND_Write_Addr_Mal(Offset,BulkBuf,BulkLen);

        nandReady = 1;

        msc_idle_time_count = 0;

        #endif

       

     

        Offset += BulkLen;//指针变换(写入和删除都有相应的执指针变化,自动切换位置)

        Length -= BulkLen;

     

        CSW.dDataResidue -= BulkLen;

     

        if ((Length == 0) || (BulkStage == MSC_BS_CSW))

        {

            CSW.bStatus = CSW_CMD_PASSED;

            MSC_SetCSW();//指令通过

        }

    }

     

     

    //数据校验

    void MSC_MemoryVerify (void)

    {

        uint32_t n;

     

        if ((Offset + BulkLen) > MSC_MemorySize)  //防止超界

        {

            BulkLen = MSC_MemorySize - Offset;

            BulkStage = MSC_BS_CSW;

            USB_SetStallEP(MSC_EP_OUT);

        }

       

        #if NORFLASH

        NOR_FLASH_Read_Buffer_Mal(Offset,usb_mac_global_buffer,BulkLen);

        for(n = 0; n < BulkLen;n++)

        {

            if(usb_mac_global_buffer[n] != BulkBuf[n])

            {

                MemOK = __FALSE;

                break;

            }

        }

        #endif

       

        #if NANDFLASH

        while(nandReady == 0);

        nandReady = 0;

        NAND_Read_Addr_Mal(Offset,usb_mac_global_buffer,BulkLen);

        nandReady = 1;

        for(n = 0; n < BulkLen;n++)

        {

            if(usb_mac_global_buffer[n] != BulkBuf[n])

            {

                MemOK = __FALSE;

                break;

            }

        }

        #endif

       

     

        Offset += BulkLen;

        Length -= BulkLen;

     

        CSW.dDataResidue -= BulkLen;

     

        if ((Length == 0) || (BulkStage == MSC_BS_CSW))

        {

            CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;//根据校验的最终状态,选择返回命令失败或者成功

            MSC_SetCSW();

        }

    }

     

     

    //usb实际与数据相关的处理工作

    uint32_t MSC_RWSetup (void)

    {

        uint32_t n;

     

        //首先获得逻辑地址对应的物理地址,主机发送下来的block地址,我们要转换成响应的nand block和nand page

        n = (CBW.CB[2] << 24) |(CBW.CB[3] << 16) |(CBW.CB[4] <<  8) | (CBW.CB[5] <<  0);

     

        Offset = n * MSC_BlockSize;//定位逻辑位置

     

        //需要传输的块数量

        n = (CBW.CB[7] <<  8) |

            (CBW.CB[8] <<  0);

     

        //要传输的数据总长度

        Length = n * MSC_BlockSize;

     

        if (CBW.dDataLength != Length) //接受长度必须和发送的要读取长度计算一致,否则不能起作用

        {

            USB_SetStallEP(MSC_EP_IN);

            USB_SetStallEP(MSC_EP_OUT);

            CSW.bStatus = CSW_PHASE_ERROR;

            MSC_SetCSW();

            return (__FALSE);

        }

       

        return (__TRUE);//算好了,核心是offect 和length

    }

     

     

    //检测数据是否符合规则

    uint32_t DataInFormat (void)

    {

     

        if (CBW.dDataLength == 0) //检测数据长度

        {

            CSW.bStatus = CSW_PHASE_ERROR;

            MSC_SetCSW();

            return (__FALSE);

        }

        if ((CBW.bmFlags & 0x80) == 0) //检测数据方向

        {

            USB_SetStallEP(MSC_EP_OUT);

            CSW.bStatus = CSW_PHASE_ERROR;

            MSC_SetCSW();

            return (__FALSE);

        }

        return (__TRUE);//数据ok

    }

     

     

    void DataInTransfer (void)

    {

     

        if (BulkLen > CBW.dDataLength) {

            BulkLen = CBW.dDataLength;

        }

     

        USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen);

        BulkStage = MSC_BS_DATA_IN_LAST;

     

        CSW.dDataResidue -= BulkLen;

        CSW.bStatus = CSW_CMD_PASSED;

    }

     

     

    //scsi指明测试存储单元是否准备好

    void MSC_TestUnitReady (void)

    {

     

        if (CBW.dDataLength != 0) //发送来的cbw不带数据就准备好了

        {

            if ((CBW.bmFlags & 0x80) != 0)

            {

                USB_SetStallEP(MSC_EP_IN);//设置断点暂停

            } else

            {

                USB_SetStallEP(MSC_EP_OUT);

            }

        }

        #if NANDFLASH

        if(nandReady == 0)MemOK = __FALSE;

        else MemOK = __TRUE;

        #endif

       

        if(MemOK == __TRUE)

        {

            CSW.bStatus = CSW_CMD_PASSED;//准备好存储空间

            MSC_SetCSW();

        }

        else

        {

            CSW.bStatus = CSW_CMD_FAILED;//还没准备好存储空间

            MSC_SetCSW();

        }

       

        #if NORFLASH

        if(msc_idle_time_count < MSC_IDLE_TIME_LIMIT)msc_idle_time_count++;//设备空闲时间(没发生写入的时间)

        else NOR_FLASH_Flush();

        #endif

       

        #if NANDFLASH

        if(msc_idle_time_count < MSC_IDLE_TIME_LIMIT)msc_idle_time_count++;//设备空闲时间(没发生写入的时间)

        else Nand_Flush();

        #endif

    }

     

     

    //检测上一次传输失败的原因 返回失败原因代码

    void MSC_RequestSense (void)

    {

     

        if (!DataInFormat()) return;

     

        BulkBuf[ 0] = 0x70;          //错误代码,固定为0x70

        BulkBuf[ 1] = 0x00;         //保留

        BulkBuf[ 2] = 0x00;         //Sense Key为0x05,表示无效请求(ILLEGAL REQUEST)

        BulkBuf[ 3] = 0x00;         //Information为0 四个字节

        BulkBuf[ 4] = 0x00;

        BulkBuf[ 5] = 0x00;

        BulkBuf[ 6] = 0x00;

        BulkBuf[ 7] = 0x0A;          //附加数据长度为10字节

        BulkBuf[ 8] = 0x00;          //保留 四字节

        BulkBuf[ 9] = 0x00;

        BulkBuf[10] = 0x00;

        BulkBuf[11] = 0x00;

        BulkBuf[12] = 0x00;          //Additional Sense Code(ASC)为0x20,表示无效命令操作码(INVALID COMMAND OPERATION CODE)

        BulkBuf[13] = 0x00;          //Additional Sense Code Qualifier(ASCQ)为0

        BulkBuf[14] = 0x00;          //保留 四字节

        BulkBuf[15] = 0x00;

        BulkBuf[16] = 0x00;

        BulkBuf[17] = 0x00;

     

        if (CBW.CB[4] <= 18)

        {

            BulkLen = CBW.CB[4];

        }

        else

        {

            BulkLen = 18;

        }

        DataInTransfer();

    }

     

    void MSC_Inquiry (void)

    {

     

        if (!DataInFormat()) return;

     

        BulkBuf[ 0] = 0x00;          //磁盘设备

        BulkBuf[ 1] = 0x80;          //其中最高位D7为RMB。RMB=0,表示不可移除设备。如果RMB=1,则为可移除设备。

        BulkBuf[ 2] = 0x00;          //各种版本号0

        BulkBuf[ 3] = 0x01;          //数据响应格式

     

        BulkBuf[ 4] = 36-4;          //附加数据长度,为32字节

        BulkBuf[ 5] = 0x80;          /* SCCS = 1: Storage Controller Component */

        BulkBuf[ 6] = 0x00;          //保留

        BulkBuf[ 7] = 0x00;          //保留

     

        BulkBuf[ 8] = 'D';           //厂商标识

        BulkBuf[ 9] = 'I';

        BulkBuf[10] = 'N';

        BulkBuf[11] = 'K';

        BulkBuf[12] = ' ';

        BulkBuf[13] = ' ';

        BulkBuf[14] = ' ';

        BulkBuf[15] = ' ';

     

        BulkBuf[16] = 'D';           //产品标识,

        BulkBuf[17] = 'E';

        BulkBuf[18] = 'N';

        BulkBuf[19] = 'G';

        BulkBuf[20] = 'X';

        BulkBuf[21] = 'I';

        BulkBuf[22] = 'A';

        BulkBuf[23] = 'O';

        BulkBuf[24] = 'J';

        BulkBuf[25] = 'U';

        BulkBuf[26] = 'N';

        BulkBuf[27] = 'D';

        BulkBuf[28] = 'I';

        BulkBuf[29] = 'S';

        BulkBuf[30] = 'K';

        BulkBuf[31] = ' ';

     

        BulkBuf[32] = '1';           //产品版本号

        BulkBuf[33] = '.';

        BulkBuf[34] = '0';

        BulkBuf[35] = ' ';

     

        BulkLen = 36;

        DataInTransfer();

    }

     

    //scsi响应函数

    void MSC_ModeSense6 (void)

    {

     

        if (!DataInFormat()) return;

     

        BulkBuf[ 0] = 0x03;

        BulkBuf[ 1] = 0x00;

        BulkBuf[ 2] = 0x00;

        BulkBuf[ 3] = 0x00;

     

        BulkLen = 4;

        DataInTransfer();

    }

     

    void MSC_ModeSense10 (void) {

     

        if (!DataInFormat()) return;

     

        BulkBuf[ 0] = 0x00;

        BulkBuf[ 1] = 0x06;

        BulkBuf[ 2] = 0x00;

        BulkBuf[ 3] = 0x00;

        BulkBuf[ 4] = 0x00;

        BulkBuf[ 5] = 0x00;

        BulkBuf[ 6] = 0x00;

        BulkBuf[ 7] = 0x00;

     

        BulkLen = 8;

        DataInTransfer();

    }

     

    //读取设备的实际容量

    void MSC_ReadCapacity (void)

    {

     

        if (!DataInFormat()) return;

     

        //最大逻辑块大小 因为逻辑块从0开始,所以需要-1

        BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;

        BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;

        BulkBuf[ 2] = ((MSC_BlockCount - 1) >>  8) & 0xFF;

        BulkBuf[ 3] = ((MSC_BlockCount - 1) >>  0) & 0xFF;

     

        //逻辑块长度

        BulkBuf[ 4] = (MSC_BlockSize >> 24) & 0xFF;

        BulkBuf[ 5] = (MSC_BlockSize >> 16) & 0xFF;

        BulkBuf[ 6] = (MSC_BlockSize >>  8) & 0xFF;

        BulkBuf[ 7] = (MSC_BlockSize >>  0) & 0xFF;

     

        BulkLen = 8;

        DataInTransfer();

    }

     

    //读格式化容量信息,返回最大能格式化的数据信息

    void MSC_ReadFormatCapacity (void)

    {

     

        if (!DataInFormat()) return;

     

        BulkBuf[ 0] = 0x00;

        BulkBuf[ 1] = 0x00;

        BulkBuf[ 2] = 0x00;

        BulkBuf[ 3] = 0x08;          //容量列表描述符长度

     

        //设备块数量 正对于不同的介质这里可以有不同的设置

        BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF;

        BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF;

        BulkBuf[ 6] = (MSC_BlockCount >>  8) & 0xFF;

        BulkBuf[ 7] = (MSC_BlockCount >>  0) & 0xFF;

     

        //每一块的长度

        BulkBuf[ 8] = 0x02;                     /* Descriptor Code: Formatted Media */

        BulkBuf[ 9] = (MSC_BlockSize >> 16) & 0xFF;

        BulkBuf[10] = (MSC_BlockSize >>  8) & 0xFF;

        BulkBuf[11] = (MSC_BlockSize >>  0) & 0xFF;

     

        BulkLen = 12;

        DataInTransfer();

    }

     

    void MSC_GetCBW (void)

    {

        uint32_t n;//将buf数据拷贝入cbw结构体,便于下一次处理

        for (n = 0; n < BulkLen; n++)

        {

            *((uint8_t *)&CBW + n) = BulkBuf[n];

        }

        if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) //检测命令长度以及命令头 usbc

        {

            //完整有效地cbw

            CSW.dTag = CBW.dTag;//发送来的cbw需要csw返回,csw的tag必须对应发送来的cbw tag

            CSW.dDataResidue = CBW.dDataLength;//需要传输的数据长度

            if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) //目标逻辑单元不对或者长度不对都会导致命令失败

            {

    fail: CSW.bStatus = CSW_CMD_FAILED;//命令失败,0x01

                MSC_SetCSW();//返回失败csw

            }

            else

            {

                switch (CBW.CB[0]) //检测命令代码,进行散转处理

                {

                case SCSI_TEST_UNIT_READY://测试设备是否准备好

                    MSC_TestUnitReady();

                    msc_debug_printf("SCSI_TEST_UNIT_READY ");

                    break;

                case SCSI_REQUEST_SENSE://检测上一次传输失败的原因

                    MSC_RequestSense();

                    msc_debug_printf("SCSI_REQUEST_SENSE ");

                    break;

                case SCSI_FORMAT_UNIT:  //格式化单元,不支持

                    msc_debug_printf("SCSI_FORMAT_UNIT ");

                    goto fail;

                case SCSI_INQUIRY: 

                    MSC_Inquiry();      //查询设备的基本信息

                    msc_debug_printf("SCSI_INQUIRY ");

                    break;

                case SCSI_START_STOP_UNIT://不支持

                    msc_debug_printf("SCSI_START_STOP_UNIT ");

                    goto fail;

                case SCSI_MEDIA_REMOVAL:

                    CSW.bStatus = CSW_CMD_PASSED;

                    MSC_SetCSW();//返回失败csw

                    msc_debug_printf("SCSI_MEDIA_REMOVAL ");

                    //goto fail;

                    break;

                case SCSI_MODE_SELECT6://不支持

                    msc_debug_printf("SCSI_MODE_SELECT6 ");

                    goto fail;

                case SCSI_MODE_SENSE6://不知干嘛的

                    MSC_ModeSense6();

                    msc_debug_printf("SCSI_MODE_SENSE6 ");

                    break;

                case SCSI_MODE_SELECT10:

                    msc_debug_printf("SCSI_MODE_SELECT10 ");

                    goto fail;

                case SCSI_MODE_SENSE10:

                    MSC_ModeSense10();

                    msc_debug_printf("SCSI_MODE_SENSE10 ");

                    break;

                case SCSI_READ_FORMAT_CAPACITIES://读格式化容量信息

                    MSC_ReadFormatCapacity();

                    msc_debug_printf("SCSI_READ_FORMAT_CAPACITIES ");

                    break;

                case SCSI_READ_CAPACITY://读容量信息

                    MSC_ReadCapacity();

                    msc_debug_printf("SCSI_READ_CAPACITY ");

                    break;

                case SCSI_READ10://读取实际的磁盘数据

                    if (MSC_RWSetup())

                    {

                        if ((CBW.bmFlags & 0x80) != 0) //方向没有错误

                        {

                            BulkStage = MSC_BS_DATA_IN;//数据输入状态,下次in事件来的时候就能传输正确数据

                            MSC_MemoryRead();

                            msc_debug_printf("SCSI_READ10 right ");

                        }

                        else

                        {

                            USB_SetStallEP(MSC_EP_OUT);//方向错误,暂停端点

                            CSW.bStatus = CSW_CMD_FAILED;

                            MSC_SetCSW();

                            msc_debug_printf("SCSI_READ10 error ");

                        }

                    }

                    break;

                case SCSI_WRITE10://写入实际磁盘数据

                    if (MSC_RWSetup())

                    {

                        if ((CBW.bmFlags & 0x80) == 0) //检查方向

                        {

                            BulkStage = MSC_BS_DATA_OUT;//说明下一次out带来就是要写入数据,修改设备的状态

                            msc_debug_printf("SCSI_WRITE10 right ");

                        }

                        else

                        {

                            USB_SetStallEP(MSC_EP_IN);//命令不支持(核心思想状态机)

                            CSW.bStatus = CSW_PHASE_ERROR;

                            MSC_SetCSW();

                            msc_debug_printf("SCSI_WRITE10 error ");

                        }

                    }

                    msc_debug_printf("SCSI_WRITE10 ");

                    break;

                case SCSI_VERIFY10://校验数据

                    if (MSC_RWSetup())

                    {

                        if ((CBW.bmFlags & 0x80) == 0)

                        {

                            BulkStage = MSC_BS_DATA_OUT;

                            MemOK = __TRUE;//直接返回数据校验ok

                        }

                        else

                        {

                            USB_SetStallEP(MSC_EP_IN);

                            CSW.bStatus = CSW_PHASE_ERROR;//方向不对,命令错误

                            MSC_SetCSW();

                        }

                    }

                    msc_debug_printf("SCSI_VERIFY10 ");

                    break;

                default:

                    goto fail;

                    }

            }

        }

        else

        {//无效的cbw指令,直接禁用全部端点,等待usb重新设置端点 从错误中恢复

            USB_SetStallEP(MSC_EP_IN);

            USB_SetStallEP(MSC_EP_OUT);

            BulkStage = MSC_BS_ERROR;

            msc_debug_printf("无效的cbw指令 ");

        }

    }

     

     

    //设备返回的状态封包

    void MSC_SetCSW (void) {

     

        CSW.dSignature = MSC_CSW_Signature;

        USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));

        BulkStage = MSC_BS_CSW;

    }

     

     

    Usb大容量存储器的宏如下

     

    #ifndef __MSC_H__

    #define __MSC_H__

    #include "sys.h"

     

    /* MSC Subclass Codes */

    #define MSC_SUBCLASS_RBC                0x01

    #define MSC_SUBCLASS_SFF8020I_MMC2      0x02

    #define MSC_SUBCLASS_QIC157             0x03

    #define MSC_SUBCLASS_UFI                0x04

    #define MSC_SUBCLASS_SFF8070I           0x05

    #define MSC_SUBCLASS_SCSI               0x06

     

    /* MSC Protocol Codes */

    #define MSC_PROTOCOL_CBI_INT            0x00

    #define MSC_PROTOCOL_CBI_NOINT          0x01

    #define MSC_PROTOCOL_BULK_ONLY          0x50

     

     

    /* MSC Request Codes */

    #define MSC_REQUEST_RESET               0xFF

    #define MSC_REQUEST_GET_MAX_LUN         0xFE

     

     

    /* MSC Bulk-only Stage */

    #define MSC_BS_CBW                      0       /* Command Block Wrapper */

    #define MSC_BS_DATA_OUT                 1       /* Data Out Phase */

    #define MSC_BS_DATA_IN                  2       /* Data In Phase */

    #define MSC_BS_DATA_IN_LAST             3       /* Data In Last Phase */

    #define MSC_BS_DATA_IN_LAST_STALL       4       /* Data In Last Phase with Stall */

    #define MSC_BS_CSW                      5       /* Command Status Wrapper */

    #define MSC_BS_ERROR                    6       /* Error */

     

     

    typedef __packed struct _MSC_CBW {

      uint32_t dSignature;  //cbw标志  为USBC四个字符

      uint32_t dTag;        //cbw标签,返回csw的时候需要添加

      uint32_t dDataLength; //需要在数据阶段传送的字节数,低字节在前

      uint8_t  bmFlags;     //cbw标志,最高位标识数据方向

      uint8_t  bLUN;        //目标逻辑单元编号,仅仅使用低四位

      uint8_t  bCBLength;   //cbw cb的长度,使用低五位

      uint8_t  CB[16];      //选择执行的命令,由选择的子类决定使用的命令,(一般是scsi命令集)

    } MSC_CBW;

     

    typedef __packed struct _MSC_CSW {

      uint32_t dSignature;  //csw标志,为字符 usbs

      uint32_t dTag;    //命令状态标签,从cbw的标签中来

      uint32_t dDataResidue;    //命令完成时的完成字节数

      uint8_t  bStatus; //命令执行状态 00代表执行成功

    } MSC_CSW;

     

    #define MSC_CBW_Signature               0x43425355  //usbc

    #define MSC_CSW_Signature               0x53425355  //usbs

     

     

    /* CSW Status Definitions */

    #define CSW_CMD_PASSED                  0x00

    #define CSW_CMD_FAILED                  0x01

    #define CSW_PHASE_ERROR                 0x02

     

     

    /* SCSI Commands */

    #define SCSI_TEST_UNIT_READY            0x00

    #define SCSI_REQUEST_SENSE              0x03

    #define SCSI_FORMAT_UNIT                0x04

    #define SCSI_INQUIRY                    0x12

    #define SCSI_MODE_SELECT6               0x15

    #define SCSI_MODE_SENSE6                0x1A

    #define SCSI_START_STOP_UNIT            0x1B

    #define SCSI_MEDIA_REMOVAL              0x1E

    #define SCSI_READ_FORMAT_CAPACITIES     0x23

    #define SCSI_READ_CAPACITY              0x25

    #define SCSI_READ10                     0x28

    #define SCSI_WRITE10                    0x2A

    #define SCSI_VERIFY10                   0x2F

    #define SCSI_MODE_SELECT10              0x55

    #define SCSI_MODE_SENSE10               0x5A

     

     

    #endif 

     

     

     

    在之前的代码中会调用两个存储设备读写命令,如下

     

    #ifndef __MEMORY_H_

    #define __MEMORY_H_

    #include "sst39vf32.h"

    #include "k9f1g08.h"

    #include "hy57v256.h"

     

    #define NORFLASH    0

    #define NANDFLASH   1

     

     

     

    #if NORFLASH

     

    #define MSC_MemorySize  NOR_FLASH_SIZE  //norflash大小

    #define MSC_BlockSize   SECTOR_SIZE     //norflash扇区大小

    #define MSC_BlockCount  SECTOR_COUNT    //norflash扇区总数

     

    extern u8 msc_idle_time_count;

     

    #define MSC_IDLE_TIME_LIMIT     90

     

    #endif

     

     

     

    #if NANDFLASH

     

    #define MSC_MemorySize  NAND_USE_NUMOF_BLOCK*NAND_PAGE_NUM*NAND_SERECT_SIZE //nand flash大小

    #define MSC_BlockSize   NAND_SERECT_SIZE            //nand flash扇区大小

    #define MSC_BlockCount  NAND_USE_NUMOF_BLOCK*NAND_PAGE_NUM  //nand flash扇区数量

     

    extern u8 msc_idle_time_count;

     

    #define MSC_IDLE_TIME_LIMIT     90

     

    #endif

     

    #endif

     

     

    #include "memory.h"

     

    #if NORFLASH

     

    u8 msc_idle_time_count; //岣дȫĿՏЊ䍊

    #endif

     

     

    #if NANDFLASH

     

    u8 msc_idle_time_count;

     

    #endif

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    vue 兼容IE报错解决方案
    JDK1.8 ArrayList 源码解析
    Mac nasm 汇编入门
    命令模式
    模板方法
    Mysql Limit 调优
    观察者模式
    外观模式
    Rest- Client
    MongoDB数据库 5分钟快速上手
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4338717.html
Copyright © 2011-2022 走看看