adding additional features
Revision 0:2d90573426d7, committed 2013-06-26
- Comitter:
- sam_grove
- Date:
- Wed Jun 26 20:35:10 2013 +0000
- Commit message:
- add dynamic connection and terminal status feedback to the embedded application
Changed in this revision
diff -r 000000000000 -r 2d90573426d7 CircBuffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircBuffer.h Wed Jun 26 20:35:10 2013 +0000 @@ -0,0 +1,82 @@ +/* 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 CIRCBUFFER_H +#define CIRCBUFFER_H + +template <class T> +class CircBuffer +{ +public: + CircBuffer( int length ) + { + write = 0; + read = 0; + size = length + 1; + buf = ( T * )malloc( size * sizeof( T ) ); + }; + + bool isFull() + { + return ( ( write + 1 ) % size == read ); + }; + + bool isEmpty() + { + return ( read == write ); + }; + + void queue( T k ) + { + if ( isFull() ) + { + read++; + read %= size; + } + + buf[write++] = k; + write %= size; + } + + uint16_t available() + { + return ( write >= read ) ? write - read : size - read + write; + }; + + bool dequeue( T *c ) + { + bool empty = isEmpty(); + + if ( !empty ) + { + *c = buf[read++]; + read %= size; + } + + return( !empty ); + }; + +private: + volatile uint16_t write; + volatile uint16_t read; + uint16_t size; + T *buf; +}; + +#endif +
diff -r 000000000000 -r 2d90573426d7 USBCDC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBCDC.cpp Wed Jun 26 20:35:10 2013 +0000 @@ -0,0 +1,280 @@ +/* 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 "USBCDC.h" + +static uint8_t cdc_line_coding[7] = {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; +// baud[0,1] stop[x], parity[x], bits[6] + +#define DEFAULT_CONFIGURATION (1) + +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 + +#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK + +USBCDC::USBCDC( uint16_t vendor_id, uint16_t product_id, uint16_t product_release ): USBDevice( vendor_id, product_id, product_release ) +{ + // Moving this up into the USBSerial class + //USBDevice::connect(); + terminal_status = 0; +} + +uint8_t USBCDC::terminalIsOpen( void ) +{ + return ( terminal_status ) ? 1 : 0; +} + +bool USBCDC::USBCallback_request( void ) +{ + /* Called in ISR context */ + bool success = false; + CONTROL_TRANSFER *transfer = getTransferPtr(); + + /* Process class-specific requests */ + + if ( transfer->setup.bmRequestType.Type == CLASS_TYPE ) + { + switch ( transfer->setup.bRequest ) + { + case CDC_GET_LINE_CODING: + transfer->remaining = 7; + transfer->ptr = cdc_line_coding; + transfer->direction = DEVICE_TO_HOST; + success = true; + break; + + case CDC_SET_LINE_CODING: + transfer->remaining = 7; + success = true; + break; + + case CDC_SET_CONTROL_LINE_STATE: + // Look at DTR to determine if the terminal is opened on the PC + terminal_status = ( uint8_t )transfer->setup.wValue & 0x01; + success = true; + break; + + default: + break; + } + } + + return success; +} + + +// Called in ISR context +// Set configuration. Return false if the +// configuration is not supported. +bool USBCDC::USBCallback_setConfiguration( uint8_t configuration ) +{ + if ( configuration != DEFAULT_CONFIGURATION ) + { + return false; + } + + // Configure endpoints > 0 + addEndpoint( EPINT_IN, MAX_PACKET_SIZE_EPINT ); + addEndpoint( EPBULK_IN, MAX_PACKET_SIZE_EPBULK ); + addEndpoint( EPBULK_OUT, MAX_PACKET_SIZE_EPBULK ); + // We activate the endpoint to be able to recceive data + readStart( EPBULK_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 ); +} + +bool USBCDC::readEP( uint8_t *buffer, uint32_t *size ) +{ + if ( !USBDevice::readEP( EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE ) ) + { + return false; + } + + if ( !readStart( EPBULK_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 ) ) + { + return false; + } + + if ( !readStart( EPBULK_OUT, MAX_CDC_REPORT_SIZE ) ) + { + return false; + } + + return true; +} + + +uint8_t *USBCDC::deviceDesc() +{ + static uint8_t deviceDescriptor[] = + { + 18, // bLength + 1, // bDescriptorType + 0x10, 0x01, // bcdUSB + 2, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 + LSB( VENDOR_ID ), MSB( VENDOR_ID ), // idVendor + LSB( PRODUCT_ID ), MSB( PRODUCT_ID ), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 3, // iSerialNumber + 1 // bNumConfigurations + }; + return deviceDescriptor; +} + +uint8_t *USBCDC::stringIinterfaceDesc() +{ + static uint8_t stringIinterfaceDescriptor[] = + { + 0x08, + STRING_DESCRIPTOR, + 'C', 0, 'D', 0, 'C', 0, + }; + return stringIinterfaceDescriptor; +} + +uint8_t *USBCDC::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+9+5+5+4+5+7+9+7+7) + +uint8_t *USBCDC::configurationDesc() +{ + static uint8_t configDescriptor[] = + { + 9, // bLength; + 2, // bDescriptorType; + LSB( CONFIG1_DESC_SIZE ), // wTotalLength + MSB( CONFIG1_DESC_SIZE ), + 2, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0x80, // bmAttributes + 50, // bMaxPower + + // 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( EPINT_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 + 7, // bLength + 5, // bDescriptorType + PHY_TO_DESC( EPBULK_IN ), // bEndpointAddress + 0x02, // 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 + 7, // bLength + 5, // bDescriptorType + PHY_TO_DESC( EPBULK_OUT ), // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + LSB( MAX_PACKET_SIZE_EPBULK ), // wMaxPacketSize (LSB) + MSB( MAX_PACKET_SIZE_EPBULK ), // wMaxPacketSize (MSB) + 0 // bInterval + }; + return configDescriptor; +} +
diff -r 000000000000 -r 2d90573426d7 USBCDC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBCDC.h Wed Jun 26 20:35:10 2013 +0000 @@ -0,0 +1,115 @@ +/* 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 USBCDC_H +#define USBCDC_H + +/* These headers are included for child class. */ +#include "USBDevice/USBDevice/USBEndpoints.h" +#include "USBDevice/USBDevice/USBDescriptor.h" +#include "USBDevice/USBDevice/USBDevice_Types.h" + +#include "USBDevice/USBDevice/USBDevice.h" + +class USBCDC: public USBDevice +{ +private: + volatile uint8_t terminal_status; + +public: + + /* + * Constructor + * + * @param vendor_id Your vendor_id + * @param product_id Your product_id + * @param product_release Your preoduct_release + */ + USBCDC( uint16_t vendor_id, uint16_t product_id, uint16_t product_release ); + + uint8_t terminalIsOpen( void ); + +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(); + + /* + * Send a buffer + * + * @param endpoint endpoint which will be sent the buffer + * @param buffer buffer to be sent + * @param size length of the buffer + * @returns true if successful + */ + bool send( uint8_t *buffer, uint32_t size ); + + /* + * Read a buffer from a certain endpoint. Warning: blocking + * + * @param endpoint endpoint to read + * @param buffer buffer where will be stored bytes + * @param size the number of bytes read will be stored in *size + * @param maxSize the maximum length that can be read + * @returns true if successful + */ + bool readEP( uint8_t *buffer, uint32_t *size ); + + /* + * Read a buffer from a certain endpoint. Warning: non blocking + * + * @param endpoint endpoint to read + * @param buffer buffer where will be stored bytes + * @param size the number of bytes read will be stored in *size + * @param maxSize the maximum length that can be read + * @returns true if successful + */ + bool readEP_NB( uint8_t *buffer, uint32_t *size ); + + virtual bool USBCallback_request(); + virtual bool USBCallback_setConfiguration( uint8_t configuration ); + +}; + +#endif +
diff -r 000000000000 -r 2d90573426d7 USBSerial.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBSerial.cpp Wed Jun 26 20:35:10 2013 +0000 @@ -0,0 +1,151 @@ +/* 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 "USBSerial.h" +#include <stdarg.h> + +USBSerial::USBSerial( uint16_t vendor_id, uint16_t product_id, uint16_t product_release ) + : USBCDC( vendor_id, product_id, product_release ) + , buf( 128 ) +#ifdef USB_ERRATA_WORKAROUND + , _connect( P0_6 ) + , _vbus( P0_3 ) +#endif +{ +#ifdef USB_ERRATA_WORKAROUND + _connect = 1; +#endif + return; +} + +int USBSerial::_putc( int c ) +{ + send( ( uint8_t * )&c, 1 ); + return 1; +} + +int USBSerial::_getc() +{ + uint8_t c; + + while ( buf.isEmpty() ); + + buf.dequeue( &c ); + return c; +} + +void USBSerial::flush( void ) +{ + while( available() ) + { + _getc(); + } + + return; +} + +void USBSerial::printf( const char *format, ... ) +{ + static char buf[128]; + uint32_t len = 0; + va_list arg; + + if ( strlen( format ) < 64 ) + { + va_start( arg, format ); + vsprintf( buf, format, arg ); + va_end( arg ); + // write to the peripheral + len = strlen( buf ); + send( ( uint8_t * )buf, len ); + // and erase the buffer conents + memset( buf, 0, len ); + } + + return; +} + +bool USBSerial::writeBlock( uint8_t *buf, uint16_t size ) +{ + if( size > MAX_PACKET_SIZE_EPBULK ) + { + return false; + } + + if( !send( buf, size ) ) + { + return false; + } + + return true; +} + +bool USBSerial::writeBlock( const char *buf ) +{ + uint16_t cnt = 0; + + while( buf[cnt++] != 0 ); + + return writeBlock( ( uint8_t * )buf, cnt ); +} + +bool USBSerial::EP2_OUT_callback() +{ + uint8_t c[65]; + uint32_t size = 0; + //we read the packet received and put it on the circular buffer + readEP( c, &size ); + + for ( int i = 0; i < size; i++ ) + { + buf.queue( c[i] ); + } + + //call a potential handler + rx.call(); + // We reactivate the endpoint to receive next characters + readStart( EPBULK_OUT, MAX_PACKET_SIZE_EPBULK ); + return true; +} + +uint8_t USBSerial::available() +{ + return buf.available(); +} + +#ifdef USB_ERRATA_WORKAROUND +void USBSerial::connect( void ) +{ + _connect = 0; + USBHAL::connect(); + return; +} +void USBSerial::disconnect( void ) +{ + _connect = 1; + USBHAL::disconnect(); + return; +} +bool USBSerial::vbusDetected( void ) +{ + return _vbus; +} +#endif + +
diff -r 000000000000 -r 2d90573426d7 USBSerial.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBSerial.h Wed Jun 26 20:35:10 2013 +0000 @@ -0,0 +1,154 @@ +/* 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 USBSERIAL_H +#define USBSERIAL_H + +#include "USBCDC.h" +#include "Stream.h" +#include "CircBuffer.h" + + +/** +* USBSerial example +* +* @code +* #include "mbed.h" +* #include "USBSerial.h" +* +* //Virtual serial port over USB +* USBSerial serial; +* +* int main(void) { +* +* while(1) +* { +* serial.printf("I am a virtual serial port\n"); +* wait(1); +* } +* } +* @endcode +*/ +class USBSerial: public USBCDC//, public Stream +{ +public: + + /** + * Constructor + * + * @param vendor_id Your vendor_id (default: 0x1f00) + * @param product_id Your product_id (default: 0x2012) + * @param product_release Your preoduct_release (default: 0x0001) + * + */ + USBSerial( uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001 ); + + + /** + * Send a character. You can use puts, printf. + * + * @param c character to be sent + * @returns true if there is no error, false otherwise + */ + virtual int _putc( int c ); + + /** + * Read a character: blocking + * + * @returns character read + */ + virtual int _getc(); + + /** + * Check the number of bytes available. + * + * @returns the number of bytes available + */ + uint8_t available(); + + + /** + * Check the number of bytes available. + */ + void flush( void ); + + /** + * Write a block of data. + * + * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written. + * + * @param buf pointer on data which will be written + * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes) + * + * @returns true if successfull + */ + bool writeBlock( uint8_t *buf, uint16_t size ); + bool writeBlock( const char *buf ); + void printf( const char *format, ... ); + +#ifdef USB_ERRATA_WORKAROUND + void connect( void ); + void disconnect( void ); + bool vbusDetected( void ); +#endif + + /** + * Attach a member function to call when a packet is received. + * + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + */ + template<typename T> + void attach( T *tptr, void ( T::*mptr )( void ) ) + { + if( ( mptr != NULL ) && ( tptr != NULL ) ) + { + rx.attach( tptr, mptr ); + } + } + + /** + * Attach a callback called when a packet is received + * + * @param fptr function pointer + */ + void attach( void ( *fn )( void ) ) + { + if( fn != NULL ) + { + rx.attach( fn ); + } + } + + +protected: + virtual bool EP2_OUT_callback(); + +private: + FunctionPointer rx; + CircBuffer<uint8_t> buf; + +#ifdef USB_ERRATA_WORKAROUND + DigitalOut _connect; + DigitalIn _vbus; +#endif + +}; + +#endif +