ISP example program.

Dependencies:   SLCD mbed USBLocalFileSystem

/media/uploads/va009039/lpc81isp-360x240.jpg

FRDM-KL46ZLPC810
UART RXDPTE23p2(P0_4)
UART TXDPTE22p8(P0_0)
nRESETD6p1(P0_5)
nISPD8p5(P0_1)
GNDGNDp7
3.3VP3V3p6

Copy binary image to the disk called LPC81ISP.
Push sw1 or sw3, start write to LPC810 flash.

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Sun Feb 16 12:56:12 2014 +0000
Parent:
0:ad2b1fc04955
Child:
2:eafc1c6787c7
Commit message:
add virtual COM.

Changed in this revision

USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
USBMSD2/DiskInterface.h Show annotated file Show diff for this revision Revisions of this file
USBMSD2/SerialInterface.h Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USBMSD2.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USBMSD2.h Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_CDC.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_CDC.h Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_HID.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_HID.h Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_MSD.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD2/USB_MSD.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
src/Storage.h Show annotated file Show diff for this revision Revisions of this file
src/myqueue.h Show diff for this revision Revisions of this file
--- a/USBDevice.lib	Sat Feb 15 10:15:42 2014 +0000
+++ b/USBDevice.lib	Sun Feb 16 12:56:12 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/va009039/code/USBDevice/#1ad500eb1e69
+http://mbed.org/users/va009039/code/USBDevice/#6dcb8023e437
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/DiskInterface.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,49 @@
+// DiskInterface.h 2013/9/21
+#pragma once
+
+class DiskInterface {
+public:
+    /*
+    * read a block on a storage chip
+    *
+    * @param data pointer where will be stored read data
+    * @param block block number
+    * @returns 0 if successful
+    */
+    virtual int disk_read(uint8_t * data, uint64_t block) = 0;
+
+    /*
+    * write a block on a storage chip
+    *
+    * @param data data to write
+    * @param block block number
+    * @returns 0 if successful
+    */
+    virtual int disk_write(const uint8_t * data, uint64_t block) = 0;
+
+    /*
+    * Disk initilization
+    */
+    virtual int disk_initialize() = 0;
+
+    /*
+    * Return the number of blocks
+    *
+    * @returns number of blocks
+    */
+    virtual uint64_t disk_sectors() = 0;
+
+    /*
+    * Return memory size
+    *
+    * @returns memory size
+    */
+    virtual uint64_t disk_size() = 0;
+
+    /*
+    * To check the status of the storage chip
+    *
+    * @returns status: 0: OK, 1: disk not initialized, 2: no medium in the drive, 4: write protected
+    */
+    virtual int disk_status() = 0;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/SerialInterface.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,15 @@
+// SerialInterface.h 2013/9/22
+#pragma once
+
+class SerialInterface {
+public:
+    /** virtual COM to target
+     */
+    virtual void serial_send_to_target(int c) = 0;
+
+    /** target to virtual COM
+     */
+    virtual int serial_send_to_virtual_com(int c);
+    
+    virtual void serial_break();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USBMSD2.cpp	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,349 @@
+/* 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 "USBMSD2.h"
+#include "USB_MSD.h"
+#include "USB_CDC.h"
+#include "USB_HID.h"
+
+#if (DEBUG2 > 3)
+#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+#else
+#define USB_DBG(...) while(0)
+#endif
+
+#define DEFAULT_CONFIGURATION (1)
+
+USBMSD2::USBMSD2(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 
+    : USBDevice(vendor_id, product_id, product_release)
+{
+    USB_DBG("%p vid=%04x pid=%04x", this, vendor_id, product_id);
+
+    _msd = new USB_MSD(this, this);
+    _cdc = new USB_CDC(this);
+    _hid = new USB_HID(this);
+}
+
+USBMSD2::~USBMSD2() {
+    _msd->disconnect();
+    USBDevice::disconnect();
+}
+
+void USBMSD2::putc(int c)
+{
+    _cdc->putc(c);
+}
+
+int USBMSD2::getc()
+{
+    return _cdc->getc();
+}
+
+int USBMSD2::readable()
+{
+    return _cdc->readable();
+}
+    
+int USBMSD2::writeable()
+{
+    return _cdc->writeable();
+}
+
+bool USBMSD2::readNB(HID_REPORT* report)
+{
+    return _hid->readNB(report);
+}
+
+bool USBMSD2::send(HID_REPORT* report)
+{
+    return _hid->send(report);
+}
+
+bool USBMSD2::connect()
+{
+    if (_msd->connect()) {
+        USBDevice::connect();
+        return true;
+    }
+    return false;
+}
+
+// Called in ISR context to process a class specific request
+bool USBMSD2::USBCallback_request(void) {
+    CONTROL_TRANSFER* transfer = getTransferPtr();
+    if (_msd->Request_callback(transfer)) {
+        return true;
+    }
+    if (_cdc->Request_callback(transfer)) {
+        return true;
+    }
+    // Find the HID descriptor, after the configuration descriptor
+    uint8_t* hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+    if (_hid->Request_callback(transfer, hidDescriptor)) {
+        return true;
+    }
+    return false;
+}
+
+/* virtual */ void USBMSD2::USBCallback_requestCompleted(uint8_t* buf, uint32_t length)
+{
+    CONTROL_TRANSFER* transfer = getTransferPtr();
+    if (_cdc->RequestCompleted_callback(transfer, buf, length)) {
+        return;
+    }    
+}
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBMSD2::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure endpoints > 0
+    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    addEndpoint(CDC_EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(CDC_EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(HID_EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+    //activate readings
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    readStart(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+    return true;
+}
+
+/* virtual */ bool USBMSD2::EP2_OUT_callback()
+{
+    return _msd->EPBULK_OUT_callback();
+}
+
+/* virtual */ bool USBMSD2::EP2_IN_callback()  {
+    return _msd->EPBULK_IN_callback();
+}
+
+/* virtual */ bool USBMSD2::EP3_OUT_callback()
+{
+    return _cdc->EPBULK_OUT_callback();
+}
+
+/* virtual */ bool USBMSD2::EP5_OUT_callback()
+{
+    return _cdc->EPBULK_OUT_callback();
+}
+
+uint8_t * USBMSD2::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 * USBMSD2::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,               //bLength
+        STRING_DESCRIPTOR,  //bDescriptorType 0x03
+        'H',0,'I',0,'D',0,  //bString iInterface - HID
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBMSD2::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        32,                                                       //bLength
+        STRING_DESCRIPTOR,                                        //bDescriptorType 0x03
+        'K',0,'L',0,'2',0,'5',0,'Z',0,' ',0,'C',0,'M',0,'S',0,'I',0,'S',0,'-',0,'D',0,'A',0,'P',0 // KL25Z CMSIS-DAP
+    };
+    return stringIproductDescriptor;
+}
+
+uint8_t * USBMSD2::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // Configuration 1
+        9,      // bLength
+        2,      // bDescriptorType
+        LSB(122), // wTotalLength
+        MSB(122),
+        4,      // bNumInterfaces
+        1,      // bConfigurationValue: 0x01 is used to select this configuration
+        0x00,   // iConfiguration: no string to describe this configuration
+        0x80,   // bmAttributes
+        250,    // bMaxPower, device power consumption is 100 mA
+
+        // Interface 0, Alternate Setting 0, MSC Class
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        0,      // bInterfaceNumber
+        0,      // bAlternateSetting
+        2,      // bNumEndpoints
+        0x08,   // bInterfaceClass
+        0x06,   // bInterfaceSubClass
+        0x50,   // bInterfaceProtocol
+        0x04,   // iInterface
+
+        // 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
+        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(EPBULK_OUT),    // bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0,                          // bInterval
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        1,                      // 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
+        2,                      // 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
+        1,                      // bMasterInterface
+        2,                      // bSlaveInterface0
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(CDC_EPINT_IN),      // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes (0x03=intr)
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        2,                              // bInterval
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        2,                          // 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(CDC_EPBULK_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(CDC_EPBULK_OUT),// bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0,                          // bInterval
+
+        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
+        INTERFACE_DESCRIPTOR,           // bDescriptorType
+        3,                              // bInterfaceNumber
+        0,                              // bAlternateSetting
+        2,                              // bNumEndpoints
+        HID_CLASS,                      // bInterfaceClass
+        HID_SUBCLASS_NONE,              // bInterfaceSubClass
+        HID_PROTOCOL_NONE,              // bInterfaceProtocol
+        0,                              // iInterface
+
+        HID_DESCRIPTOR_LENGTH,          // bLength
+        HID_DESCRIPTOR,                 // bDescriptorType
+        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
+        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
+        0x00,                           // bCountryCode
+        1,                              // bNumDescriptors
+        REPORT_DESCRIPTOR,              // bDescriptorType
+        LSB(_hid->reportDescLength()),  // wDescriptorLength (LSB)
+        MSB(_hid->reportDescLength()),  // wDescriptorLength (MSB)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(HID_EPINT_IN),      // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        1,                              // bInterval (milliseconds)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(HID_EPINT_OUT),     // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        1,                              // bInterval (milliseconds)
+    };
+    return configDescriptor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USBMSD2.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,175 @@
+/* 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.
+*/
+
+#pragma once
+
+/* These headers are included for child class. */
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+#include "USBHID_Types.h"
+#include "USBDevice.h"
+#include "DiskInterface.h"
+
+/**
+ * USBMSD2 class: generic class in order to use all kinds of blocks storage chip
+ *
+ * Introduction
+ *
+ * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
+ * from a computer over USB. But this class doesn't work standalone, you need to subclass this class
+ * and define virtual functions which are called in USBMSD.
+ *
+ * How to use this class with your chip ?
+ *
+ * You have to inherit and define some pure virtual functions (mandatory step):
+ *   - virtual int disk_read(char * data, int block): function to read a block
+ *   - virtual int disk_write(const char * data, int block): function to write a block
+ *   - virtual int disk_initialize(): function to initialize the memory
+ *   - virtual int disk_sectors(): return the number of blocks
+ *   - virtual int disk_size(): return the memory size
+ *   - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
+ *
+ * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with
+ * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which
+ * will access the sd card. You can do a master/slave system using the disk_status method.
+ *
+ * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)
+ * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.
+ * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information
+ * such as the number of blocks and the memory size.
+ */
+class USB_MSD;
+class USB_CDC;
+class USB_HID;
+
+class USBMSD2: public DiskInterface, public USBDevice {
+public:
+    /**
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBMSD2(uint16_t vendor_id = 0x0d28, uint16_t product_id = 0x0204, uint16_t product_release = 0x0001);
+
+    /**
+    * Connect the USB MSD device. Establish disk initialization before really connect the device.
+    *
+    * @returns true if successful
+    */
+    bool connect();
+
+    /**
+    * Disconnect the USB MSD device.
+    */
+    void disconnect();
+    
+    /**
+    * Destructor
+    */
+    ~USBMSD2();
+    
+    /** target to virtual COM
+     */
+    void putc(int c);
+    
+    /** virtial COM to target
+     */
+    int getc();
+    int readable();
+    int writeable();
+
+
+    /**
+    * Read a report: non blocking
+    *
+    * @param report pointer to the report to fill
+    * @returns true if successful
+    */
+    bool readNB(HID_REPORT* report);
+
+    /**
+    * Send a Report. warning: blocking
+    *
+    * @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);
+
+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();
+
+    virtual bool EP2_OUT_callback(); // MSC Callback called when a packet is received
+    virtual bool EP2_IN_callback();  // MSC Callback called when a packet has been sent
+    virtual bool EP3_OUT_callback(); // CDC Callback called when a packet is received
+    virtual bool EP5_OUT_callback(); // CDC Callback called when a packet is received
+
+    /*
+    * Set configuration of device. Add endpoints
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+    /*
+    * Callback called to process class specific requests
+    */
+    virtual bool USBCallback_request();
+
+    /*
+    * 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);
+
+private:
+    USB_MSD* _msd;
+    USB_CDC* _cdc;
+    USB_HID* _hid;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_CDC.cpp	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,172 @@
+/* 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 "USB_CDC.h"
+
+#if (DEBUG2 > 3)
+#define CDC_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+#define CDC_DBG_HEX(A,B) while(0);
+#else
+#define CDC_DBG(...) while(0)
+#define CDC_DBG_HEX(A,B) while(0)
+#endif
+
+#define CDC_SET_LINE_CODING        0x20
+#define CDC_GET_LINE_CODING        0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+#define CDC_SEND_BREAK             0x23
+
+#define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
+
+USB_CDC::USB_CDC(USBDevice* device) : _device(device), _rx_buf(128)
+{
+    CDC_DBG("device=%p", device);
+
+    terminal_connected = false;
+    //USBDevice::connect();
+}
+
+void USB_CDC::putc(int c)
+{
+    if (terminal_connected) {
+        uint8_t buf[1];
+        buf[0] = c;
+        _device->write(CDC_EPBULK_IN, buf, sizeof(buf), MAX_CDC_REPORT_SIZE);
+    }
+}
+
+int USB_CDC::getc()
+{
+    uint8_t c = 0;
+    while (_rx_buf.isEmpty());
+    _rx_buf.dequeue(&c);
+    return c;
+}
+
+int USB_CDC::readable()
+{
+    return _rx_buf.available() > 0 ? 1 : 0;
+}
+
+int USB_CDC::writeable()
+{
+    return 1;
+}
+
+void USB_CDC::baud_callback(int baudrate)
+{
+    CDC_DBG("baudrate=%d", baudrate);
+}
+
+void USB_CDC::send_break_callback(uint16_t duration)
+{
+    CDC_DBG("duration=%04x", duration);
+}
+
+void USB_CDC::control_line_callback(int rts, int dtr)
+{
+    CDC_DBG("rts=%d, dtr=%d", rts, dtr);
+}
+
+bool USB_CDC::send(uint8_t * buffer, uint32_t size) {
+    return _device->write(CDC_EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
+}
+
+bool USB_CDC::readEP(uint8_t * buffer, uint32_t * size) {
+    if (!_device->readEP(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+        return false;
+    if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+bool USB_CDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
+    if (!_device->readEP_NB(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+        return false;
+    if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE))
+        return false;
+    return true;
+}
+
+bool USB_CDC::Request_callback(CONTROL_TRANSFER* transfer)
+{
+    static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+            case CDC_SET_LINE_CODING: // 0x20
+                transfer->remaining = 7;
+                transfer->notify = true;
+                terminal_connected = true;
+                return true;
+
+            case CDC_GET_LINE_CODING: // x021
+                transfer->remaining = 7;
+                transfer->ptr = cdc_line_coding;
+                transfer->direction = DEVICE_TO_HOST;
+                return true;
+
+            case CDC_SET_CONTROL_LINE_STATE: // 0x22
+                control_line_callback((transfer->setup.wValue>>1) & 1, (transfer->setup.wValue) & 1);
+                terminal_connected = false;
+                return true;
+            
+            case CDC_SEND_BREAK: // 0x23
+                send_break_callback(transfer->setup.wValue);
+                return true;
+        }
+    }
+    return false;
+}
+
+static uint32_t LD32(uint8_t* buf)
+{
+    return buf[0]|(buf[1]<<8)|(buf[2]<<16)|(buf[3]<<24);
+}
+
+bool USB_CDC::RequestCompleted_callback(CONTROL_TRANSFER* transfer, uint8_t* buf, int length)
+{
+    CDC_DBG("transer=%p", transfer);
+    int baudrate;
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+            case CDC_SET_LINE_CODING: // 0x20
+                baudrate = LD32(buf);
+                baud_callback(baudrate);
+                return true;
+        }
+    }
+    CDC_DBG_HEX((uint8_t*)transfer, sizeof(CONTROL_TRANSFER));
+    return false;           
+}
+
+bool USB_CDC::EPBULK_OUT_callback() // virtual COM to target
+{
+    uint8_t buf[MAX_CDC_REPORT_SIZE];
+    uint32_t size = 0;
+    //we read the packet received and put it on the circular buffer
+    _device->readEP(CDC_EPBULK_OUT, buf, &size, MAX_CDC_REPORT_SIZE);
+    CDC_DBG("size=%d", size);
+    for(int i = 0; i < size; i++) {
+        _rx_buf.queue(buf[i]);
+    }
+
+    // We reactivate the endpoint to receive next characters
+    _device->readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_CDC.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,100 @@
+/* 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.
+*/
+
+#pragma once
+
+#include "USBDevice.h"
+#include "CircBuffer.h"
+
+#if defined(TARGET_LPC1768)
+#define CDC_EPINT_IN   EP1IN
+#define CDC_EPBULK_IN  EP5IN 
+#define CDC_EPBULK_OUT EP5OUT
+#elif defined(TARGET_LPC1347)
+#define CDC_EPINT_IN   EP1IN
+#define CDC_EPBULK_IN  EP3IN 
+#define CDC_EPBULK_OUT EP3OUT
+#elif defined(TARGET_KL25Z)||defined(TARGET_KL46Z)
+#define CDC_EPINT_IN   EP1IN
+#define CDC_EPBULK_IN  EP5IN 
+#define CDC_EPBULK_OUT EP5OUT
+#else
+#error "target type error"
+#endif
+
+class USB_CDC {
+public:
+    USB_CDC(USBDevice* device);
+
+    /** target to virtual COM
+     */
+    void putc(int c);
+    
+    /** virtial COM to target
+     */
+    int getc();
+
+    int readable();
+    
+    int writeable();
+
+    void baud_callback(int baudrate);
+    void send_break_callback(uint16_t duration);
+    void control_line_callback(int rts, int dtr);
+
+    /*
+    * 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);
+
+    bool Request_callback(CONTROL_TRANSFER* transfer);
+    bool RequestCompleted_callback(CONTROL_TRANSFER* transfer, uint8_t* buf, int length);
+    bool EPBULK_OUT_callback();
+    
+private:
+    USBDevice* _device;
+    CircBuffer<uint8_t> _rx_buf;
+    volatile bool terminal_connected;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_HID.cpp	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,142 @@
+/* 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 "USB_HID.h"
+
+#if (DEBUG2 > 3)
+#define HID_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+#else
+#define HID_DBG(...) while(0)
+#endif
+
+USB_HID::USB_HID(USBDevice* device, uint8_t output_report_length, uint8_t input_report_length) : _device(device)
+{
+    HID_DBG("device=%p", device);
+
+    output_length = output_report_length;
+    input_length = input_report_length;
+}
+
+bool USB_HID::send(HID_REPORT *report)
+{
+    return _device->write(HID_EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+bool USB_HID::sendNB(HID_REPORT *report)
+{
+    return _device->writeNB(HID_EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
+}
+
+bool USB_HID::read(HID_REPORT *report)
+{
+    uint32_t bytesRead = 0;
+    bool result;
+    result = _device->readEP(HID_EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    if(!_device->readStart(HID_EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    report->length = bytesRead;
+    return result;
+}
+
+bool USB_HID::readNB(HID_REPORT *report)
+{
+    uint32_t bytesRead = 0;
+    bool result;
+    result = _device->readEP_NB(HID_EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
+    report->length = bytesRead;
+    if(!_device->readStart(HID_EPINT_OUT, MAX_HID_REPORT_SIZE))
+        return false;
+    return result;
+}
+
+/* virtual */ uint8_t * USB_HID::reportDesc() {
+    static uint8_t reportDescriptor[] = {
+        0x06, 0x00, 0xff,
+        0x09, 0x01,         // usage
+        0xA1, 0x01,         // Collection 0x01
+        0x15, 0x00,         // logical minimum = 0
+        0x26, 0xFF, 0x00,   // logical maximum = 255
+        0x75, 0x08,         // report size = 8 bits
+        0x95, 0x40,         // report count
+        0x09, 0x01,         // usage
+        0x81, 0x02,         // Input (array)
+        0x95, 0x40,         // report count
+        0x09, 0x01,         // usage
+        0x91, 0x02,         // Output (array)
+        0x95, 0x01,         // report count
+        0x09, 0x01,         // usage
+        0xb1, 0x02,
+        0xC0                // end collection
+    };
+    reportLength = sizeof(reportDescriptor);
+    return reportDescriptor;
+}
+
+/* virtual */ uint16_t USB_HID::reportDescLength() {
+    reportDesc();
+    return reportLength;
+}
+
+bool USB_HID::Request_callback(CONTROL_TRANSFER* transfer, 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)) {
+                            transfer->remaining = reportDescLength();
+                            transfer->ptr = reportDesc();
+                            transfer->direction = DEVICE_TO_HOST;
+                            return true;
+                        }
+                        break;
+                    case HID_DESCRIPTOR:
+                        if (hidDescriptor != NULL) {
+                            transfer->remaining = HID_DESCRIPTOR_LENGTH;
+                            transfer->ptr = hidDescriptor;
+                            transfer->direction = DEVICE_TO_HOST;
+                            return true;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+             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;
+                return true;
+        }
+    }
+    return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_HID.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,97 @@
+/* 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.
+*/
+
+#pragma once
+
+#include "USBHID_Types.h"
+#include "USBDevice.h"
+
+#define HID_EPINT_IN   EP4IN
+#define HID_EPINT_OUT  EP4OUT
+
+/** USB HID device for CMSIS-DAP
+ */
+class USB_HID {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param output_report_length Maximum length of a sent report (up to 64 bytes) (default: 64 bytes)
+    * @param input_report_length Maximum length of a received report (up to 64 bytes) (default: 64 bytes)
+    */
+    USB_HID(USBDevice* device, uint8_t output_report_length = 64, uint8_t input_report_length = 64);
+
+
+    /**
+    * Send a Report. warning: blocking
+    *
+    * @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);
+    
+    
+    /**
+    * Send a Report. warning: non blocking
+    *
+    * @param report Report which will be sent (a report is defined by all data and the length)
+    * @returns true if successful
+    */
+    bool sendNB(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);
+
+    /*
+    * Get the length of the report descriptor
+    *
+    * @returns the length of the report descriptor
+    */
+    virtual uint16_t reportDescLength();
+
+    bool Request_callback(CONTROL_TRANSFER* transfer, uint8_t* hidDescriptor);
+protected:
+    /*
+    * Get the Report descriptor
+    *
+    * @returns pointer to the report descriptor
+    */
+    virtual uint8_t * reportDesc();
+
+    uint16_t reportLength;
+
+private:
+    USBDevice* _device;
+    HID_REPORT outputReport;
+    uint8_t output_length;
+    uint8_t input_length;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_MSD.cpp	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,550 @@
+/* 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 "USB_MSD.h"
+
+#if (DEBUG2 > 3)
+#define MSD_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+#else
+#define MSD_DBG(...) while(0)
+#endif
+
+#define DISK_OK         0x00
+#define NO_INIT         0x01
+#define NO_DISK         0x02
+#define WRITE_PROTECT   0x04
+
+#define CBW_Signature   0x43425355
+#define CSW_Signature   0x53425355
+
+// SCSI Commands
+#define TEST_UNIT_READY            0x00
+#define REQUEST_SENSE              0x03
+#define FORMAT_UNIT                0x04
+#define INQUIRY                    0x12
+#define MODE_SELECT6               0x15
+#define MODE_SENSE6                0x1A
+#define START_STOP_UNIT            0x1B
+#define MEDIA_REMOVAL              0x1E
+#define READ_FORMAT_CAPACITIES     0x23
+#define READ_CAPACITY              0x25
+#define READ10                     0x28
+#define WRITE10                    0x2A
+#define VERIFY10                   0x2F
+#define READ12                     0xA8
+#define WRITE12                    0xAA
+#define MODE_SELECT10              0x55
+#define MODE_SENSE10               0x5A
+
+// MSC class specific requests
+#define MSC_REQUEST_RESET          0xFF
+#define MSC_REQUEST_GET_MAX_LUN    0xFE
+
+#define DEFAULT_CONFIGURATION (1)
+
+// max packet size
+#define MAX_PACKET  MAX_PACKET_SIZE_EPBULK
+
+// CSW Status
+enum Status {
+    CSW_PASSED,
+    CSW_FAILED,
+    CSW_ERROR,
+};
+
+USB_MSD::USB_MSD(USBDevice* device, DiskInterface* disk) : _device(device),_disk(disk)
+{
+    MSD_DBG("device=%p", device);
+
+    stage = READ_CBW;
+    memset((void *)&cbw, 0, sizeof(CBW));
+    memset((void *)&csw, 0, sizeof(CSW));
+    page = NULL;
+}
+
+bool USB_MSD::connect() {
+
+    //disk initialization
+    if (_disk->disk_status() & NO_INIT) {
+        if (_disk->disk_initialize()) {
+            return false;
+        }
+    }
+
+    // get number of blocks
+    BlockCount = _disk->disk_sectors();
+
+    // get memory size
+    MemorySize = _disk->disk_size();
+
+    if (BlockCount > 0) {
+        BlockSize = MemorySize / BlockCount;
+        if (BlockSize != 0) {
+            free(page);
+            page = (uint8_t *)malloc(BlockSize * sizeof(uint8_t));
+            if (page == NULL)
+                return false;
+        }
+    } else {
+        return false;
+    }
+    return true;
+}
+
+void USB_MSD::disconnect() {
+    //De-allocate MSD page size:
+    free(page);
+    page = NULL;
+}
+
+void USB_MSD::reset() {
+    stage = READ_CBW;
+}
+
+bool USB_MSD::Request_callback(CONTROL_TRANSFER* transfer)
+{
+    static uint8_t msc_maxLUN[1] = {0};
+    
+    if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+        switch (transfer->setup.bRequest) {
+            case MSC_REQUEST_RESET:
+                reset();
+                return true;
+
+            case MSC_REQUEST_GET_MAX_LUN:
+                transfer->remaining = 1;
+                transfer->ptr = msc_maxLUN;
+                transfer->direction = DEVICE_TO_HOST;
+                return true;
+        }
+    }
+    return false;
+}
+
+// Called in ISR context called when a data is received
+bool USB_MSD::EPBULK_OUT_callback() {
+    uint32_t size = 0;
+    uint8_t buf[MAX_PACKET_SIZE_EPBULK];
+    _device->readEP(EPBULK_OUT, buf, &size, MAX_PACKET_SIZE_EPBULK);
+    switch (stage) {
+            // the device has to decode the CBW received
+        case READ_CBW:
+            CBWDecode(buf, size);
+            break;
+
+            // the device has to receive data from the host
+        case PROCESS_CBW:
+            switch (cbw.CB[0]) {
+                case WRITE10:
+                case WRITE12:
+                    memoryWrite(buf, size);
+                    break;
+                case VERIFY10:
+                    memoryVerify(buf, size);
+                    break;
+            }
+            break;
+
+            // an error has occured: stall endpoint and send CSW
+        default:
+            _device->stallEndpoint(EPBULK_OUT);
+            csw.Status = CSW_ERROR;
+            sendCSW();
+            break;
+    }
+
+    //reactivate readings on the OUT bulk endpoint
+    _device->readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+// Called in ISR context when a data has been transferred
+bool USB_MSD::EPBULK_IN_callback() {
+    switch (stage) {
+
+            // the device has to send data to the host
+        case PROCESS_CBW:
+            switch (cbw.CB[0]) {
+                case READ10:
+                case READ12:
+                    memoryRead();
+                    break;
+            }
+            break;
+
+            //the device has to send a CSW
+        case SEND_CSW:
+            sendCSW();
+            break;
+
+        // the host has received the CSW -> we wait a CBW
+        case WAIT_CSW:
+            stage = READ_CBW;
+            break;
+
+        // an error has occured
+        default:
+            _device->stallEndpoint(EPBULK_IN);
+            sendCSW();
+            break;
+    }
+    return true;
+}
+
+void USB_MSD::memoryWrite (uint8_t * buf, uint16_t size) {
+
+    if ((addr + size) > MemorySize) {
+        size = MemorySize - addr;
+        stage = ERROR;
+        _device->stallEndpoint(EPBULK_OUT);
+    }
+
+    // we fill an array in RAM of 1 block before writing it in memory
+    for (int i = 0; i < size; i++)
+        page[addr%BlockSize + i] = buf[i];
+
+    // if the array is filled, write it in memory
+    if (!((addr + size)%BlockSize)) {
+        if (!(_disk->disk_status() & WRITE_PROTECT)) {
+            _disk->disk_write(page, addr/BlockSize);
+        }
+    }
+
+    addr += size;
+    length -= size;
+    csw.DataResidue -= size;
+
+    if ((!length) || (stage != PROCESS_CBW)) {
+        csw.Status = (stage == ERROR) ? CSW_FAILED : CSW_PASSED;
+        sendCSW();
+    }
+}
+
+void USB_MSD::memoryVerify (uint8_t * buf, uint16_t size) {
+    uint32_t n;
+
+    if ((addr + size) > MemorySize) {
+        size = MemorySize - addr;
+        stage = ERROR;
+        _device->stallEndpoint(EPBULK_OUT);
+    }
+
+    // beginning of a new block -> load a whole block in RAM
+    if (!(addr%BlockSize))
+        _disk->disk_read(page, addr/BlockSize);
+
+    // info are in RAM -> no need to re-read memory
+    for (n = 0; n < size; n++) {
+        if (page[addr%BlockSize + n] != buf[n]) {
+            memOK = false;
+            break;
+        }
+    }
+
+    addr += size;
+    length -= size;
+    csw.DataResidue -= size;
+
+    if ( !length || (stage != PROCESS_CBW)) {
+        csw.Status = (memOK && (stage == PROCESS_CBW)) ? CSW_PASSED : CSW_FAILED;
+        sendCSW();
+    }
+}
+
+bool USB_MSD::inquiryRequest (void) {
+    uint8_t inquiry[] = { 0x00, 0x80, 0x00, 0x01,
+                          36 - 4, 0x80, 0x00, 0x00,
+                          'M', 'B', 'E', 'D', '.', 'O', 'R', 'G',
+                          'M', 'B', 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', 'K', ' ', ' ', ' ',
+                          '1', '.', '0', ' ',
+                        };
+    if (!write(inquiry, sizeof(inquiry))) {
+        return false;
+    }
+    return true;
+}
+
+bool USB_MSD::readFormatCapacity() {
+    uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,
+                           (uint8_t)((BlockCount >> 24) & 0xff),
+                           (uint8_t)((BlockCount >> 16) & 0xff),
+                           (uint8_t)((BlockCount >> 8) & 0xff),
+                           (uint8_t)((BlockCount >> 0) & 0xff),
+
+                           0x02,
+                           (uint8_t)((BlockSize >> 16) & 0xff),
+                           (uint8_t)((BlockSize >> 8) & 0xff),
+                           (uint8_t)((BlockSize >> 0) & 0xff),
+                         };
+    if (!write(capacity, sizeof(capacity))) {
+        return false;
+    }
+    return true;
+}
+
+bool USB_MSD::readCapacity (void) {
+    uint8_t capacity[] = {
+        (uint8_t)(((BlockCount - 1) >> 24) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 16) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 8) & 0xff),
+        (uint8_t)(((BlockCount - 1) >> 0) & 0xff),
+
+        (uint8_t)((BlockSize >> 24) & 0xff),
+        (uint8_t)((BlockSize >> 16) & 0xff),
+        (uint8_t)((BlockSize >> 8) & 0xff),
+        (uint8_t)((BlockSize >> 0) & 0xff),
+    };
+    if (!write(capacity, sizeof(capacity))) {
+        return false;
+    }
+    return true;
+}
+
+bool USB_MSD::write (uint8_t * buf, uint16_t size) {
+
+    if (size >= cbw.DataLength) {
+        size = cbw.DataLength;
+    }
+    stage = SEND_CSW;
+
+    if (!_device->writeNB(EPBULK_IN, buf, size, MAX_PACKET_SIZE_EPBULK)) {
+        return false;
+    }
+
+    csw.DataResidue -= size;
+    csw.Status = CSW_PASSED;
+    return true;
+}
+
+bool USB_MSD::modeSense6 (void) {
+    uint8_t sense6[] = { 0x03, 0x00, 0x00, 0x00 };
+    if (!write(sense6, sizeof(sense6))) {
+        return false;
+    }
+    return true;
+}
+
+void USB_MSD::sendCSW() {
+    csw.Signature = CSW_Signature;
+    _device->writeNB(EPBULK_IN, (uint8_t *)&csw, sizeof(CSW), MAX_PACKET_SIZE_EPBULK);
+    stage = WAIT_CSW;
+}
+
+bool USB_MSD::requestSense (void) {
+    uint8_t request_sense[] = {
+        0x70,
+        0x00,
+        0x05,   // Sense Key: illegal request
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x0A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x30,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+    };
+
+    if (!write(request_sense, sizeof(request_sense))) {
+        return false;
+    }
+
+    return true;
+}
+
+void USB_MSD::fail() {
+    csw.Status = CSW_FAILED;
+    sendCSW();
+}
+
+void USB_MSD::CBWDecode(uint8_t * buf, uint16_t size) {
+    if (size == sizeof(cbw)) {
+        memcpy((uint8_t *)&cbw, buf, size);
+        if (cbw.Signature == CBW_Signature) {
+            csw.Tag = cbw.Tag;
+            csw.DataResidue = cbw.DataLength;
+            if ((cbw.CBLength <  1) || (cbw.CBLength > 16) ) {
+                fail();
+            } else {
+                switch (cbw.CB[0]) {
+                    case TEST_UNIT_READY:
+                        testUnitReady();
+                        break;
+                    case REQUEST_SENSE:
+                        requestSense();
+                        break;
+                    case INQUIRY:
+                        inquiryRequest();
+                        break;
+                    case MODE_SENSE6:
+                        modeSense6();
+                        break;
+                    case READ_FORMAT_CAPACITIES:
+                        readFormatCapacity();
+                        break;
+                    case READ_CAPACITY:
+                        readCapacity();
+                        break;
+                    case READ10:
+                    case READ12:
+                        if (infoTransfer()) {
+                            if ((cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                                memoryRead();
+                            } else {
+                                _device->stallEndpoint(EPBULK_OUT);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case WRITE10:
+                    case WRITE12:
+                        if (infoTransfer()) {
+                            if (!(cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                            } else {
+                                _device->stallEndpoint(EPBULK_IN);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case VERIFY10:
+                        if (!(cbw.CB[1] & 0x02)) {
+                            csw.Status = CSW_PASSED;
+                            sendCSW();
+                            break;
+                        }
+                        if (infoTransfer()) {
+                            if (!(cbw.Flags & 0x80)) {
+                                stage = PROCESS_CBW;
+                                memOK = true;
+                            } else {
+                                _device->stallEndpoint(EPBULK_IN);
+                                csw.Status = CSW_ERROR;
+                                sendCSW();
+                            }
+                        }
+                        break;
+                    case MEDIA_REMOVAL:
+                        csw.Status = CSW_PASSED;
+                        sendCSW();
+                        break;
+                    default:
+                        fail();
+                        break;
+                }
+            }
+        }
+    }
+}
+
+void USB_MSD::testUnitReady (void) {
+
+    if (cbw.DataLength != 0) {
+        if ((cbw.Flags & 0x80) != 0) {
+            _device->stallEndpoint(EPBULK_IN);
+        } else {
+            _device->stallEndpoint(EPBULK_OUT);
+        }
+    }
+
+    csw.Status = CSW_PASSED;
+    sendCSW();
+}
+
+void USB_MSD::memoryRead (void) {
+    uint32_t n;
+
+    n = (length > MAX_PACKET) ? MAX_PACKET : length;
+
+    if ((addr + n) > MemorySize) {
+        n = MemorySize - addr;
+        stage = ERROR;
+    }
+
+    // we read an entire block
+    if (!(addr%BlockSize))
+        _disk->disk_read(page, addr/BlockSize);
+
+    // write data which are in RAM
+    _device->writeNB(EPBULK_IN, &page[addr%BlockSize], n, MAX_PACKET_SIZE_EPBULK);
+
+    addr += n;
+    length -= n;
+
+    csw.DataResidue -= n;
+
+    if ( !length || (stage != PROCESS_CBW)) {
+        csw.Status = (stage == PROCESS_CBW) ? CSW_PASSED : CSW_FAILED;
+        stage = (stage == PROCESS_CBW) ? SEND_CSW : stage;
+    }
+}
+
+bool USB_MSD::infoTransfer (void) {
+    uint32_t n;
+
+    // Logical Block Address of First Block
+    n = (cbw.CB[2] << 24) | (cbw.CB[3] << 16) | (cbw.CB[4] <<  8) | (cbw.CB[5] <<  0);
+
+    addr = n * BlockSize;
+
+    // Number of Blocks to transfer
+    switch (cbw.CB[0]) {
+        case READ10:
+        case WRITE10:
+        case VERIFY10:
+            n = (cbw.CB[7] <<  8) | (cbw.CB[8] <<  0);
+            break;
+
+        case READ12:
+        case WRITE12:
+            n = (cbw.CB[6] << 24) | (cbw.CB[7] << 16) | (cbw.CB[8] <<  8) | (cbw.CB[9] <<  0);
+            break;
+    }
+
+    length = n * BlockSize;
+
+    if (!cbw.DataLength) {              // host requests no data
+        csw.Status = CSW_FAILED;
+        sendCSW();
+        return false;
+    }
+
+    if (cbw.DataLength != length) {
+        if ((cbw.Flags & 0x80) != 0) {
+            _device->stallEndpoint(EPBULK_IN);
+        } else {
+            _device->stallEndpoint(EPBULK_OUT);
+        }
+
+        csw.Status = CSW_FAILED;
+        sendCSW();
+        return false;
+    }
+
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD2/USB_MSD.h	Sun Feb 16 12:56:12 2014 +0000
@@ -0,0 +1,153 @@
+/* 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.
+*/
+
+#pragma once
+
+#include "USBDevice.h"
+#include "DiskInterface.h"
+
+// MSC class specific requests
+#define MSC_REQUEST_RESET          0xFF
+#define MSC_REQUEST_GET_MAX_LUN    0xFE
+
+/**
+ * USBMSD2 class: generic class in order to use all kinds of blocks storage chip
+ *
+ * Introduction
+ *
+ * The USBMSD implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
+ * from a computer over USB. But this class doesn't work standalone, you need to subclass this class
+ * and define virtual functions which are called in USBMSD.
+ *
+ * How to use this class with your chip ?
+ *
+ * You have to inherit and define some pure virtual functions (mandatory step):
+ *   - virtual int disk_read(char * data, int block): function to read a block
+ *   - virtual int disk_write(const char * data, int block): function to write a block
+ *   - virtual int disk_initialize(): function to initialize the memory
+ *   - virtual int disk_sectors(): return the number of blocks
+ *   - virtual int disk_size(): return the memory size
+ *   - virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
+ *
+ * All functions names are compatible with the fat filesystem library. So you can imagine using your own class with
+ * USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which
+ * will access the sd card. You can do a master/slave system using the disk_status method.
+ *
+ * Once these functions defined, you can call connect() (at the end of the constructor of your class for instance)
+ * of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk.
+ * If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information
+ * such as the number of blocks and the memory size.
+ */
+class USB_MSD {
+public:
+    USB_MSD(USBDevice* device, DiskInterface* disk);
+
+    /**
+    * Connect the USB MSD device. Establish disk initialization before really connect the device.
+    *
+    * @returns true if successful
+    */
+    bool connect();
+
+    /**
+    * Disconnect the USB MSD device.
+    */
+    void disconnect();
+    
+    /**
+    * Destructor
+    */
+    ~USB_MSD();
+
+    bool Request_callback(CONTROL_TRANSFER* transfer);
+    bool EPBULK_OUT_callback();
+    bool EPBULK_IN_callback();
+
+private:
+    USBDevice* _device;
+    DiskInterface* _disk;
+
+    // MSC Bulk-only Stage
+    enum Stage {
+        READ_CBW,     // wait a CBW
+        ERROR,        // error
+        PROCESS_CBW,  // process a CBW request
+        SEND_CSW,     // send a CSW
+        WAIT_CSW,     // wait that a CSW has been effectively sent
+    };
+
+    // Bulk-only CBW
+    typedef struct {
+        uint32_t Signature;
+        uint32_t Tag;
+        uint32_t DataLength;
+        uint8_t  Flags;
+        uint8_t  LUN;
+        uint8_t  CBLength;
+        uint8_t  CB[16];
+    } PACKED CBW;
+
+    // Bulk-only CSW
+    typedef struct {
+        uint32_t Signature;
+        uint32_t Tag;
+        uint32_t DataResidue;
+        uint8_t  Status;
+    } PACKED CSW;
+
+    //state of the bulk-only state machine
+    Stage stage;
+
+    // current CBW
+    CBW cbw;
+
+    // CSW which will be sent
+    CSW csw;
+
+    // addr where will be read or written data
+    uint32_t addr;
+
+    // length of a reading or writing
+    uint32_t length;
+
+    // memory OK (after a memoryVerify)
+    bool memOK;
+
+    // cache in RAM before writing in memory. Useful also to read a block.
+    uint8_t * page;
+
+    int BlockSize;
+    uint64_t MemorySize;
+    uint64_t BlockCount;
+
+    void reset();
+    void CBWDecode(uint8_t * buf, uint16_t size);
+    void sendCSW (void);
+    bool inquiryRequest (void);
+    bool write (uint8_t * buf, uint16_t size);
+    bool readFormatCapacity();
+    bool readCapacity (void);
+    bool infoTransfer (void);
+    void memoryRead (void);
+    bool modeSense6 (void);
+    void testUnitReady (void);
+    bool requestSense (void);
+    void memoryVerify (uint8_t * buf, uint16_t size);
+    void memoryWrite (uint8_t * buf, uint16_t size);
+    void fail();
+};
--- a/main.cpp	Sat Feb 15 10:15:42 2014 +0000
+++ b/main.cpp	Sun Feb 16 12:56:12 2014 +0000
@@ -1,3 +1,4 @@
+#ifdef TARGET_KL46Z
 #include "RamDisk.h"
 #include "Storage.h"
 #include "BaseLpcIsp.h"
@@ -42,7 +43,7 @@
     sw3.rise(swIRQ);
     
     RamDisk* ramdisk = new RamDisk;
-    USBStorage* usb = new USBStorage(ramdisk);
+    USBStorage2* usb = new USBStorage2(ramdisk);
     LocalStorage* local = NULL;
     slcd.puts("REDY");
     write_start = false;
@@ -63,6 +64,12 @@
             }    
             write_start = false;
         }
+        if (usb->readable()) {
+            lpc.putc(usb->getc());
+        }
+        if (lpc.readable()) {
+            usb->putc(lpc.getc());
+        }
         if (pc.readable()) {
             switch(pc.getc()) {
                 case 'd': ramdisk->dump(0); break;
@@ -72,3 +79,4 @@
         } 
     }
 }
