USBMSD SD card Hello World for Mbed platforms

Dependencies:   mbed USBMSD_SD USBDevice

Files at this revision

API Documentation at this revision

Comitter:
samux
Date:
Wed Nov 16 11:06:27 2011 +0000
Parent:
9:9c343b9ee6d8
Child:
11:a26e7b7a1221
Commit message:
YES!!!!!!!!!!!!!!!!!! msd with sd card and hid generic device works

Changed in this revision

USBMSD/USBMSD.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD/USBMSD.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/USBMSD/USBMSD.cpp	Tue Nov 15 09:16:25 2011 +0000
+++ b/USBMSD/USBMSD.cpp	Wed Nov 16 11:06:27 2011 +0000
@@ -48,26 +48,74 @@
 USBMSD::USBMSD(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
 }
 
-
-DigitalOut l2(LED2);
-// Called in ISR context to process a class specific request
-bool USBMSD::USBCallback_request(void) {
-
+bool USBMSD::USBCallback_request() {
     bool success = false;
     CONTROL_TRANSFER * transfer = getTransferPtr();
+    uint8_t *hidDescriptor;
+
+    // Process additional standard requests
+
+    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) {
+        switch (transfer->setup.bRequest) {
+            case GET_DESCRIPTOR:
+                switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) {
+                    case REPORT_DESCRIPTOR:
+                        if ((reportDesc() != NULL) \
+                                && (reportDescLength() != 0)) {
+                            printf("report desc\r\n");
+                            transfer->remaining = reportDescLength();
+                            transfer->ptr = reportDesc();
+                            transfer->direction = DEVICE_TO_HOST;
+                            success = true;
+                        }
+                        break;
+                    case HID_DESCRIPTOR:
+                        printf("hid desc\r\n");
+                        // Find the HID descriptor, after the configuration descriptor
+                        hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+                        if (hidDescriptor != NULL) {
+                            transfer->remaining = HID_DESCRIPTOR_LENGTH;
+                            transfer->ptr = hidDescriptor;
+                            transfer->direction = DEVICE_TO_HOST;
+                            success = true;
+                        }
+                        break;
+
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    // Process class-specific requests
 
     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        uint8_t * dum = {0};
         switch (transfer->setup.bRequest) {
-            case MSC_REQUEST_RESET:
-                reset();
+            case SET_REPORT:
+                // First byte will be used for report ID
+                outputReport.data[0] = transfer->setup.wValue & 0xff;
+                outputReport.length = transfer->setup.wLength + 1;
+
+                transfer->remaining = sizeof(outputReport.data) - 1;
+                transfer->ptr = &outputReport.data[1];
+                transfer->direction = HOST_TO_DEVICE;
+                transfer->notify = true;
                 success = true;
-                break;
             case MSC_REQUEST_GET_MAX_LUN:
+                printf("get max lun\r\n");
                 transfer->remaining = 1;
-                transfer->ptr = getMaxLUN();
+                transfer->ptr = dum;
                 transfer->direction = DEVICE_TO_HOST;
                 success = true;
                 break;
+            case SET_IDLE:
+                printf("set idle\r\n");
+                // First byte will be used for report ID
+                success = true;
             default:
                 break;
         }
@@ -76,6 +124,39 @@
     return success;
 }
 
+bool USBMSD::send(HID_REPORT *report) {
+    return USBDevice::write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+
+bool USBMSD::read(HID_REPORT *report) {
+    uint16_t bytesRead = 0;
+    bool result;
+    result = USBDevice::read(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    report->length = bytesRead;
+    return result;
+}
+
+
+bool USBMSD::readNB(HID_REPORT *report) {
+    uint16_t bytesRead = 0;
+    bool result;
+    result = USBDevice::readNB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    report->length = bytesRead;
+    if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    return result;
+}
+
+
+uint16_t USBMSD::reportDescLength() {
+    reportDesc();
+    return reportLength;
+}
+
+
 
 bool USBMSD::connect() {
 
@@ -91,13 +172,13 @@
     }
 
     BlockCount = disk_sectors();
-    
+
     //get memory size
     MemorySize = BlockCount * BlockSize;
     if (!MemorySize) {
         return false;
     }
-    
+
     printf("blockSize: %d\r\n", BlockSize);
     printf("memSize: %d\r\n", MemorySize);
     printf("number of blocks: %d\r\n", BlockCount);
@@ -121,7 +202,7 @@
 bool USBMSD::EP2_OUT_callback() {
     uint16_t size = 0;
     uint8_t buf[MAX_PACKET_SIZE_EPBULK];
-    read(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
+    USBDevice::read(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
     switch (stage) {
             // the device has to decode the CBW received
         case READ_CBW:
@@ -544,11 +625,14 @@
     }
 
     // Configure endpoints > 0
+    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
     addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
     addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
 
-    //activate readings
     readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
     return true;
 }
 
@@ -571,22 +655,45 @@
     return stringIproductDescriptor;
 }
 
+uint8_t * USBMSD::reportDesc() {
+    static uint8_t reportDescriptor[] = {
+        0x06, LSB(0xFFAB), MSB(0xFFAB),
+        0x0A, LSB(0x0200), MSB(0x0200),
+        0xA1, 0x01,         // Collection 0x01
+        0x75, 0x08,         // report size = 8 bits
+        0x15, 0x00,         // logical minimum = 0
+        0x26, 0xFF, 0x00,   // logical maximum = 255
+        0x95, 64,           // report count
+        0x09, 0x01,         // usage
+        0x81, 0x02,         // Input (array)
+        0x95, 64,           // report count
+        0x09, 0x02,         // usage
+        0x91, 0x02,         // Output (array)
+        0xC0                // end collection
+
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (2 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * HID_DESCRIPTOR_LENGTH) \
+                               + (4 * ENDPOINT_DESCRIPTOR_LENGTH))
 
 uint8_t * USBMSD::configurationDesc() {
     static uint8_t configDescriptor[] = {
+        CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+        CONFIGURATION_DESCRIPTOR,       // bDescriptorType
+        LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
+        MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
+        0x02,                           // bNumInterfaces     (2 interfaces)
+        DEFAULT_CONFIGURATION,          // bConfigurationValue
+        0x00,                           // iConfiguration
+        C_RESERVED | C_SELF_POWERED,    // bmAttributes
+        C_POWER(0),                     // bMaxPower
 
-        // Configuration 1
-        9,      // bLength
-        2,      // bDescriptorType
-        LSB(9 + 9 + 7 + 7), // wTotalLength
-        MSB(9 + 9 + 7 + 7),
-        0x01,   // bNumInterfaces
-        0x01,   // bConfigurationValue: 0x01 is used to select this configuration
-        0x00,   // iConfiguration: no string to describe this configuration
-        0xC0,   // bmAttributes
-        100,    // bMaxPower, device power consumption is 100 mA
-
-        // Interface 0, Alternate Setting 0, MSC Class
+        // Interface 1, Alternate Setting 0, MSC Class
         9,      // bLength
         4,      // bDescriptorType
         0x00,   // bInterfaceNumber
@@ -595,7 +702,7 @@
         0x08,   // bInterfaceClass
         0x06,   // bInterfaceSubClass
         0x50,   // bInterfaceProtocol
-        0x04,   // iInterface
+        0x00,   // iInterface
 
         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
         7,                          // bLength
@@ -613,7 +720,45 @@
         0x02,                       // bmAttributes (0x02=bulk)
         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
-        0                           // bInterval
+        0,                           // bInterval
+
+        // interface 1: HID
+        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
+        INTERFACE_DESCRIPTOR,           // bDescriptorType
+        0x01,                           // bInterfaceNumber
+        0x00,                           // bAlternateSetting
+        0x02,                           // bNumEndpoints
+        HID_CLASS,                      // bInterfaceClass
+        HID_SUBCLASS_NONE,              // bInterfaceSubClass
+        HID_PROTOCOL_NONE,              // bInterfaceProtocol
+        0x00,                           // iInterface
+
+        HID_DESCRIPTOR_LENGTH,          // bLength
+        HID_DESCRIPTOR,                 // bDescriptorType
+        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
+        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
+        0x00,                           // bCountryCode
+        0x01,                           // bNumDescriptors
+        REPORT_DESCRIPTOR,              // bDescriptorType
+        LSB(this->reportDescLength()),  // wDescriptorLength (LSB)
+        MSB(this->reportDescLength()),  // wDescriptorLength (MSB)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        10,                             // bInterval (milliseconds)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        10,                             // bInterval (milliseconds)
+
     };
     return configDescriptor;
 }
--- a/USBMSD/USBMSD.h	Tue Nov 15 09:16:25 2011 +0000
+++ b/USBMSD/USBMSD.h	Wed Nov 16 11:06:27 2011 +0000
@@ -16,6 +16,7 @@
 #include "USBDevice_Types.h"
 
 #include "USBDevice.h"
+#include "USBHID.h"
 
 #define DEFAULT_CONFIGURATION (1)
 
@@ -59,7 +60,31 @@
     * @param product_id Your product_id
     * @param product_release Your preoduct_release
     */
-    USBMSD(uint16_t vendor_id = 0x0703, uint16_t product_id = 0x0104, uint16_t product_release = 0x0001);
+    USBMSD(uint16_t vendor_id = 0x0843, uint16_t product_id = 0x0154, uint16_t product_release = 0x0001);
+    
+    /**
+    * Send a Report
+    *
+    * @param report Report which will be sent (a report is defined by all data and the length)
+    * @returns true if successful
+    */
+    bool send(HID_REPORT *report);
+    
+    /**
+    * Read a report: blocking
+    *
+    * @param report pointer to the report to fill
+    * @returns true if successful
+    */
+    bool read(HID_REPORT * report);
+    
+    /**
+    * Read a report: non blocking
+    *
+    * @param report pointer to the report to fill
+    * @returns true if successful
+    */
+    bool readNB(HID_REPORT * report);
     
     /*
     * read a block on a storage chip
@@ -99,6 +124,20 @@
     virtual uint32_t memorySize(){return 0;};
     
     /*
+    * Get the Report descriptor
+    *
+    * @returns pointer to the report descriptor
+    */
+    virtual uint8_t * reportDesc();
+
+    /*
+    * Get the length of the report descriptor
+    *
+    * @returns the length of the report descriptor
+    */
+    virtual uint16_t reportDescLength();
+    
+    /*
     * Connect the USB MSD device. Establish disk initialization before really connect the device.
     *
     * @returns
@@ -107,6 +146,7 @@
     
     
 protected:
+    uint16_t reportLength;
 
 
     /*
@@ -199,6 +239,8 @@
     void memoryWrite (uint8_t * buf, uint16_t size);
     void reset();
     void fail();
+    
+    HID_REPORT outputReport;
 };
 
 #endif
--- a/main.cpp	Tue Nov 15 09:16:25 2011 +0000
+++ b/main.cpp	Wed Nov 16 11:06:27 2011 +0000
@@ -3,6 +3,18 @@
 
 SDFileSystem sd(p5, p6, p7, p8, "sd");
 
+//This report will contain data to be sent
+HID_REPORT send_report;
+
 int main() {
-    while(1);
+    //Fill the report
+    for(int i = 0; i < 64; i++)
+        send_report.data[i] = i;
+    send_report.length = 64;
+    
+    while (1) {
+        //Send the report
+        sd.send(&send_report);
+        wait(0.1);
+    }
 }
\ No newline at end of file