local fix version of myBlueUSB (http://mbed.org/users/networker/code/myBlueUSB/). - merge deleted files which are required to compile. - enable echo back of received data via RFCOMM.

Dependencies:   AvailableMemory FatFileSystem mbed myUSBHost

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MassStorage.h Source File

MassStorage.h

00001 #ifndef MASSSTORAGE_H
00002 #define MASSSTORAGE_H
00003 
00004 #include "Utils.h"
00005 #include "USBHost.h"
00006 
00007 
00008 #define ERR_BAD_CSW_SIGNATURE -200
00009 
00010 #define CBW_SIGNATURE  0x43425355
00011 #define CSW_SIGNATURE  0x53425355
00012 
00013 #define BULK_ENDPOINT_IN    0x81
00014 #define BULK_ENDPOINT_OUT   0x02
00015 
00016 //  Command Block
00017 typedef struct {
00018     u32 Signature;
00019     u32 Tag;
00020     u32 TransferLength;
00021     u8 Flags;
00022     u8 LUN;
00023     u8 CBLength;
00024     u8 CB[16];   // only 6 really
00025 } CBW;
00026 
00027 //  Status block
00028 typedef struct {
00029     u32 Signature;
00030     u32 Tag;
00031     u32 DataResidue;
00032     u8 Status;
00033 } CSW;
00034 
00035 class USBSCSI {
00036 protected:
00037     int _device;
00038     unsigned char epin, epout;
00039 public:
00040     USBSCSI() : _device(0) {}
00041 
00042     void SetDevice(int device, unsigned char in, unsigned char out)
00043     {
00044         _device = device;
00045         epin = in;
00046         epout = out;
00047     }
00048 protected:    
00049     int DoSCSI(const u8* cmd, int cmdLen, int flags, u8* data, u32 transferLen) {
00050         CBW cbw;
00051         cbw.Signature = CBW_SIGNATURE;
00052         cbw.Tag = 0;
00053         cbw.TransferLength = transferLen;
00054         cbw.Flags = flags;
00055         cbw.LUN = 0;
00056         cbw.CBLength = cmdLen;
00057         memset(cbw.CB,0,sizeof(cbw.CB));
00058         memcpy(cbw.CB,cmd,cmdLen);
00059 
00060         int r;
00061         //r = USBBulkTransfer(device,0x01,(u8*)&cbw,31);   // Send the command
00062         r = USBBulkTransfer(_device,epout,(u8*)&cbw,31);   // Send the command
00063         if (r < 0) {
00064             printf("first transfer returns %d\n", r);
00065             return r;
00066         }
00067         if (data) {
00068             //r = USBBulkTransfer(device,flags | 1,data,transferLen);
00069             r = USBBulkTransfer(_device,flags ? epin : epout,data,transferLen);
00070             if (r < 0) {
00071                 printf("second transfer returns %d (flags=%02xH)\n", r, flags);
00072                 return r;
00073             }
00074         }
00075 
00076         CSW csw;
00077         csw.Signature = 0;
00078         //r = USBBulkTransfer(device,0x81,(u8*)&csw,13);
00079         r = USBBulkTransfer(_device,epin,(u8*)&csw,13);
00080         if (r < 0) {
00081             printf("third transfer returns %d\n", r);
00082             return r;
00083         }
00084         if (csw.Signature != CSW_SIGNATURE)
00085             return ERR_BAD_CSW_SIGNATURE;
00086 
00087         // ModeSense?
00088         if (csw.Status == 1 && cmd[0] != 3)
00089             return SCSIRequestSense();
00090 
00091         return csw.Status;
00092     }
00093 
00094     int SCSITestUnitReady() {
00095         u8 cmd[6];
00096         memset(cmd,0,6);
00097         return DoSCSI(cmd,6,DEVICE_TO_HOST,0,0);
00098     }
00099 
00100     int SCSIRequestSense() {
00101         u8 cmd[6] = {0x03,0,0,0,18,0};
00102         u8 result[18];
00103         int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,18);
00104         return r;
00105     }
00106 
00107     int SCSIInquiry() {
00108         u8 cmd[6] = {0x12,0,0,0,36,0};
00109         u8 result[36+2];
00110         result[36] = '\n';
00111         result[37] = 0;
00112         int r = DoSCSI(cmd,6,DEVICE_TO_HOST,result,36);
00113         if (r == 0)
00114             printf((const char*)result + 8);
00115         return r;
00116     }
00117 
00118     int SCSIReadCapacity(u32* blockCount, u32* blockSize) {
00119         u8 cmd[10] = {0x25,0,0,0,8,0,0,0,0,0};
00120         u8 result[8];
00121         *blockSize = 0;
00122         *blockCount = 0;
00123         int r = DoSCSI(cmd,10,DEVICE_TO_HOST,result,8);
00124         if (r == 0) {
00125             *blockCount = BE32(result);
00126             *blockSize = BE32(result+4);
00127         }
00128         return r;
00129     }
00130 
00131     int SCSITransfer(u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize, int direction) {
00132         //  USB hardware will only do 4k per transfer
00133         while (blockCount*blockSize > 4096) {
00134             int count = 4096/blockSize;
00135             int r = SCSITransfer(blockAddr,count,dst,blockSize,direction);
00136             dst += count*blockSize;
00137             blockAddr += count;
00138             blockCount -= count;
00139         }
00140 
00141         u8 cmd[10];
00142         memset(cmd,0,10);
00143         cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
00144         BE32(blockAddr,cmd+2);
00145         BE16(blockCount,cmd+7);
00146         return DoSCSI(cmd,10,direction,dst,blockSize*blockCount);
00147     }
00148 };
00149 #endif