+#endif
--- a/src/Storage.h	Sat Feb 15 10:15:42 2014 +0000
+++ b/src/Storage.h	Sun Feb 16 12:56:12 2014 +0000
@@ -2,6 +2,7 @@
 #include "mbed.h"
 #include "FATFileSystem.h"
 #include "USBMSD.h"
+#include "USBMSD2.h"
 #include "StorageInterface.h"
 #include "mystring.h"
 
@@ -42,3 +43,22 @@
     StorageInterface* _storage;
 };
 
+class USBStorage2 : public USBMSD2 {
+public:
+    USBStorage2(StorageInterface* storage): _storage(storage) {
+        connect();
+    }
+    virtual int disk_read(uint8_t * data, uint64_t block) {
+        return _storage->storage_read(data, block);
+    }
+    virtual int disk_write(const uint8_t * data, uint64_t block) {
+        return _storage->storage_write(data, block);
+    }
+    virtual int disk_initialize() { return _storage->storage_initialize(); }
+    virtual uint64_t disk_sectors() { return _storage->storage_sectors(); }
+    virtual uint64_t disk_size() { return _storage->storage_size(); }
+    virtual int disk_status() { return _storage->storage_status(); }
+
+private:
+    StorageInterface* _storage;
+};
--- a/src/myqueue.h	Sat Feb 15 10:15:42 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#pragma once
-
-template<class T>
-class myqueue {
-public:
-    myqueue() {
-        m_wpos = m_rpos = 0;
-        m_size = 0;
-        m_capacity = 0;
-    }
-    void push(T v) {
-        if (m_size >= m_capacity) { // resize
-            int new_capacity = m_capacity + 1;
-            T* new_buf = new T[new_capacity];
-            if (m_capacity > 0) {
-                for(int i = 0; i < m_size; i++) {
-                    new_buf[i] = m_buf[m_rpos++];
-                    if (m_rpos >= m_capacity) {
-                        m_rpos = 0;
-                    }
-                }
-                delete[] m_buf;
-            }
-            m_rpos = 0;
-            m_wpos = m_size;
-            m_buf = new_buf;
-            m_capacity = new_capacity;
-        }
-        m_buf[m_wpos++] = v;
-        if (m_wpos >= m_capacity) {
-            m_wpos = 0;
-        }
-        m_size++;
-    }
-    T pop() {
-        T v = m_buf[m_rpos++];
-        if (m_rpos >= m_capacity) {
-            m_rpos = 0;
-        }
-        m_size--;
-        return v;
-    }
-    bool empty() { return m_size == 0; }
-    int size() { return m_size; }
-
-private:
-    int m_capacity;
-    int m_size;
-    int m_wpos;
-    int m_rpos;
-    T *m_buf;
-};