Almost identical to USBHostShell; reads all endpoint descriptors

Dependents:   myBlueUSB mbed_TANK_Kinect myBlueUSB_ros myBlueUSB_localfix

Committer:
networker
Date:
Fri Jul 01 09:13:39 2011 +0000
Revision:
3:58c785c2b381
revised massStorage to cope with different endpoint addresses

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 3:58c785c2b381 1 #ifndef MASSSTORAGE_H
networker 3:58c785c2b381 2 #define MASSSTORAGE_H
networker 3:58c785c2b381 3
networker 3:58c785c2b381 4 #include "Utils.h"
networker 3:58c785c2b381 5 #include "USBHost.h"
networker 3:58c785c2b381 6
networker 3:58c785c2b381 7
networker 3:58c785c2b381 8 #define ERR_BAD_CSW_SIGNATURE -200
networker 3:58c785c2b381 9
networker 3:58c785c2b381 10 #define CBW_SIGNATURE 0x43425355
networker 3:58c785c2b381 11 #define CSW_SIGNATURE 0x53425355
networker 3:58c785c2b381 12
networker 3:58c785c2b381 13 #define BULK_ENDPOINT_IN 0x81
networker 3:58c785c2b381 14 #define BULK_ENDPOINT_OUT 0x02
networker 3:58c785c2b381 15
networker 3:58c785c2b381 16 // Command Block
networker 3:58c785c2b381 17 typedef struct {
networker 3:58c785c2b381 18 u32 Signature;
networker 3:58c785c2b381 19 u32 Tag;
networker 3:58c785c2b381 20 u32 TransferLength;
networker 3:58c785c2b381 21 u8 Flags;
networker 3:58c785c2b381 22 u8 LUN;
networker 3:58c785c2b381 23 u8 CBLength;
networker 3:58c785c2b381 24 u8 CB[16]; // only 6 really
networker 3:58c785c2b381 25 } CBW;
networker 3:58c785c2b381 26
networker 3:58c785c2b381 27 // Status block
networker 3:58c785c2b381 28 typedef struct {
networker 3:58c785c2b381 29 u32 Signature;
networker 3:58c785c2b381 30 u32 Tag;
networker 3:58c785c2b381 31 u32 DataResidue;
networker 3:58c785c2b381 32 u8 Status;
networker 3:58c785c2b381 33 } CSW;
networker 3:58c785c2b381 34
networker 3:58c785c2b381 35 class USBSCSI {
networker 3:58c785c2b381 36 protected:
networker 3:58c785c2b381 37 int _device;
networker 3:58c785c2b381 38 unsigned char epin, epout;
networker 3:58c785c2b381 39 public:
networker 3:58c785c2b381 40 USBSCSI() : _device(0) {}
networker 3:58c785c2b381 41
networker 3:58c785c2b381 42 void SetDevice(int device, unsigned char in, unsigned char out)
networker 3:58c785c2b381 43 {
networker 3:58c785c2b381 44 _device = device;
networker 3:58c785c2b381 45 epin = in;
networker 3:58c785c2b381 46 epout = out;
networker 3:58c785c2b381 47 }
networker 3:58c785c2b381 48 protected:
networker 3:58c785c2b381 49 int DoSCSI(const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen) {
networker 3:58c785c2b381 50 CBW cbw;
networker 3:58c785c2b381 51 cbw.Signature = CBW_SIGNATURE;
networker 3:58c785c2b381 52 cbw.Tag = 0;
networker 3:58c785c2b381 53 cbw.TransferLength = transferLen;
networker 3:58c785c2b381 54 cbw.Flags = flags;
networker 3:58c785c2b381 55 cbw.LUN = 0;
networker 3:58c785c2b381 56 cbw.CBLength = cmdLen;
networker 3:58c785c2b381 57 memset(cbw.CB,0,sizeof(cbw.CB));
networker 3:58c785c2b381 58 memcpy(cbw.CB,cmd,cmdLen);
networker 3:58c785c2b381 59
networker 3:58c785c2b381 60 int r;
networker 3:58c785c2b381 61 //r = USBBulkTransfer(device,0x01,(u8*)&cbw,31); // Send the command
networker 3:58c785c2b381 62 r = USBBulkTransfer(_device,epout,(u8*)&cbw,31); // Send the command
networker 3:58c785c2b381 63 if (r < 0) {
networker 3:58c785c2b381 64 printf("first transfer returns %d\n", r);
networker 3:58c785c2b381 65 return r;
networker 3:58c785c2b381 66 }
networker 3:58c785c2b381 67 if (data) {
networker 3:58c785c2b381 68 //r = USBBulkTransfer(device,flags | 1,data,transferLen);
networker 3:58c785c2b381 69 r = USBBulkTransfer(_device,flags ? epin : epout,data,transferLen);
networker 3:58c785c2b381 70 if (r < 0) {
networker 3:58c785c2b381 71 printf("second transfer returns %d (flags=%02xH)\n", r, flags);
networker 3:58c785c2b381 72 return r;
networker 3:58c785c2b381 73 }
networker 3:58c785c2b381 74 }
networker 3:58c785c2b381 75
networker 3:58c785c2b381 76 CSW csw;
networker 3:58c785c2b381 77 csw.Signature = 0;
networker 3:58c785c2b381 78 //r = USBBulkTransfer(device,0x81,(u8*)&csw,13);
networker 3:58c785c2b381 79 r = USBBulkTransfer(_device,epin,(u8*)&csw,13);
networker 3:58c785c2b381 80 if (r < 0) {
networker 3:58c785c2b381 81 printf("third transfer returns %d\n", r);
networker 3:58c785c2b381 82 return r;
networker 3:58c785c2b381 83 }
networker 3:58c785c2b381 84 if (csw.Signature != CSW_SIGNATURE)
networker 3:58c785c2b381 85 return ERR_BAD_CSW_SIGNATURE;
networker 3:58c785c2b381 86
networker 3:58c785c2b381 87 // ModeSense?
networker 3:58c785c2b381 88 if (csw.Status == 1 && cmd[0] != 3)
networker 3:58c785c2b381 89 return SCSIRequestSense();
networker 3:58c785c2b381 90
networker 3:58c785c2b381 91 return csw.Status;
networker 3:58c785c2b381 92 }
networker 3:58c785c2b381 93
networker 3:58c785c2b381 94 int SCSITestUnitReady() {
networker 3:58c785c2b381 95 u8 cmd[6];
networker 3:58c785c2b381 96 memset(cmd,0,6);
networker 3:58c785c2b381 97 return DoSCSI(cmd,6,DEVICE_TO_HOST,0,0);
networker 3:58c785c2b381 98 }
networker 3:58c785c2b381 99
networker 3:58c785c2b381 100 int SCSIRequestSense() {
networker 3:58c785c2b381 101 u8 cmd[6] = {0x03,0,0,0,18,0};
networker 3:58c785c2b381 102 u8 result[18];
networker 3:58c785c2b381 103 int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,18);
networker 3:58c785c2b381 104 return r;
networker 3:58c785c2b381 105 }
networker 3:58c785c2b381 106
networker 3:58c785c2b381 107 int SCSIInquiry() {
networker 3:58c785c2b381 108 u8 cmd[6] = {0x12,0,0,0,36,0};
networker 3:58c785c2b381 109 u8 result[36+2];
networker 3:58c785c2b381 110 result[36] = '\n';
networker 3:58c785c2b381 111 result[37] = 0;
networker 3:58c785c2b381 112 int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,36);
networker 3:58c785c2b381 113 if (r == 0)
networker 3:58c785c2b381 114 printf((const char*)result + 8);
networker 3:58c785c2b381 115 return r;
networker 3:58c785c2b381 116 }
networker 3:58c785c2b381 117
networker 3:58c785c2b381 118 int SCSIReadCapacity(u32* blockCount, u32* blockSize) {
networker 3:58c785c2b381 119 u8 cmd[10] = {0x25,0,0,0,8,0,0,0,0,0};
networker 3:58c785c2b381 120 u8 result[8];
networker 3:58c785c2b381 121 *blockSize = 0;
networker 3:58c785c2b381 122 *blockCount = 0;
networker 3:58c785c2b381 123 int r = DoSCSI(cmd,10,DEVICE_TO_HOST,result,8);
networker 3:58c785c2b381 124 if (r == 0) {
networker 3:58c785c2b381 125 *blockCount = BE32(result);
networker 3:58c785c2b381 126 *blockSize = BE32(result+4);
networker 3:58c785c2b381 127 }
networker 3:58c785c2b381 128 return r;
networker 3:58c785c2b381 129 }
networker 3:58c785c2b381 130
networker 3:58c785c2b381 131 int SCSITransfer(u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction) {
networker 3:58c785c2b381 132 // USB hardware will only do 4k per transfer
networker 3:58c785c2b381 133 while (blockCount*blockSize > 4096) {
networker 3:58c785c2b381 134 int count = 4096/blockSize;
networker 3:58c785c2b381 135 int r = SCSITransfer(blockAddr,count,dst,blockSize,direction);
networker 3:58c785c2b381 136 dst += count*blockSize;
networker 3:58c785c2b381 137 blockAddr += count;
networker 3:58c785c2b381 138 blockCount -= count;
networker 3:58c785c2b381 139 }
networker 3:58c785c2b381 140
networker 3:58c785c2b381 141 u8 cmd[10];
networker 3:58c785c2b381 142 memset(cmd,0,10);
networker 3:58c785c2b381 143 cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
networker 3:58c785c2b381 144 BE32(blockAddr,cmd+2);
networker 3:58c785c2b381 145 BE16(blockCount,cmd+7);
networker 3:58c785c2b381 146 return DoSCSI(cmd,10,direction,dst,blockSize*blockCount);
networker 3:58c785c2b381 147 }
networker 3:58c785c2b381 148 };
networker 3:58c785c2b381 149 #endif