USBMSD SD card Hello World for Mbed platforms
Dependencies: mbed USBMSD_SD USBDevice
Revision 10:cf8fd2b6ca23, committed 2011-11-16
- 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
--- 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
Samuel Mokrani