USB Composite support
Dependents: mbed_cdc_hid_composite
Fork of USBDevice by
Revision 55:7c559fcb1d17, committed 2015-05-31
- Comitter:
- steeven
- Date:
- Sun May 31 15:36:50 2015 +0000
- Parent:
- 54:461d954eee6b
- Commit message:
- Make USBDevice support Composite
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBComposite.cpp Sun May 31 15:36:50 2015 +0000 @@ -0,0 +1,214 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "stdint.h" +#include "USBComposite.h" + +#define DEFAULT_CONFIGURATION (1) + +USBComposite::USBComposite(bool connect_blocking, uint16_t vendor_id, uint16_t product_id , uint16_t product_release): + USBDevice(vendor_id, product_id, product_release) { +// USBDevice::connect(connect_blocking); +} + +bool USBComposite::USBCallback_request(void) { + /* Called in ISR context */ + uint8_t i; + + for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) { + if (_intfs[i] != NULL && _intfs[i]->USBCallback_request() == true) { + return true; + } + } + + return false; +} + +void USBComposite::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) { + /* Called in ISR context */ + uint8_t i; + + for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) { + if (_intfs[i] != NULL) { + _intfs[i]->USBCallback_requestCompleted(buf, length); + } + } +} + +// Called in ISR context +// Set configuration. Return false if the +// configuration is not supported. +bool USBComposite::USBCallback_setConfiguration(uint8_t configuration) { + if (configuration != DEFAULT_CONFIGURATION) { + return false; + } + +// // Configure endpoints > 0 +// _usb->addEndpoint(_ep_int_in, MAX_PACKET_SIZE_EPINT); +// _usb->addEndpoint(_ep_bulk_in, MAX_PACKET_SIZE_EPBULK); +// _usb->addEndpoint(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK); +// +// // We activate the endpoint to be able to recceive data +// _usb->readStart(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK); + return true; +} + +uint8_t * USBComposite::deviceDesc() { + static uint8_t deviceDescriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x10, 0x01, // bcdUSB + 2, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 + (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor + (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 3, // iSerialNumber + 1 // bNumConfigurations + }; + return deviceDescriptor; +} + +uint8_t * USBComposite::stringIinterfaceDesc() { + static uint8_t stringIinterfaceDescriptor[] = { + 0x08, + STRING_DESCRIPTOR, + 'C',0,'D',0,'C',0, + }; + return stringIinterfaceDescriptor; +} + +uint8_t * USBComposite::stringIproductDesc() { + static uint8_t stringIproductDescriptor[] = { + 0x16, + STRING_DESCRIPTOR, + 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 + }; + return stringIproductDescriptor; +} + + +#define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) + +uint8_t * USBComposite::configurationDesc() { + static uint8_t configDescriptor[] = { + // configuration descriptor + 9, // bLength + 2, // bDescriptorType + LSB(CONFIG1_DESC_SIZE), // wTotalLength + MSB(CONFIG1_DESC_SIZE), + 2, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0x80, // bmAttributes + 50, // bMaxPower + + // IAD to associate the two CDC interfaces + 0x08, // bLength + 0x0b, // bDescriptorType + 0x00, // bFirstInterface + 0x02, // bInterfaceCount + 0x02, // bFunctionClass + 0x02, // bFunctionSubClass + 0, // bFunctionProtocol + 0, // iFunction + + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + 0, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubClass + 0x01, // bInterfaceProtocol + 0, // iInterface + + // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x00, // bDescriptorSubtype + 0x10, 0x01, // bcdCDC + + // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x01, // bDescriptorSubtype + 0x03, // bmCapabilities + 1, // bDataInterface + + // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 + 4, // bFunctionLength + 0x24, // bDescriptorType + 0x02, // bDescriptorSubtype + 0x06, // bmCapabilities + + // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x06, // bDescriptorSubtype + 0, // bMasterInterface + 1, // bSlaveInterface0 + + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType +// PHY_TO_DESC(_ep_int_in), // bEndpointAddress + E_INTERRUPT, // bmAttributes (0x03=intr) + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 16, // bInterval + + + + + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + 1, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType +// PHY_TO_DESC(_ep_bulk_in), // bEndpointAddress + E_BULK, // bmAttributes (0x02=bulk) + LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) + 0, // bInterval + + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType +// PHY_TO_DESC(_ep_bulk_out), // bEndpointAddress + E_BULK, // bmAttributes (0x02=bulk) + LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) + 0 // bInterval + }; + return configDescriptor; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBComposite.h Sun May 31 15:36:50 2015 +0000 @@ -0,0 +1,93 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USBCOMPOSITE_H +#define USBCOMPOSITE_H + +/* These headers are included for child class. */ +#include "USBEndpoints.h" +#include "USBDescriptor.h" +#include "USBDevice_Types.h" + +#include "USBDevice.h" + +class USBComposite: public USBDevice{ +public: + + /* + * Constructor + * + * @param vendor_id Your vendor_id + * @param product_id Your product_id + * @param product_release Your preoduct_release + * @param connect_blocking define if the connection must be blocked if USB not plugged in + */ + USBComposite(bool connect_blocking = true, uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001); + + virtual bool bind(USBComposite *intf) { + uint8_t i; + for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) { + if (_intfs[i] == NULL){ + _intfs[i] = intf; + return true; + } + } + return false; + } + +protected: + + /* + * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength. + * + * @returns pointer to the device descriptor + */ + virtual uint8_t * deviceDesc(); + + /* + * Get string product descriptor + * + * @returns pointer to the string product descriptor + */ + virtual uint8_t * stringIproductDesc(); + + /* + * Get string interface descriptor + * + * @returns pointer to the string interface descriptor + */ + virtual uint8_t * stringIinterfaceDesc(); + + /* + * Get configuration descriptor + * + * @returns pointer to the configuration descriptor + */ + virtual uint8_t * configurationDesc(); + + +protected: + virtual bool USBCallback_request(); + virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length); + virtual bool USBCallback_setConfiguration(uint8_t configuration); + volatile bool terminal_connected; + + USBComposite* _intfs[4]; +}; + +#endif
--- a/USBDevice/USBDevice.cpp Fri May 22 08:45:47 2015 +0100 +++ b/USBDevice/USBDevice.cpp Sun May 31 15:36:50 2015 +0000 @@ -987,6 +987,8 @@ } uint8_t * USBDevice::stringIinterfaceDesc() { + if (_intf) + return _intf->stringIinterfaceDesc(); static uint8_t stringIinterfaceDescriptor[] = { 0x08, /*bLength*/ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ @@ -996,6 +998,8 @@ } uint8_t * USBDevice::stringIproductDesc() { + if (_intf) + return _intf->stringIproductDesc(); static uint8_t stringIproductDescriptor[] = { 0x16, /*bLength*/ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
--- a/USBDevice/USBDevice.h Fri May 22 08:45:47 2015 +0100 +++ b/USBDevice/USBDevice.h Sun May 31 15:36:50 2015 +0000 @@ -22,11 +22,13 @@ #include "mbed.h" #include "USBDevice_Types.h" #include "USBHAL.h" +#include "USBInterface.h" + class USBDevice: public USBHAL { public: - USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release); + USBDevice(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001); /* * Check if the device is configured @@ -126,6 +128,7 @@ */ virtual void USBCallback_busReset(void) {}; + /* * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context * This is used to handle extensions to standard requests @@ -133,7 +136,12 @@ * * @returns true if class handles this request */ - virtual bool USBCallback_request() { return false; }; + virtual bool USBCallback_request() { + if (_intf) + return _intf->USBCallback_request(); + else + return false; + }; /* * Called by USBDevice on Endpoint0 request completion @@ -145,7 +153,10 @@ * @param buf buffer received on endpoint 0 * @param length length of this buffer */ - virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {}; + virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) { + if (_intf) + _intf->USBCallback_requestCompleted(buf, length); + }; /* * Called by USBDevice layer. Set configuration of the device. @@ -153,7 +164,11 @@ * * @param configuration Number of the configuration */ - virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; }; + virtual bool USBCallback_setConfiguration(uint8_t configuration) { + if (_intf) + return _intf->USBCallback_setConfiguration(configuration); + return false; + }; /* * Called by USBDevice layer. Set interface/alternate of the device. @@ -176,7 +191,11 @@ * * @returns pointer to the configuration descriptor */ - virtual uint8_t * configurationDesc(){return NULL;}; + virtual uint8_t * configurationDesc(){ + if (_intf) + return _intf->configurationDesc(); + return NULL; + }; /* * Get string lang id descriptor @@ -227,7 +246,16 @@ */ virtual uint16_t reportDescLength() { return 0; }; + CONTROL_TRANSFER * getTransferPtr(void); + virtual bool bind(USBInterface *intf) { + _intf = intf; + return true; + } + + uint16_t VENDOR_ID; + uint16_t PRODUCT_ID; + uint16_t PRODUCT_RELEASE; protected: virtual void busReset(void); @@ -237,11 +265,7 @@ virtual void connectStateChanged(unsigned int connected); virtual void suspendStateChanged(unsigned int suspended); uint8_t * findDescriptor(uint8_t descriptorType); - CONTROL_TRANSFER * getTransferPtr(void); - uint16_t VENDOR_ID; - uint16_t PRODUCT_ID; - uint16_t PRODUCT_RELEASE; private: bool addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket); @@ -265,6 +289,8 @@ uint16_t currentInterface; uint8_t currentAlternate; + + USBInterface *_intf; };
--- a/USBDevice/USBHAL.h Fri May 22 08:45:47 2015 +0100 +++ b/USBDevice/USBHAL.h Sun May 31 15:36:50 2015 +0000 @@ -108,14 +108,24 @@ static void _usbisr(void); static USBHAL * instance; + #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549) bool (USBHAL::*epCallback[10 - 2])(void); #elif defined(TARGET_STM32F4) bool (USBHAL::*epCallback[8 - 2])(void); #else - bool (USBHAL::*epCallback[32 - 2])(void); + void *epCallbackObj[32 - 2]; + bool (*epCallback[32 - 2])(void *); #endif +public: + void set_ep_callback(uint8_t ep, void * obj, bool (*ptr)(void *)) { + if ((obj != NULL) && (ptr != NULL)) { + epCallback[ep] = ptr; + epCallbackObj[ep] = obj; + } + } + }; #endif
--- a/USBDevice/USBHAL_LPC17.cpp Fri May 22 08:45:47 2015 +0100 +++ b/USBDevice/USBHAL_LPC17.cpp Sun May 31 15:36:50 2015 +0000 @@ -329,6 +329,9 @@ NVIC_DisableIRQ(USB_IRQn); // fill in callback array + memset(epCallback, 0, sizeof(epCallback) * sizeof(void *)); + memset(epCallbackObj, 0, sizeof(epCallbackObj) * sizeof(void *)); + /* epCallback[0] = &USBHAL::EP1_OUT_callback; epCallback[1] = &USBHAL::EP1_IN_callback; epCallback[2] = &USBHAL::EP2_OUT_callback; @@ -359,6 +362,7 @@ epCallback[27] = &USBHAL::EP14_IN_callback; epCallback[28] = &USBHAL::EP15_OUT_callback; epCallback[29] = &USBHAL::EP15_IN_callback; + */ // Enable power to USB device controller LPC_SC->PCONP |= PCUSB; @@ -612,8 +616,11 @@ selectEndpointClearInterrupt(num); epComplete |= EP(num); LPC_USB->USBDevIntClr = EP_SLOW; - if ((instance->*(epCallback[num - 2]))()) { - epComplete &= ~EP(num); + + if (instance->epCallback[num - 2] != NULL){ + if (instance->epCallback[num - 2](instance->epCallbackObj[num - 2])) { + epComplete &= ~EP(num); + } } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice/USBInterface.h Sun May 31 15:36:50 2015 +0000 @@ -0,0 +1,84 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USINTERFACE_H +#define USINTERFACE_H + +#include "mbed.h" +#include "USBDevice_Types.h" +//#include "USBHAL.h" + +class USBInterface { +public: + USBInterface(){} + virtual ~USBInterface(){}; +// virtual int *endpoints(); + + /* + * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context + * This is used to handle extensions to standard requests + * and class specific requests + * + * @returns true if class handles this request + */ + virtual bool USBCallback_request() { return false; }; + + /* + * Called by USBDevice on Endpoint0 request completion + * if the 'notify' flag has been set to true. Warning: Called in ISR context + * + * In this case it is used to indicate that a HID report has + * been received from the host on endpoint 0 + * + * @param buf buffer received on endpoint 0 + * @param length length of this buffer + */ + virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {}; + + /* + * Get string interface descriptor + * + * @returns pointer to the string interface descriptor + */ + virtual uint8_t * stringIinterfaceDesc() { return (uint8_t *)NULL; } + + /* + * Get string product descriptor + * + * @returns pointer to the string product descriptor + */ + virtual uint8_t * stringIproductDesc() { return (uint8_t *)NULL; } + + /* + * Get configuration descriptor + * + * @returns pointer to the configuration descriptor + */ + virtual uint8_t * configurationDesc() { return (uint8_t *)NULL; } + + /* + * Called by USBDevice layer. Set configuration of the device. + * For instance, you can add all endpoints that you need on this function. + * + * @param configuration Number of the configuration + */ + virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; }; + +}; + +#endif
--- a/USBSerial/USBCDC.cpp Fri May 22 08:45:47 2015 +0100 +++ b/USBSerial/USBCDC.cpp Sun May 31 15:36:50 2015 +0000 @@ -33,16 +33,19 @@ #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK -USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) { +USBCDC::USBCDC(USBDevice *usb, uint8_t ep_int_in, uint8_t ep_bulk_in, uint8_t ep_bulk_out, bool connect_blocking): + _usb(usb), + _ep_int_in(ep_int_in), _ep_bulk_in(ep_bulk_in), _ep_bulk_out(ep_bulk_out) { terminal_connected = false; - USBDevice::connect(connect_blocking); + _usb->bind(this); + _usb->connect(connect_blocking); } bool USBCDC::USBCallback_request(void) { /* Called in ISR context */ bool success = false; - CONTROL_TRANSFER * transfer = getTransferPtr(); + CONTROL_TRANSFER * transfer = _usb->getTransferPtr(); /* Process class-specific requests */ @@ -81,7 +84,7 @@ return; } - CONTROL_TRANSFER * transfer = getTransferPtr(); + CONTROL_TRANSFER * transfer = _usb->getTransferPtr(); /* Process class-specific requests */ if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { @@ -110,31 +113,31 @@ } // Configure endpoints > 0 - addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); - addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); - addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); + _usb->addEndpoint(_ep_int_in, MAX_PACKET_SIZE_EPINT); + _usb->addEndpoint(_ep_bulk_in, MAX_PACKET_SIZE_EPBULK); + _usb->addEndpoint(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK); // We activate the endpoint to be able to recceive data - readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); + _usb->readStart(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK); return true; } bool USBCDC::send(uint8_t * buffer, uint32_t size) { - return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); + return _usb->write(_ep_bulk_in, buffer, size, MAX_CDC_REPORT_SIZE); } bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { - if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) + if (!_usb->readEP(_ep_bulk_out, buffer, size, MAX_CDC_REPORT_SIZE)) return false; - if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) + if (!_usb->readStart(_ep_bulk_out, MAX_CDC_REPORT_SIZE)) return false; return true; } bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { - if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) + if (!_usb->readEP_NB(_ep_bulk_out, buffer, size, MAX_CDC_REPORT_SIZE)) return false; - if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) + if (!_usb->readStart(_ep_bulk_out, MAX_CDC_REPORT_SIZE)) return false; return true; } @@ -149,8 +152,8 @@ 0, // bDeviceSubClass 0, // bDeviceProtocol MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 - (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor - (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct + (uint8_t)(LSB(_usb->VENDOR_ID)), (uint8_t)(MSB(_usb->VENDOR_ID)), // idVendor + (uint8_t)(LSB(_usb->PRODUCT_ID)), (uint8_t)(MSB(_usb->PRODUCT_ID)),// idProduct 0x00, 0x01, // bcdDevice 1, // iManufacturer 2, // iProduct @@ -244,7 +247,7 @@ // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 ENDPOINT_DESCRIPTOR_LENGTH, // bLength ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_IN), // bEndpointAddress + PHY_TO_DESC(_ep_int_in), // bEndpointAddress E_INTERRUPT, // bmAttributes (0x03=intr) LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) @@ -267,7 +270,7 @@ // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 ENDPOINT_DESCRIPTOR_LENGTH, // bLength ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPBULK_IN), // bEndpointAddress + PHY_TO_DESC(_ep_bulk_in), // bEndpointAddress E_BULK, // bmAttributes (0x02=bulk) LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) @@ -276,7 +279,7 @@ // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 ENDPOINT_DESCRIPTOR_LENGTH, // bLength ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress + PHY_TO_DESC(_ep_bulk_out), // bEndpointAddress E_BULK, // bmAttributes (0x02=bulk) LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
--- a/USBSerial/USBCDC.h Fri May 22 08:45:47 2015 +0100 +++ b/USBSerial/USBCDC.h Sun May 31 15:36:50 2015 +0000 @@ -26,7 +26,7 @@ #include "USBDevice.h" -class USBCDC: public USBDevice { +class USBCDC: public USBInterface { public: /* @@ -37,7 +37,7 @@ * @param product_release Your preoduct_release * @param connect_blocking define if the connection must be blocked if USB not plugged in */ - USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking); + USBCDC(USBDevice *usb, uint8_t ep_int_in, uint8_t ep_bulk_in, uint8_t ep_bulk_out, bool connect_blocking); protected: @@ -118,6 +118,15 @@ virtual bool USBCallback_setConfiguration(uint8_t configuration); volatile bool terminal_connected; + USBDevice *_usb; + + uint8_t _ep_int_in; //EPINT_IN + uint8_t _ep_bulk_in; //EPBULK_IN + uint8_t _ep_bulk_out; //EPBULK_OUT + + }; + + #endif
--- a/USBSerial/USBSerial.cpp Fri May 22 08:45:47 2015 +0100 +++ b/USBSerial/USBSerial.cpp Sun May 31 15:36:50 2015 +0000 @@ -16,6 +16,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #include "stdint.h" #include "USBSerial.h" @@ -33,7 +34,6 @@ return c; } - bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) { if(size > MAX_PACKET_SIZE_EPBULK) { return false; @@ -46,18 +46,19 @@ -bool USBSerial::EPBULK_OUT_callback() { +bool USBSerial::EP_OUT_callback(void *_self) { + USBSerial *self = (USBSerial *)_self; uint8_t c[65]; uint32_t size = 0; //we read the packet received and put it on the circular buffer - readEP(c, &size); + self->readEP(c, &size); for (uint32_t i = 0; i < size; i++) { - buf.queue(c[i]); + self->buf.queue(c[i]); } //call a potential handler - rx.call(); + self->rx.call(); return true; }
--- a/USBSerial/USBSerial.h Fri May 22 08:45:47 2015 +0100 +++ b/USBSerial/USBSerial.h Sun May 31 15:36:50 2015 +0000 @@ -56,8 +56,11 @@ * @param connect_blocking define if the connection must be blocked if USB not plugged in * */ - USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){ + + USBSerial(USBDevice *usb = new USBDevice(), bool connect_blocking = true, uint8_t ep_int_in = EPINT_IN, uint8_t ep_bulk_in = EPBULK_IN, uint8_t ep_bulk_out = EPBULK_OUT): + USBCDC(usb, ep_int_in, ep_bulk_in, ep_bulk_out, connect_blocking) { settingsChangedCallback = 0; + usb->set_ep_callback(ep_bulk_out, this, &USBSerial::EP_OUT_callback); }; @@ -145,13 +148,15 @@ } protected: - virtual bool EPBULK_OUT_callback(); + static bool EP_OUT_callback(void *self); + virtual void lineCodingChanged(int baud, int bits, int parity, int stop){ if (settingsChangedCallback) { settingsChangedCallback(baud, bits, parity, stop); } } + private: FunctionPointer rx; CircBuffer<uint8_t,128> buf;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readme.txt Sun May 31 15:36:50 2015 +0000 @@ -0,0 +1,22 @@ +UsbDeviceComposite + +!!! only tested CDC on LPC1768 +TODO: + 0. need to associate max packet length with endpoint + 1. Rework HID + 2. test Composite + 3. rework device... + 4. rework all HAL drivers + +Why not direct extend to USBDevice? + USBDevice has to be shared to multiple interfaces of a composite device +Why not multi-extend? + Some time need to implement 2 CDC or HIDs, can't extend twoice + +Composite Sample: + UsbComposite usb; + USBHID hid(&usb); + USBSerial ser(&usb); + +Single interface Sample: + USBHID hid;