2014-01-25 35 views
1

我正在尝试为8位RISC MCU编写USB初始化程序。下面给出数据表链接。了解和解码标准USB命令到端点零?

我的目标是编写设备原型代码,这将允许主机成功枚举我的设备并发送/接收数据。

在这种IC的SDK有一个UFI静态库没有来源,它在头文件中定义只有几个功能:

// 
// Command/Data/Status Protocol 
// 
typedef struct _CBW // Command Block Wrapper 
{ 
    unsigned char dSignature[4]; // 43425355h (little endian) 
    unsigned char dTag[4]; 
    unsigned char dDataTransferLength[4]; 
    unsigned char bmFlags;   // Bit 7 0 = Data-Out from host to the device. 
            //   1 = Data-In from the device to host. 
            // Bit 6 Obsolete 
    unsigned char bLUN; 
    unsigned char bCBLength; 
    unsigned char CB[0x10];   // offset: (15 + bCBLength - 1) 
} CBW; 
typedef struct _CSW // Command Status Wrapper 
{ 
    unsigned char dSignature[4]; // 53425355h (little endian) 
    unsigned char dTag[4]; 
    unsigned char dDataResidue[4]; 
    unsigned char bStatus;   // 00h Command Passed ("good status") 
            // 01h Command Failed 
            // 02h Phase Error 
            // 03h and 04h Reserved (Obsolete) 
} CSW; 

#define COMMAND_PASSED 0x00 
#define COMMAND_FAILED 0x01 
#define PHASE_ERROR 0x02 

enum 
{ 
UFI_MODE_TIMESYNC = 1, 
UFI_MODE_DOWNSTART, 
UFI_MODE_DOWNFINISH, 
UFI_MODE_IGNORE, 
UFI_MODE_NORMAL 
}; 

// 
// UFI Command 
// 
#define INQUIRY      0x12 
#define READ_FORMAT_CAPACITIES  0x23 
#define READ_CAPACITY    0x25 
#define READ_10      0x28 
#define REQUEST_SENSE    0x03 
#define TEST_UNIT_READY    0x00 
#define PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e 
#define WRITE_10      0x2a 
#define VERIFY      0x2f 

typedef struct 
{ 
    UCHAR memType; // 0:eflash 1:s-flash 
    ULONG tgtAddr; // Target address to write 
    ULONG totSize; // Total size of data 
    ULONG curSize; // Downloaded size of data 
}stUfiDwnStatus; 

UFI_EXT CBW g_cbw; 
UFI_EXT CSW g_csw; 
UFI_EXT unsigned char g_bUfiWriteMode; 
UFI_EXT unsigned char g_bUfiWriteMode_post; 
UFI_EXT stUfiDwnStatus g_ufiDwnStaus; 



void UFI_proc(void); 
void UFI_InitMem(UCHAR *buf, UCHAR *name); // Buffer size must be larger than 0x200 
void UFI_InitFuncEFlash(void (*funcSectorErase)(UCHAR AddH, UCHAR AddM, UCHAR AddL), 
         void (*funcPageProgram)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer), 
         void (*funcRead)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer)); 
void UFI_InitFuncSFlash(void (*funcBlockErase)(UCHAR AddH, UCHAR AddM, UCHAR AddL), 
         void (*funcPageProgram)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer), 
         void (*funcRead)(UCHAR AddH, UCHAR AddM, UCHAR AddL, int size, UCHAR *Buffer)); 

不知怎的,我为了把我的设备使用这个库作为海量存储来避免处理自定义主机设备驱动程序。

问题是我不知道从哪里开始。特别是我不明白如何配置EP0? USB功能列表提及

Understanding and decoding of standard USB commands to endpoint zero 

究竟是什么意思?文档非常稀少,我不知道为了至少在设备端初始化USB设备要遵循什么逻辑。我通常阅读关于USB的知识,但是我不能将这些知识与我必须构建代码的方式联系起来......我已经完成了对该IC上除USB外的所有外设的编码。

任何想法将不胜感激。

https://www.dropbox.com/s/qd9d25oxxvh23ia/BMC51A_UM_REV1.0.pdf

+0

什么是UFI?你有什么确切的处理器和硬件? –

+0

'USB软盘接口'和命令指定[这里](https://www.dropbox.com/s/5avvsl4571szs9z/usbmass-ufi10.pdf)。它看起来像命令匹配。处理器参考在我的文章中描述。我没有其他硬件,只有那个CPU。 – Pablo

回答

1

“标准USB命令端点零”中的USB规范的第9章中描述。我通常是指到2.0版,您可以在这里找到:

http://www.usb.org/developers/docs/usb20_docs/

只需下载ZIP文件,找到usb_20.pdf,并进入第9章。该章规定了由使用端点零控制权转移USB主机获取描述符并设置设备。 USB规范大约有600页,但它非常易读,你应该能够从中学到很多东西。

为了让您的设备像一个大容量存储设备,你需要实现在USB-IF设备类文件的大容量存储类别描述的一些功能:

http://www.usb.org/developers/docs/devclass_docs/

如果您在这个级别使用USB,您需要一些方法来查看总线上的低级流量。我建议使用hardware USB protocol analyzer,但您也可能会找到一个软件解决方案。您也可以使用示波器,但要花几分钟时间才能解码每个数据包并找到您要查找的内容。

您发布的代码看上去与标准USB命令没有任何关系。它可能与MSD类有关,也可能是一些自定义协议。

1

“端点零”是USB中的“控制转移”。

对于数据交换,存在“批量传输”(批量在&批量出,具有不同的端点)。

我的建议是,你首先在PC上编写一个简单的USB驱动程序,以了解USB工作原理。

你可以在linux上使用“tcpdump”(使用“modprobe usbmon”之后的接口usbmon0,usbmon1等)嗅探usb数据包。使用wireshark查看数据包。

您可以使用libusb轻松地从用户空间访问USB。