USB composite device example program, drag-and-drop flash writer.

Dependencies:   SWD USBDevice mbed BaseDAP

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Sat Sep 28 03:21:14 2013 +0000
Parent:
0:2385683c867a
Commit message:
add USBMSD_Drop class. add CDC(Virtual COM) and HID(for example CMSIS-DAP), but KL25Z not work.

Changed in this revision

RomDisk.cpp Show diff for this revision Revisions of this file
RomDisk.h Show diff for this revision Revisions of this file
RomDiskData.cpp Show diff for this revision Revisions of this file
Target2.cpp Show annotated file Show diff for this revision Revisions of this file
Target2.h Show annotated file Show diff for this revision Revisions of this file
USBMSD_Drop/RomDisk.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD_Drop/RomDisk.h Show annotated file Show diff for this revision Revisions of this file
USBMSD_Drop/RomDiskData.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD_Drop/USBMSD_Drop.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD_Drop/USBMSD_Drop.h Show annotated file Show diff for this revision Revisions of this file
USBMSD_LPC.cpp Show annotated file Show diff for this revision Revisions of this file
USBMSD_LPC.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
mydebug.h Show annotated file Show diff for this revision Revisions of this file
tests/BaseDAP.lib Show annotated file Show diff for this revision Revisions of this file
tests/BuildRomDisk.cpp Show diff for this revision Revisions of this file
tests/BuildRomDisk.h Show diff for this revision Revisions of this file
tests/RamDisk.cpp Show annotated file Show diff for this revision Revisions of this file
tests/RamDisk.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/DiskInterface.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/SerialInterface.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USBMSD2.cpp Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USBMSD2.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_CDC.cpp Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_CDC.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_HID.cpp Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_HID.h Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_MSD.cpp Show annotated file Show diff for this revision Revisions of this file
tests/USBMSD2/USB_MSD.h Show annotated file Show diff for this revision Revisions of this file
tests/mydebug.cpp Show annotated file Show diff for this revision Revisions of this file
tests/test2_USBMSD_Drop.cpp Show annotated file Show diff for this revision Revisions of this file
tests/test_BuildRomDisk.cpp Show annotated file Show diff for this revision Revisions of this file
tests/test_RomDisk.cpp Show annotated file Show diff for this revision Revisions of this file
tests/test_USBMSD2_HID.cpp Show annotated file Show diff for this revision Revisions of this file
tests/test_USBMSD_Drop.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 2385683c867a -r ea8e179320d7 RomDisk.cpp
--- a/RomDisk.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// RomDisk.cpp 2013/9/17
-#include "mbed.h"
-#include "RomDisk.h"
-
-RomDisk::RomDisk()
-{
-    _sectors = 128; // 64KB(512*128)
-}
-
-int RomDisk::read(uint8_t * data, uint32_t block)
-{
-    SectorIndex* p = const_cast<SectorIndex*>(sector_index);
-    while(p->data) {
-        if (p->block == block) {
-            memcpy(data, p->data, 512);
-            return 0;
-        }
-        p++;    
-    }
-    memset(data, 0x00, 512);
-    return 0;   
-}
-
-int RomDisk::write(const uint8_t * data, uint32_t block)
-{
-    return 0;
-}
-
-uint32_t RomDisk::sectors()
-{
-    return _sectors;
-}
-
-bool RomDisk::is_data(uint32_t block)
-{
-    return block >= 40;
-}
diff -r 2385683c867a -r ea8e179320d7 RomDisk.h
--- a/RomDisk.h	Tue Sep 17 04:33:44 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-// RomDisk.h 2013/9/17
-#pragma once
-
-struct SectorIndex {
-    int block;
-    const uint8_t* data;
-};
-
-extern const SectorIndex sector_index[]; // RomDiskData.cpp
-
-class RomDisk {
-public:
-    RomDisk();
-    int read(uint8_t * data, uint32_t block);
-    int write(const uint8_t * data, uint32_t block);
-    uint32_t sectors();
-    bool is_data(uint32_t block);
-protected:
-    uint64_t _sectors;
-};
diff -r 2385683c867a -r ea8e179320d7 RomDiskData.cpp
--- a/RomDiskData.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-// RomDiskData.cpp 2013/9/17
-#include "mbed.h"
-#include "RomDisk.h"
-
-const uint8_t sector_40[] = {
-0x3c,0x21,0x2d,0x2d,0x20,0x6d,0x62,0x65,0x64,0x20,0x4d,0x69,0x63,0x72,0x6f,0x63,
-0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x6c,0x65,0x72,0x20,0x57,0x65,0x62,0x73,0x69,0x74,
-0x65,0x20,0x61,0x6e,0x64,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,
-0x74,0x69,0x6f,0x6e,0x20,0x53,0x68,0x6f,0x72,0x74,0x63,0x75,0x74,0x20,0x2d,0x2d,
-0x3e,0x0d,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,
-0x3e,0x0d,0x0a,0x3c,0x6d,0x65,0x74,0x61,0x20,0x68,0x74,0x74,0x70,0x2d,0x65,0x71,
-0x75,0x69,0x76,0x3d,0x22,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x22,0x20,0x63,0x6f,
-0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x30,0x3b,0x20,0x75,0x72,0x6c,0x3d,0x68,0x74,
-0x74,0x70,0x3a,0x2f,0x2f,0x6d,0x62,0x65,0x64,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x6c,
-0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x2f,0x4c,0x50,0x43,0x31,0x31,0x31,0x34,0x46,
-0x4e,0x32,0x38,0x2f,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,
-0x6d,0x62,0x65,0x64,0x20,0x57,0x65,0x62,0x73,0x69,0x74,0x65,0x20,0x53,0x68,0x6f,
-0x72,0x74,0x63,0x75,0x74,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,
-0x2f,0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x3c,0x2f,
-0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,
-0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-const uint8_t sector_8[] = {
-0x4d,0x42,0x45,0x44,0x32,0x2e,0x30,0x20,0x20,0x20,0x20,0x08,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x67,0x30,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x4d,0x42,0x45,0x44,0x20,0x20,0x20,0x20,0x48,0x54,0x4d,0x20,0x18,0x38,0x48,0x67,
-0x30,0x43,0x30,0x43,0x00,0x00,0x6d,0x66,0x30,0x43,0x02,0x00,0xf2,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-const uint8_t sector_7[] = {
-0xf8,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-const uint8_t sector_6[] = {
-0xf8,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-const uint8_t sector_0[] = {
-0xeb,0x3c,0x90,0x4d,0x53,0x44,0x4f,0x53,0x35,0x2e,0x30,0x00,0x02,0x01,0x06,0x00,
-0x02,0x00,0x02,0x80,0x00,0xf8,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x82,0x14,0xf1,0x28,0x4e,0x4f,0x20,0x4e,0x41,
-0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xc9,
-0x8e,0xd1,0xbc,0xf0,0x7b,0x8e,0xd9,0xb8,0x00,0x20,0x8e,0xc0,0xfc,0xbd,0x00,0x7c,
-0x38,0x4e,0x24,0x7d,0x24,0x8b,0xc1,0x99,0xe8,0x3c,0x01,0x72,0x1c,0x83,0xeb,0x3a,
-0x66,0xa1,0x1c,0x7c,0x26,0x66,0x3b,0x07,0x26,0x8a,0x57,0xfc,0x75,0x06,0x80,0xca,
-0x02,0x88,0x56,0x02,0x80,0xc3,0x10,0x73,0xeb,0x33,0xc9,0x8a,0x46,0x10,0x98,0xf7,
-0x66,0x16,0x03,0x46,0x1c,0x13,0x56,0x1e,0x03,0x46,0x0e,0x13,0xd1,0x8b,0x76,0x11,
-0x60,0x89,0x46,0xfc,0x89,0x56,0xfe,0xb8,0x20,0x00,0xf7,0xe6,0x8b,0x5e,0x0b,0x03,
-0xc3,0x48,0xf7,0xf3,0x01,0x46,0xfc,0x11,0x4e,0xfe,0x61,0xbf,0x00,0x00,0xe8,0xe6,
-0x00,0x72,0x39,0x26,0x38,0x2d,0x74,0x17,0x60,0xb1,0x0b,0xbe,0xa1,0x7d,0xf3,0xa6,
-0x61,0x74,0x32,0x4e,0x74,0x09,0x83,0xc7,0x20,0x3b,0xfb,0x72,0xe6,0xeb,0xdc,0xa0,
-0xfb,0x7d,0xb4,0x7d,0x8b,0xf0,0xac,0x98,0x40,0x74,0x0c,0x48,0x74,0x13,0xb4,0x0e,
-0xbb,0x07,0x00,0xcd,0x10,0xeb,0xef,0xa0,0xfd,0x7d,0xeb,0xe6,0xa0,0xfc,0x7d,0xeb,
-0xe1,0xcd,0x16,0xcd,0x19,0x26,0x8b,0x55,0x1a,0x52,0xb0,0x01,0xbb,0x00,0x00,0xe8,
-0x3b,0x00,0x72,0xe8,0x5b,0x8a,0x56,0x24,0xbe,0x0b,0x7c,0x8b,0xfc,0xc7,0x46,0xf0,
-0x3d,0x7d,0xc7,0x46,0xf4,0x29,0x7d,0x8c,0xd9,0x89,0x4e,0xf2,0x89,0x4e,0xf6,0xc6,
-0x06,0x96,0x7d,0xcb,0xea,0x03,0x00,0x00,0x20,0x0f,0xb6,0xc8,0x66,0x8b,0x46,0xf8,
-0x66,0x03,0x46,0x1c,0x66,0x8b,0xd0,0x66,0xc1,0xea,0x10,0xeb,0x5e,0x0f,0xb6,0xc8,
-0x4a,0x4a,0x8a,0x46,0x0d,0x32,0xe4,0xf7,0xe2,0x03,0x46,0xfc,0x13,0x56,0xfe,0xeb,
-0x4a,0x52,0x50,0x06,0x53,0x6a,0x01,0x6a,0x10,0x91,0x8b,0x46,0x18,0x96,0x92,0x33,
-0xd2,0xf7,0xf6,0x91,0xf7,0xf6,0x42,0x87,0xca,0xf7,0x76,0x1a,0x8a,0xf2,0x8a,0xe8,
-0xc0,0xcc,0x02,0x0a,0xcc,0xb8,0x01,0x02,0x80,0x7e,0x02,0x0e,0x75,0x04,0xb4,0x42,
-0x8b,0xf4,0x8a,0x56,0x24,0xcd,0x13,0x61,0x61,0x72,0x0b,0x40,0x75,0x01,0x42,0x03,
-0x5e,0x0b,0x49,0x75,0x06,0xf8,0xc3,0x41,0xbb,0x00,0x00,0x60,0x66,0x6a,0x00,0xeb,
-0xb0,0x4e,0x54,0x4c,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0d,0x0a,0x52,0x65,
-0x6d,0x6f,0x76,0x65,0x20,0x64,0x69,0x73,0x6b,0x73,0x20,0x6f,0x72,0x20,0x6f,0x74,
-0x68,0x65,0x72,0x20,0x6d,0x65,0x64,0x69,0x61,0x2e,0xff,0x0d,0x0a,0x44,0x69,0x73,
-0x6b,0x20,0x65,0x72,0x72,0x6f,0x72,0xff,0x0d,0x0a,0x50,0x72,0x65,0x73,0x73,0x20,
-0x61,0x6e,0x79,0x20,0x6b,0x65,0x79,0x20,0x74,0x6f,0x20,0x72,0x65,0x73,0x74,0x61,
-0x72,0x74,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0xcb,0xd8,0x55,0xaa,
-};
-const SectorIndex sector_index[] = {
-{40, sector_40},
-{8, sector_8},
-{7, sector_7},
-{6, sector_6},
-{0, sector_0},
-{-1, NULL},
-};
diff -r 2385683c867a -r ea8e179320d7 Target2.cpp
--- a/Target2.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/Target2.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,4 +1,4 @@
-// Target2.cpp 2013/9/17
+// Target2.cpp 2013/9/23
 #include "Target2.h"
 #include "mydebug.h"
 
@@ -18,7 +18,17 @@
 #define FP_COMP0 (0xE0002008)
 
 Target2::Target2(PinName swdio, PinName swclk, PinName reset)
-    : _swd(swdio, swclk, reset)
+{
+    _swd = new SWD(swdio, swclk, reset);
+    inst();
+}
+
+Target2::Target2(SWD* swd) : _swd(swd)
+{
+    inst();
+}
+
+void Target2::inst()
 {
     r0.setup(this, 0);
     r1.setup(this, 1);
@@ -41,47 +51,46 @@
 
 bool Target2::setup()
 {
-    _swd.Setup();
+    _swd->Setup();
     JTAG2SWD();
     
     uint32_t data;
-    uint8_t ack = _swd.Transfer(DP_IDCODE, &data);
+    uint8_t ack = _swd->Transfer(DP_IDCODE, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
     idcode = data;
-    //TEST_ASSERT(data == 0x0bb11477);
 
     Abort();
 
     data = 0x0;
-    ack = _swd.Transfer(DP_SELECT, &data);
+    ack = _swd->Transfer(DP_SELECT, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
-    ack = _swd.Transfer(DP_RDBUFF, &data);
+    ack = _swd->Transfer(DP_RDBUFF, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
     data = CSYSPWRUPREQ | CDBGPWRUPREQ;
-    ack = _swd.Transfer(DP_CTRL_STAT, &data);
+    ack = _swd->Transfer(DP_CTRL_STAT, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
-    ack = _swd.Transfer(DP_RDBUFF, &data);
+    ack = _swd->Transfer(DP_RDBUFF, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
-    ack = _swd.Transfer(DP_CTRL_STAT_R, &data);
+    ack = _swd->Transfer(DP_CTRL_STAT_R, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
@@ -89,26 +98,26 @@
     TEST_ASSERT(data == 0xf0000040);
 
     data = CSYSPWRUPREQ | CDBGPWRUPREQ | 0x04000000;
-    ack = _swd.Transfer(DP_CTRL_STAT, &data);
+    ack = _swd->Transfer(DP_CTRL_STAT, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
-    ack = _swd.Transfer(DP_RDBUFF, &data);
+    ack = _swd->Transfer(DP_RDBUFF, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
     data = CSYSPWRUPREQ | CDBGPWRUPREQ | MASKLANE;
-    ack = _swd.Transfer(DP_CTRL_STAT, &data);
+    ack = _swd->Transfer(DP_CTRL_STAT, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
     }
 
-    ack = _swd.Transfer(DP_RDBUFF, &data);
+    ack = _swd->Transfer(DP_RDBUFF, &data);
     TEST_ASSERT(ack == SWD_OK);
     if (ack != SWD_OK) {
         return false;
@@ -118,7 +127,7 @@
 
 void Target2::SWJClock(uint32_t clock_hz)
 {
-    _swd.SWJClock(clock_hz);
+    _swd->SWJClock(clock_hz);
 }
 
 void Target2::JTAG2SWD()
@@ -126,16 +135,16 @@
     const uint8_t data1[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff};
     const uint8_t data2[] = {0x9e,0xe7};
     const uint8_t data3[] = {0x00};
-    _swd.SWJSequence(sizeof(data1)*8, data1);
-    _swd.SWJSequence(sizeof(data2)*8, data2);
-    _swd.SWJSequence(sizeof(data1)*8, data1);
-    _swd.SWJSequence(sizeof(data3)*8, data3);
+    _swd->SWJSequence(sizeof(data1)*8, data1);
+    _swd->SWJSequence(sizeof(data2)*8, data2);
+    _swd->SWJSequence(sizeof(data1)*8, data1);
+    _swd->SWJSequence(sizeof(data3)*8, data3);
 }
 
 void Target2::HardwareReset()
 {
-    _swd.SWJPins(0x00, 0x80); // nReset off
-    _swd.SWJPins(0x80, 0x80); // nReset on
+    _swd->SWJPins(0x00, 0x80); // nReset off
+    _swd->SWJPins(0x80, 0x80); // nReset on
 }
 
 void Target2::SoftwareReset()
@@ -148,10 +157,10 @@
     _setaddr(addr);
 
     uint32_t data;
-    uint8_t ack = _swd.Transfer(AP_DRW_R, &data); // dummy read
+    uint8_t ack = _swd->Transfer(AP_DRW_R, &data); // dummy read
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, &data);
+    ack = _swd->Transfer(DP_RDBUFF, &data);
     TEST_ASSERT(ack == SWD_OK);
     return data;
 }
@@ -164,14 +173,14 @@
 
     _setaddr(addr);
     
-    uint8_t ack = _swd.Transfer(AP_DRW_R, NULL); // dummy read
+    uint8_t ack = _swd->Transfer(AP_DRW_R, NULL); // dummy read
     TEST_ASSERT(ack == SWD_OK);
 
     for(int i = 0; i < count-1; i++) {
-        ack = _swd.Transfer(AP_DRW_R, data++);
+        ack = _swd->Transfer(AP_DRW_R, data++);
         TEST_ASSERT(ack == SWD_OK);
     }
-    ack = _swd.Transfer(DP_RDBUFF, data);
+    ack = _swd->Transfer(DP_RDBUFF, data);
     TEST_ASSERT(ack == SWD_OK);
 }
 
@@ -185,7 +194,7 @@
     _setaddr(addr);
 
     while(count-- > 0) {
-        uint8_t ack = _swd.Transfer(AP_DRW_W, data);
+        uint8_t ack = _swd->Transfer(AP_DRW_W, data);
         TEST_ASSERT(ack == SWD_OK);
         data++;
     }
@@ -196,10 +205,10 @@
     _setaddr8(addr);
 
     uint32_t data32;
-    uint8_t ack = _swd.Transfer(AP_DRW_R, &data32); // dummy read
+    uint8_t ack = _swd->Transfer(AP_DRW_R, &data32); // dummy read
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, &data32);
+    ack = _swd->Transfer(DP_RDBUFF, &data32);
     TEST_ASSERT(ack == SWD_OK);
     return (data32 >> ((addr & 0x03) << 3)) & 0xff;
 }
@@ -210,46 +219,46 @@
 
     uint32_t data32 = data;
     data32 <<= ((addr & 0x03) << 3);
-    uint8_t ack = _swd.Transfer(AP_DRW_W, &data32);
+    uint8_t ack = _swd->Transfer(AP_DRW_W, &data32);
     TEST_ASSERT(ack == SWD_OK);
 }
 
 void Target2::_setaddr(uint32_t addr)
 {
     uint32_t ctl = CSW_VALUE|CSW_SIZE32;
-    uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
+    uint8_t ack = _swd->Transfer(AP_CSW, &ctl);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, NULL);
+    ack = _swd->Transfer(DP_RDBUFF, NULL);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(AP_TAR, &addr);
+    ack = _swd->Transfer(AP_TAR, &addr);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, NULL);
+    ack = _swd->Transfer(DP_RDBUFF, NULL);
     TEST_ASSERT(ack == SWD_OK);
 } 
 
 void Target2::_setaddr8(uint32_t addr)
 {
     uint32_t ctl = CSW_VALUE|CSW_SIZE8;
-    uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
+    uint8_t ack = _swd->Transfer(AP_CSW, &ctl);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, NULL);
+    ack = _swd->Transfer(DP_RDBUFF, NULL);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(AP_TAR, &addr);
+    ack = _swd->Transfer(AP_TAR, &addr);
     TEST_ASSERT(ack == SWD_OK);
 
-    ack = _swd.Transfer(DP_RDBUFF, NULL);
+    ack = _swd->Transfer(DP_RDBUFF, NULL);
     TEST_ASSERT(ack == SWD_OK);
 } 
 
 void Target2::Abort()
 {
     uint32_t data = 0x1e;
-    uint8_t ack = _swd.Transfer(DP_ABORT, &data);
+    uint8_t ack = _swd->Transfer(DP_ABORT, &data);
     TEST_ASSERT(ack == SWD_OK);
 }
 
diff -r 2385683c867a -r ea8e179320d7 Target2.h
--- a/Target2.h	Tue Sep 17 04:33:44 2013 +0000
+++ b/Target2.h	Sat Sep 28 03:21:14 2013 +0000
@@ -1,4 +1,4 @@
-// Target2.h 2013/9/17
+// Target2.h 2013/9/23
 #pragma once
 #include "mbed.h"
 #include "SWD.h"
@@ -41,6 +41,11 @@
      * @param reset reset pin
      */
     Target2(PinName swdio, PinName swclk, PinName reset);
+
+    /** create target MCU interface
+     * @param swd SWD interface
+     */
+    Target2(SWD* swd);
     bool setup();
     void SWJClock(uint32_t clock_hz);
     uint32_t readMemory(uint32_t addr);
@@ -81,9 +86,10 @@
     
     uint32_t idcode;
 protected:
+    void inst();
     void _setaddr(uint32_t addr); 
     void _setaddr8(uint32_t addr); 
     void JTAG2SWD();
 
-    SWD _swd;
+    SWD* _swd;
 };
diff -r 2385683c867a -r ea8e179320d7 USBMSD_Drop/RomDisk.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD_Drop/RomDisk.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,55 @@
+// RomDisk.cpp 2013/9/26
+#include "mbed.h"
+#include "RomDisk.h"
+
+RomDisk::RomDisk()
+{
+    _sectors = 128; // 64KB(512*128)
+}
+
+int RomDisk::read(uint8_t * data, uint32_t block)
+{
+    SectorIndex* p = const_cast<SectorIndex*>(sector_index);
+    while(p->data) {
+        if (p->block == block) {
+            memcpy(data, p->data, 512);
+            return 0;
+        }
+        p++;    
+    }
+    memset(data, 0x00, 512);
+    return 0;   
+}
+
+int RomDisk::write(const uint8_t * data, uint32_t block)
+{
+    return 0;
+}
+
+uint32_t RomDisk::sectors()
+{
+    return _sectors;
+}
+
+bool RomDisk::is_fat(uint32_t sector)
+{
+    return sector >= 6 && sector <= 7;
+}
+
+bool RomDisk::is_rootdir(uint32_t sector)
+{
+    return sector >= 8 && sector <= 15;
+}
+
+int RomDisk::dir_count(uint32_t sector)
+{
+    if (!is_rootdir(sector)) {
+        return -1;
+    }
+    return sector - 8;
+}
+
+uint32_t RomDisk::cluster_to_sector(uint32_t cluster)
+{
+    return cluster + 38;
+}
diff -r 2385683c867a -r ea8e179320d7 USBMSD_Drop/RomDisk.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD_Drop/RomDisk.h	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,65 @@
+// RomDisk.h 2013/9/26
+#pragma once
+
+#define ATTR_READ_ONLY 0x01
+#define ATTR_HIDDEN    0x02
+#define ATTR_SYSTEM    0x04
+#define ATTR_VOLUME_ID 0x08
+#define ATTR_DIRECTORY 0x10
+#define ATTR_ARCHIVE   0x20
+#define ATTR_LONG_NAME (ATTR_READ_ONLY|ATTR_HIDDEN|ATTR_SYSTEM|ATTR_VOLUME_ID)
+
+struct DirEntry {
+    uint8_t name[8+3];
+    uint8_t attr;
+    uint8_t NTres;
+    uint8_t cDateTime_ms;
+    uint16_t cTime;
+    uint16_t cDate;
+    uint16_t aDate;
+    uint16_t clusterHI;
+    uint16_t mTime;
+    uint16_t mDate;
+    uint16_t cluster;
+    uint32_t size;
+    bool is_free() {
+        return name[0] == 0xe5 || name[0] == 0x00;
+    }
+    bool is_file() {
+        return is_free() == false && attr == ATTR_ARCHIVE;
+    }
+    int cmpDateTime(DirEntry* entry) {
+        if (mDate > entry->mDate) {
+            return 1;
+        } else if (mDate < entry->mDate) {
+            return -1;
+        }
+        if (mTime > entry->mTime) {
+            return 1;
+        } else if (mTime < entry->mTime) {
+            return -1;
+        }
+        return 0;
+    }
+} __attribute__((__packed__));;
+
+struct SectorIndex {
+    int block;
+    const uint8_t* data;
+};
+
+extern const SectorIndex sector_index[]; // RomDiskData.cpp
+
+class RomDisk {
+public:
+    RomDisk();
+    int read(uint8_t * data, uint32_t block);
+    int write(const uint8_t * data, uint32_t block);
+    uint32_t sectors();
+    bool is_fat(uint32_t sector);
+    bool is_rootdir(uint32_t sector);
+    int dir_count(uint32_t sector);
+    uint32_t cluster_to_sector(uint32_t cluster);
+protected:
+    uint64_t _sectors;
+};
diff -r 2385683c867a -r ea8e179320d7 USBMSD_Drop/RomDiskData.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD_Drop/RomDiskData.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,182 @@
+// RomDiskData.cpp 2013/9/17
+#include "mbed.h"
+#include "RomDisk.h"
+
+const uint8_t sector_40[] = {
+0x3c,0x21,0x2d,0x2d,0x20,0x6d,0x62,0x65,0x64,0x20,0x4d,0x69,0x63,0x72,0x6f,0x63,
+0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x6c,0x65,0x72,0x20,0x57,0x65,0x62,0x73,0x69,0x74,
+0x65,0x20,0x61,0x6e,0x64,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,
+0x74,0x69,0x6f,0x6e,0x20,0x53,0x68,0x6f,0x72,0x74,0x63,0x75,0x74,0x20,0x2d,0x2d,
+0x3e,0x0d,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,
+0x3e,0x0d,0x0a,0x3c,0x6d,0x65,0x74,0x61,0x20,0x68,0x74,0x74,0x70,0x2d,0x65,0x71,
+0x75,0x69,0x76,0x3d,0x22,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x22,0x20,0x63,0x6f,
+0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x30,0x3b,0x20,0x75,0x72,0x6c,0x3d,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x6d,0x62,0x65,0x64,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x6c,
+0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x2f,0x4c,0x50,0x43,0x31,0x31,0x31,0x34,0x46,
+0x4e,0x32,0x38,0x2f,0x22,0x2f,0x3e,0x0d,0x0a,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,
+0x6d,0x62,0x65,0x64,0x20,0x57,0x65,0x62,0x73,0x69,0x74,0x65,0x20,0x53,0x68,0x6f,
+0x72,0x74,0x63,0x75,0x74,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,
+0x2f,0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x3c,0x2f,
+0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,
+0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+const uint8_t sector_8[] = {
+0x4d,0x42,0x45,0x44,0x32,0x2e,0x30,0x20,0x20,0x20,0x20,0x08,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x67,0x30,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
+0x4d,0x42,0x45,0x44,0x20,0x20,0x20,0x20,0x48,0x54,0x4d,0x20,0x18,0x38,0x48,0x67,
+0x30,0x43,0x30,0x43,0x00,0x00,0x6d,0x66,0x30,0x43,0x02,0x00,0xf2,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+const uint8_t sector_7[] = {
+0xf8,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+const uint8_t sector_6[] = {
+0xf8,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+const uint8_t sector_0[] = {
+0xeb,0x3c,0x90,0x4d,0x53,0x44,0x4f,0x53,0x35,0x2e,0x30,0x00,0x02,0x01,0x06,0x00,
+0x02,0x00,0x02,0x80,0x00,0xf8,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x82,0x14,0xf1,0x28,0x4e,0x4f,0x20,0x4e,0x41,
+0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xc9,
+0x8e,0xd1,0xbc,0xf0,0x7b,0x8e,0xd9,0xb8,0x00,0x20,0x8e,0xc0,0xfc,0xbd,0x00,0x7c,
+0x38,0x4e,0x24,0x7d,0x24,0x8b,0xc1,0x99,0xe8,0x3c,0x01,0x72,0x1c,0x83,0xeb,0x3a,
+0x66,0xa1,0x1c,0x7c,0x26,0x66,0x3b,0x07,0x26,0x8a,0x57,0xfc,0x75,0x06,0x80,0xca,
+0x02,0x88,0x56,0x02,0x80,0xc3,0x10,0x73,0xeb,0x33,0xc9,0x8a,0x46,0x10,0x98,0xf7,
+0x66,0x16,0x03,0x46,0x1c,0x13,0x56,0x1e,0x03,0x46,0x0e,0x13,0xd1,0x8b,0x76,0x11,
+0x60,0x89,0x46,0xfc,0x89,0x56,0xfe,0xb8,0x20,0x00,0xf7,0xe6,0x8b,0x5e,0x0b,0x03,
+0xc3,0x48,0xf7,0xf3,0x01,0x46,0xfc,0x11,0x4e,0xfe,0x61,0xbf,0x00,0x00,0xe8,0xe6,
+0x00,0x72,0x39,0x26,0x38,0x2d,0x74,0x17,0x60,0xb1,0x0b,0xbe,0xa1,0x7d,0xf3,0xa6,
+0x61,0x74,0x32,0x4e,0x74,0x09,0x83,0xc7,0x20,0x3b,0xfb,0x72,0xe6,0xeb,0xdc,0xa0,
+0xfb,0x7d,0xb4,0x7d,0x8b,0xf0,0xac,0x98,0x40,0x74,0x0c,0x48,0x74,0x13,0xb4,0x0e,
+0xbb,0x07,0x00,0xcd,0x10,0xeb,0xef,0xa0,0xfd,0x7d,0xeb,0xe6,0xa0,0xfc,0x7d,0xeb,
+0xe1,0xcd,0x16,0xcd,0x19,0x26,0x8b,0x55,0x1a,0x52,0xb0,0x01,0xbb,0x00,0x00,0xe8,
+0x3b,0x00,0x72,0xe8,0x5b,0x8a,0x56,0x24,0xbe,0x0b,0x7c,0x8b,0xfc,0xc7,0x46,0xf0,
+0x3d,0x7d,0xc7,0x46,0xf4,0x29,0x7d,0x8c,0xd9,0x89,0x4e,0xf2,0x89,0x4e,0xf6,0xc6,
+0x06,0x96,0x7d,0xcb,0xea,0x03,0x00,0x00,0x20,0x0f,0xb6,0xc8,0x66,0x8b,0x46,0xf8,
+0x66,0x03,0x46,0x1c,0x66,0x8b,0xd0,0x66,0xc1,0xea,0x10,0xeb,0x5e,0x0f,0xb6,0xc8,
+0x4a,0x4a,0x8a,0x46,0x0d,0x32,0xe4,0xf7,0xe2,0x03,0x46,0xfc,0x13,0x56,0xfe,0xeb,
+0x4a,0x52,0x50,0x06,0x53,0x6a,0x01,0x6a,0x10,0x91,0x8b,0x46,0x18,0x96,0x92,0x33,
+0xd2,0xf7,0xf6,0x91,0xf7,0xf6,0x42,0x87,0xca,0xf7,0x76,0x1a,0x8a,0xf2,0x8a,0xe8,
+0xc0,0xcc,0x02,0x0a,0xcc,0xb8,0x01,0x02,0x80,0x7e,0x02,0x0e,0x75,0x04,0xb4,0x42,
+0x8b,0xf4,0x8a,0x56,0x24,0xcd,0x13,0x61,0x61,0x72,0x0b,0x40,0x75,0x01,0x42,0x03,
+0x5e,0x0b,0x49,0x75,0x06,0xf8,0xc3,0x41,0xbb,0x00,0x00,0x60,0x66,0x6a,0x00,0xeb,
+0xb0,0x4e,0x54,0x4c,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0d,0x0a,0x52,0x65,
+0x6d,0x6f,0x76,0x65,0x20,0x64,0x69,0x73,0x6b,0x73,0x20,0x6f,0x72,0x20,0x6f,0x74,
+0x68,0x65,0x72,0x20,0x6d,0x65,0x64,0x69,0x61,0x2e,0xff,0x0d,0x0a,0x44,0x69,0x73,
+0x6b,0x20,0x65,0x72,0x72,0x6f,0x72,0xff,0x0d,0x0a,0x50,0x72,0x65,0x73,0x73,0x20,
+0x61,0x6e,0x79,0x20,0x6b,0x65,0x79,0x20,0x74,0x6f,0x20,0x72,0x65,0x73,0x74,0x61,
+0x72,0x74,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0xcb,0xd8,0x55,0xaa,
+};
+const SectorIndex sector_index[] = {
+{40, sector_40},
+{8, sector_8},
+{7, sector_7},
+{6, sector_6},
+{0, sector_0},
+{-1, NULL},
+};
diff -r 2385683c867a -r ea8e179320d7 USBMSD_Drop/USBMSD_Drop.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD_Drop/USBMSD_Drop.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,120 @@
+// USBMSD_Drop.cpp 2013/9/26
+#include "mbed.h"
+#include "USBMSD_Drop.h"
+//#define MY_DEBUG
+#include "mydebug.h"
+
+USBMSD_Drop::USBMSD_Drop()
+{
+    _seq = 0;
+    _file = NULL;
+    _drop_evt = NULL;  
+
+    _status = 0x01;
+    connect();
+}
+
+void USBMSD_Drop::attach(void (*fptr)(const uint8_t* data, int len, int offset, int total))
+{
+    _drop_evt = fptr;     
+}
+
+/* virtual */ int USBMSD_Drop::disk_initialize()
+{
+    _status = 0x00;
+    return 0;
+}
+
+/* virtual */ int USBMSD_Drop::disk_status()
+{
+    return _status;
+}
+
+/* virtual */ int USBMSD_Drop::disk_read(uint8_t * data, uint64_t block)
+{
+    return _disk.read(data, block);
+}
+
+/* virtual */ int USBMSD_Drop::disk_write(const uint8_t * data, uint64_t block)
+{
+    DBG("seq=%d block=%d", _seq, (int)block);
+    DirEntry* entry;
+    switch(_seq) {
+        case 0:
+            if (_disk.is_fat(block)) {
+                break;
+            }    
+            if (_disk.is_rootdir(block)) {
+                entry = findNewFile(data, block);
+                if (entry) {
+                    _file = entry;
+                }
+                break;
+            }     
+            if (_file && _disk.cluster_to_sector(_file->cluster) == block) { // file head ?
+                _addr = 0;
+                _drop(data, 512, _addr, _file->size);
+                _prev_block = block;
+                _addr += 512;
+                _seq++;
+            }
+            break;
+        case 1:    
+            if ((_prev_block+1) != block) {
+                _seq = 0;
+                break;
+            }
+            _drop(data, 512, _addr, _file->size);
+            _prev_block = block;
+            _addr += 512;
+            if (_addr >= _file->size) { // file tail ?
+                _seq = 0;
+            }
+            break;
+    }    
+    return _disk.write(data, block);
+}
+
+/* virtual */ uint64_t USBMSD_Drop::disk_sectors()
+{
+    return _disk.sectors();
+}
+
+/* virtual */ uint64_t USBMSD_Drop::disk_size()
+{
+    return _disk.sectors() * 512;
+}
+
+void USBMSD_Drop::_drop(const uint8_t* data, int len, int offset, int total)
+{
+    Drop(data, len, offset, total);
+    if (_drop_evt) {
+        _drop_evt(data, len, offset, total);
+    }
+}
+
+DirEntry* USBMSD_Drop::findNewFile(const uint8_t* data, uint32_t block)
+{
+    int cnt = _disk.dir_count(block);
+    if (cnt == (-1)) {
+        return NULL;
+    }
+    CT_ASSERT(sizeof(DirEntry) == 32);
+    if (cnt == 0) {
+        _result = NULL;
+    }    
+    for(int pos = 0; pos < 512; pos += sizeof(DirEntry)) {
+        DirEntry* entry = reinterpret_cast<DirEntry*>((uint8_t*)data+pos);
+        if (entry->is_file() && entry->size > 0) {
+            if (_result == NULL || entry->cmpDateTime(_result) > 0) {
+                _dir_entry = *entry;
+                _result = entry;
+            }
+        }
+    }
+    if (_result == NULL) {
+        return NULL;
+    }
+    //DBG_HEX((uint8_t*)&_dir_entry, sizeof(DirEntry));
+    return &_dir_entry;
+}
diff -r 2385683c867a -r ea8e179320d7 USBMSD_Drop/USBMSD_Drop.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBMSD_Drop/USBMSD_Drop.h	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,75 @@
+// USBMSD_Drop.h 2013/9/26
+#pragma once
+#include "USBMSD.h"
+#include "USBMSD2.h"
+#include "RomDisk.h"
+
+#ifdef TARGET_LPC1768
+#define USBMSD USBMSD2
+#endif 
+
+/** drag-and-drop using the USBMSD class
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "USBMSD_Drop.h"
+ * Serial pc(USBTX, USBRX);
+ * USBMSD_Drop* host;
+ * 
+ * void callback(const uint8_t* data, int len, int offset, int total)
+ * {
+ *     for(int i = 0; i < len && (offset+i) < total; i++) {
+ *         pc.putc(data[i]);
+ *     }
+ * }
+ * 
+ * int main() {
+ *     host = new USBMSD_Drop();
+ *     host->attach(callback);
+ *     while(1); // forever
+ * }
+ * @endcode
+ */
+class USBMSD_Drop : public USBMSD {
+public:
+    /** create drag-and-drop file transfer
+     */
+    USBMSD_Drop();
+    virtual ~USBMSD_Drop() {}
+
+    /** drag-and-drop file received
+     *
+     * @param data received data pointer
+     * @param len data length
+     * @param offset offset from file top
+     * @param total total file size
+     */
+    virtual void Drop(const uint8_t* data, int len, int offset, int total){};
+
+    /**
+     * Attach a callback for when a file is received
+     *
+     * @param fptr function pointer
+     */
+    void attach(void (*fptr)(const uint8_t* data, int len, int offset, int total));
+protected:
+    virtual int disk_initialize();
+    virtual int disk_status();
+    virtual int disk_read(uint8_t * data, uint64_t block);
+    virtual int disk_write(const uint8_t * data, uint64_t block);
+    virtual uint64_t disk_sectors();
+    virtual uint64_t disk_size();
+    uint8_t _status;
+
+    void _drop(const uint8_t* data, int len, int offset, int total);
+    void (*_drop_evt)(const uint8_t* data, int len, int offset, int total);
+    
+    DirEntry* findNewFile(const uint8_t* data, uint32_t block);
+    DirEntry _dir_entry;
+    DirEntry* _result;
+    DirEntry* _file;
+    RomDisk _disk;
+    int _seq;
+    int _prev_block;
+    int _addr;
+};
diff -r 2385683c867a -r ea8e179320d7 USBMSD_LPC.cpp
--- a/USBMSD_LPC.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/USBMSD_LPC.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,80 +1,45 @@
-// USBMSD_LPC.cpp 2013/9/17
+// USBMSD_LPC.cpp 2013/9/28
 #include "mbed.h"
 #include "USBMSD_LPC.h"
+#define MY_DEBUG
 #include "mydebug.h"
 
-USBMSD_LPC::USBMSD_LPC(PinName swdio, PinName swclk, PinName reset, Serial* usbpc)
-    : _target(swdio, swclk, reset), _pc(usbpc)
-{
-    _target.setup();
-    _flash = new Flash(&_target, _pc);
-    _status = 0x01;
-    _prog_mode = false;  
-    connect();
-}
+#ifdef TARGET_LPC1768
+#define LED_ON  1
+#define LED_OFF 0
+#endif
+#ifdef TARGET_KL25Z
+#define LED_ON  0
+#define LED_OFF 1
+#endif
+DigitalOut led3(LED3);
 
-/* virtual */ int USBMSD_LPC::disk_initialize()
+USBMSD_LPC::USBMSD_LPC(SWD* swd, Serial* usbpc) : _pc(usbpc)
 {
-    _status = 0x00;
-    return 0;
-}
-
-/* virtual */ int USBMSD_LPC::disk_status()
-{
-    return _status;
-}
-
-/* virtual */ int USBMSD_LPC::disk_read(uint8_t * data, uint64_t block)
-{
-    DBG("block=%d", (int)block);
-    return _romdisk.read(data, block);
+    _target = new Target2(swd);
+    _flash = NULL;
+    led3 = LED_OFF;
 }
 
-/* virtual */ int USBMSD_LPC::disk_write(const uint8_t * data, uint64_t block)
+/* virtual */ void USBMSD_LPC::Drop(const uint8_t* data, int len, int offset, int total)
 {
-    DBG("block=%d", (int)block);
-    if (_prog_mode == false) {
-        if (_romdisk.is_data(block)) {
-            _addr = 0;
-            flashBinary(_addr, data, 512);
-            _prev_block = block;
-            _addr += 512;
-            _prog_mode = true;
-            _pc->printf("Writing.");
-        }
-    } else {
-        if (!_romdisk.is_data(block)) {
-            _pc->printf("passed.\n");
-            _target.SoftwareReset();
-            _prog_mode = false;
-        } else if ((_prev_block+1) != block) {
-            _prog_mode = false;
-        } else {
-            flashBinary(_addr, data, 512);
-            _pc->printf(".");
-            _prev_block = block;
-            _addr += 512;
-        }
+    if (_flash == NULL) {
+        _target->setup();
+        _flash = new Flash(_target, _pc);
     }    
-    return _romdisk.write(data, block);
-}
-
-/* virtual */ uint64_t USBMSD_LPC::disk_sectors()
-{
-    return _romdisk.sectors();
-}
-
-/* virtual */ uint64_t USBMSD_LPC::disk_size()
-{
-    return _romdisk.sectors() * 512;
-}
-
-void USBMSD_LPC::flashBinary(int addr, const uint8_t* buf, int size)
-{
-    DBG("addr=%d(%d)", addr, size);
-    if (addr == 0) {
+    DBG("%d/%d", offset, total);
+    if (offset == 0) {
         _flash->init();
         _flash->eraseAll();
+        led3 = LED_ON;
     }
-    _flash->write(addr, buf, size);
+    _flash->write(offset, data, len);
+    led3 = !led3;
+    if (offset+len >= total) {
+        led3 = LED_OFF;
+        delete _flash;
+        _flash = NULL;
+        _target->SoftwareReset();
+        _target->setup();
+    }
 }
diff -r 2385683c867a -r ea8e179320d7 USBMSD_LPC.h
--- a/USBMSD_LPC.h	Tue Sep 17 04:33:44 2013 +0000
+++ b/USBMSD_LPC.h	Sat Sep 28 03:21:14 2013 +0000
@@ -1,7 +1,6 @@
-// USBMSD_LPC.h 2013/9/16
+// USBMSD_LPC.h 2013/9/26
 #pragma once
-#include "USBMSD.h"
-#include "RomDisk.h"
+#include "USBMSD_Drop.h"
 #include "Target2.h"
 #include "Flash.h"
 
@@ -11,36 +10,24 @@
  * #include "mbed.h"
  * #include "USBMSD_LPC.h"
  * Serial pc(USBTX, USBRX);
+ * SWD swd(PTB8,PTB9,PTB10); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+ *
  * int main() {
- *     USBMSD_LPC* LPC1114 = new USBMSD_LPC(PTB8,PTB9,PTB10,&pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+ *     USBMSD_LPC* LPC1114 = new USBMSD_LPC(&swd, &pc); 
  *     while(1); // forever
  * }
  * @endcode
  */
-class USBMSD_LPC : public USBMSD {
+class USBMSD_LPC : public USBMSD_Drop {
 public:
     /** create drag-and-drop flash writer
-     * @param swdio SWD(swdio) pin
-     * @param swclk SWD(swclk) pin
-     * @param reset reset pin
-     * @param usbpc output stream
+     * @param swd SWD interface
      */
-    USBMSD_LPC(PinName swdio, PinName swclk, PinName reset, Serial* usbpc);
+    USBMSD_LPC(SWD* swd, Serial* usbpc);
     virtual ~USBMSD_LPC() {}
-    virtual int disk_initialize();
-    virtual int disk_status();
-    virtual int disk_read(uint8_t * data, uint64_t block);
-    virtual int disk_write(const uint8_t * data, uint64_t block);
-    virtual uint64_t disk_sectors();
-    virtual uint64_t disk_size();
+    virtual void Drop(const uint8_t* data, int len, int offset, int total);
 protected:
-    void flashBinary(int addr, const uint8_t* buf, int size);
-    RomDisk _romdisk;
-    bool _prog_mode;
-    int _prev_block;
-    int _addr;
-    uint8_t _status;
-    Target2 _target;
+    Target2* _target;
     Flash* _flash;
     Serial* _pc;
 };
diff -r 2385683c867a -r ea8e179320d7 main.cpp
--- a/main.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/main.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,19 +1,55 @@
+// main.cpp 2013/9/28
 #if 1
 #include "mbed.h"
 #include "USBMSD_LPC.h"
+#include "BaseDAP.h"
 
 Serial pc(USBTX, USBRX);
 
-int main() {
-
 #ifdef TARGET_KL25Z
-    USBMSD_LPC* LPC1114 = new USBMSD_LPC(PTB8,PTB9,PTB10,&pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+SWD swd(PTB8,PTB9,PTB10); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
 #endif
 
 #ifdef TARGET_LPC1768
-    USBMSD_LPC* LPC1114 = new USBMSD_LPC(p21,p22,p17,&pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23) 
+SWD swd(p21,p22,p17); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+Serial target_uart(p9,p10); // RXD(dp15),TXD(dp16)
+DigitalOut connected(LED1);
+DigitalOut running(LED2);
+class myDAP : public BaseDAP {
+public:
+    myDAP(SWD* swd):BaseDAP(swd){};
+    virtual void infoLED(int select, int value) {
+        switch(select) {
+            case 0: connected = value; break;
+            case 1: running = value; break;
+        }
+    } 
+}* dap = NULL;
+HID_REPORT send_report;
+HID_REPORT recv_report;
 #endif
 
-    while(1); // forever
+int main() {
+    USBMSD_LPC* device = new USBMSD_LPC(&swd, &pc); 
+    while(1) {
+#ifdef TARGET_LPC1768 
+        if (target_uart.readable()) {
+            device->putc(target_uart.getc());
+        }
+        if(device->readable()) {
+            target_uart.putc(device->getc());
+        }
+
+        if (dap == NULL) {
+            dap = new myDAP(&swd);
+        }
+        if(device->readNB(&recv_report)) {
+            dap->Command(recv_report.data, send_report.data);
+            send_report.length = 64;
+            device->send(&send_report);
+        }
+#endif
+    }
 }
+
 #endif
diff -r 2385683c867a -r ea8e179320d7 mydebug.h
--- a/mydebug.h	Tue Sep 17 04:33:44 2013 +0000
+++ b/mydebug.h	Sat Sep 28 03:21:14 2013 +0000
@@ -1,9 +1,7 @@
-// mydebug.h 2013/8/31
+// mydebug.h 2013/9/26
 #pragma once
 
-#define MY_DEBUG 1
-
-#if MY_DEBUG
+#ifdef MY_DEBUG
 #include "mbed_debug.h"
 extern void debug_hex(uint8_t* buf, int len);
 #define DBG(x, ...) debug("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
@@ -19,3 +17,9 @@
 #else
 #define TEST_ASSERT(A) while(0);
 #endif
+
+#ifndef CT_ASSERT
+template <bool>struct CtAssert;
+template <>struct CtAssert<true> {};
+#define CT_ASSERT(A) CtAssert<A>();
+#endif //CT_ASSERT
diff -r 2385683c867a -r ea8e179320d7 tests/BaseDAP.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/BaseDAP.lib	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/va009039/code/BaseDAP/#76588be01e71
diff -r 2385683c867a -r ea8e179320d7 tests/BuildRomDisk.cpp
--- a/tests/BuildRomDisk.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#include "mbed.h"
-#include "BuildRomDisk.h"
-
-BuildRomDisk::BuildRomDisk()
-{
-    _sectors = 128; // 64KB(512*128)
-    _status = 0x01;
-    connect();
-}
-
-/* virtual */ int BuildRomDisk::disk_initialize()
-{
-    _status = 0x00;
-    return 0;
-}
-
-/* virtual */ int BuildRomDisk::disk_status()
-{
-    return _status;
-}
-
-/* virtual */ int BuildRomDisk::disk_read(uint8_t * data, uint64_t block)
-{
-    return _ramdisk.read(data, block);
-}
-
-/* virtual */ int BuildRomDisk::disk_write(const uint8_t * data, uint64_t block)
-{
-    return _ramdisk.write(data, block);
-}
-
-/* virtual */ uint64_t BuildRomDisk::disk_sectors()
-{
-    return _sectors;
-}
-
-/* virtual */ uint64_t BuildRomDisk::disk_size()
-{
-    return _sectors * 512;
-}
-
-void BuildRomDisk::exportData(Stream* pc)
-{
-    _ramdisk.exportData(pc);
-}
diff -r 2385683c867a -r ea8e179320d7 tests/BuildRomDisk.h
--- a/tests/BuildRomDisk.h	Tue Sep 17 04:33:44 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#pragma once
-#include "USBMSD.h"
-#include "RamDisk.h"
-
-class BuildRomDisk : public USBMSD {
-public:
-    BuildRomDisk();
-    virtual int disk_initialize();
-    virtual int disk_status();
-    virtual int disk_read(uint8_t * data, uint64_t block);
-    virtual int disk_write(const uint8_t * data, uint64_t block);
-    virtual uint64_t disk_sectors();
-    virtual uint64_t disk_size();
-
-    void exportData(Stream* pc);
-protected:
-    RamDisk _ramdisk;
-    uint64_t _sectors;
-    uint8_t _status;
-};
diff -r 2385683c867a -r ea8e179320d7 tests/RamDisk.cpp
--- a/tests/RamDisk.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/tests/RamDisk.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,14 +1,16 @@
-// RamDisk.cpp 2013/9/16
+// RamDisk.cpp 2013/9/21
 #include "mbed.h"
 #include "RamDisk.h"
+#include "mydebug.h"
 
-RamDisk::RamDisk() : _head(NULL)
+RamDisk::RamDisk() : _head(NULL), use_size(0)
 {
     _sectors = 128; // 64KB(512*128)
 }
 
 int RamDisk::read(uint8_t * data, uint32_t block)
 {
+    //DBG("block=%d", block);
     SectorData* p = find(block);
     if (p) {
         memcpy(data, p->data, 512);
@@ -32,17 +34,23 @@
 {
     SectorData* p = find(block);
     if (p) {
+        DBG("update block=%d", block);
         memcpy(p->data, data, 512);
         return 0;
     }
     if (is_blank(data)) {
         return 0;
     }   
+    DBG("new block=%d", block);
     p = new SectorData;
+    TEST_ASSERT(p);
     p->block = block;
     memcpy(p->data, data, 512);
     p->next = _head;
     _head = p;
+    use_size += 512;
+    //DBG("use_size: %d", use_size);
+    TEST_ASSERT(use_size < (512*16));
     return 0;
 }
 
diff -r 2385683c867a -r ea8e179320d7 tests/RamDisk.h
--- a/tests/RamDisk.h	Tue Sep 17 04:33:44 2013 +0000
+++ b/tests/RamDisk.h	Sat Sep 28 03:21:14 2013 +0000
@@ -17,5 +17,6 @@
 protected:
     SectorData* find(uint16_t block);
     SectorData* _head;
+    int use_size;
     uint64_t _sectors;
 };
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/DiskInterface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/DiskInterface.h	Sat Sep 28 03:21:14 2013 +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;
+};
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/SerialInterface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/SerialInterface.h	Sat Sep 28 03:21:14 2013 +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();
+};
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USBMSD2.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USBMSD2.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,330 @@
+/* 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"
+#include "mydebug.h"
+
+#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)
+{
+    _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::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;
+}
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USBMSD2.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USBMSD2.h	Sat Sep 28 03:21:14 2013 +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 "USBEndpoints.h"
+#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 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;
+};
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_CDC.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_CDC.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,163 @@
+/* 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 "USB_CDC.h"
+#define MY_DEBUG
+#include "mydebug.h"
+
+#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)
+{
+    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)
+{
+    DBG("baudrate=%d", baudrate);
+}
+
+void USB_CDC::send_break_callback(uint16_t duration)
+{
+    DBG("duration=%04x", duration);
+}
+
+void USB_CDC::control_line_callback(int rts, int dtr)
+{
+    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)
+{
+    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;
+        }
+    }
+    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);
+    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;
+}
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_CDC.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_CDC.h	Sat Sep 28 03:21:14 2013 +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.
+*/
+
+#pragma once
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+#include "CircBuffer.h"
+
+#define CDC_EPINT_IN   EP1IN
+#define CDC_EPBULK_IN  EP5IN 
+#define CDC_EPBULK_OUT EP5OUT
+
+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();
+    
+protected:
+    USBDevice* _device;
+    CircBuffer<uint8_t> _rx_buf;
+    volatile bool terminal_connected;
+};
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_HID.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_HID.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,135 @@
+/* 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 "USB_HID.h"
+
+USB_HID::USB_HID(USBDevice* device, uint8_t output_report_length, uint8_t input_report_length) : _device(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;
+}
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_HID.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_HID.h	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,102 @@
+/* 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 "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#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;
+};
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_MSD.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_MSD.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,543 @@
+/* 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 "USB_MSD.h"
+
+#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(USBMSD2* device, USBMSD2* disk) : _device(device),_disk(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;
+}
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USB_MSD.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USB_MSD.h	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,150 @@
+/* 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 "USBMSD2.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(USBMSD2* device, USBMSD2* 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:
+    USBMSD2* _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();
+};
diff -r 2385683c867a -r ea8e179320d7 tests/mydebug.cpp
--- a/tests/mydebug.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/tests/mydebug.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,6 +1,6 @@
 // mydebug.cpp 2013/4/22
 #include "mydebug.h"
-#ifdef MY_DEBUG
+
 #include <string.h>
 void debug_hex(uint8_t* buf, int len)
 {
@@ -176,5 +176,3 @@
                                                                         wdata, rdata, ack); 
     debug("\n");
 }
-
-#endif
diff -r 2385683c867a -r ea8e179320d7 tests/test2_USBMSD_Drop.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test2_USBMSD_Drop.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,26 @@
+// test2_USBMSD_Drop.cpp 2013/9/26
+#if 0
+#include "mbed.h"
+#include "USBMSD_Drop.h"
+
+Serial pc(USBTX, USBRX);
+USBMSD_Drop* host;
+
+void callback(const uint8_t* data, int len, int offset, int total)
+{
+    for(int i = 0; i < len && (offset+i) < total; i++) {
+        pc.putc(data[i]);
+    }
+}
+
+int main()
+{
+    pc.baud(921600);
+    //pc.baud(9600);
+    pc.printf("%s\n", __FILE__);
+
+    host = new USBMSD_Drop();
+    host->attach(callback);
+    while(1); // forever
+}
+#endif
diff -r 2385683c867a -r ea8e179320d7 tests/test_BuildRomDisk.cpp
--- a/tests/test_BuildRomDisk.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/tests/test_BuildRomDisk.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,13 +1,37 @@
+// test_BuildRomDisk.cpp 2013/9/22
 #if 0
 #include "mbed.h"
-#include "BuildRomDisk.h"
-
+#include "USBMSD2.h"
+#include "RamDisk.h"
 #include "mytest.h"
 #include "mydebug.h"
 
 Serial pc(USBTX, USBRX);
 DigitalIn exit_btn(p14); // application board 
 
+class BuildRomDisk : public USBMSD2 {
+public:
+    BuildRomDisk() {
+        _sectors = 128; // 64KB(512*128)
+        _status = 0x01;
+        connect();
+    }
+    virtual int disk_initialize() {
+        _status = 0x00;
+        return 0;
+    }
+    virtual int disk_status() { return _status; }
+    virtual int disk_read(uint8_t * data, uint64_t block) { return _ramdisk.read(data, block); }
+    virtual int disk_write(const uint8_t * data, uint64_t block) { return _ramdisk.write(data, block); }
+    virtual uint64_t disk_sectors() { return _sectors; }
+    virtual uint64_t disk_size() { return _sectors * 512; }
+    void exportData(Stream* pc) { _ramdisk.exportData(pc); }
+protected:
+    RamDisk _ramdisk;
+    uint64_t _sectors;
+    uint8_t _status;
+};
+
 TEST(BuildRomDisk1,test1) {
     BuildRomDisk* target = new BuildRomDisk();
     while(!exit_btn);
diff -r 2385683c867a -r ea8e179320d7 tests/test_RomDisk.cpp
--- a/tests/test_RomDisk.cpp	Tue Sep 17 04:33:44 2013 +0000
+++ b/tests/test_RomDisk.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -1,21 +1,59 @@
+// test_RomDisk.cpp 2013/9/24
 #if 0
 #include "mbed.h"
-#include "USBMSD_LPC.h"
-
+#include "USBMSD2.h"
+#include "RomDisk.h"
 #include "mytest.h"
 #include "mydebug.h"
 
 Serial pc(USBTX, USBRX);
 
+class RomDisk1 : public USBMSD2 {
+public:
+    RomDisk1() {
+        _sectors = 128; // 64KB(512*128)
+        _status = 0x01;
+        connect();
+    }
+    virtual int disk_initialize() {
+        _status = 0x00;
+        return 0;
+    }
+    virtual int disk_status() { return _status; }
+    virtual int disk_read(uint8_t * data, uint64_t block) { return _disk.read(data, block); }
+    virtual int disk_write(const uint8_t * data, uint64_t block) {
+        if (_disk.is_data(block)) {
+            DBG("block=%d", (int)block);
+        }
+        return _disk.write(data, block);
+    }
+    virtual uint64_t disk_sectors() { return _sectors; }
+    virtual uint64_t disk_size() { return _sectors * 512; }
+    
+protected:
+    RomDisk _disk;
+    uint64_t _sectors;
+    uint8_t _status;
+};
+
+
 TEST(RomDisk1,test1) {
-#ifdef TARGET_LPC1768
-    USBMSD_LPC* LPC1114 = new USBMSD_LPC(p21,p22,p17,&pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23) 
-#endif
-#ifdef TARGET_KL25Z
-    USBMSD_LPC* LPC1114 = new USBMSD_LPC(PTB8,PTB9,PTB10,&pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
-#endif
-
-    while(1); // forever
+    RomDisk1* intf = new RomDisk1();
+    Timer t;
+    t.reset();
+    t.start();
+    int n = 0;
+    while(1) { // forever
+        if (intf->readable()) {
+            int c = intf->getc();
+            debug("%02x[%c]\n", c, c > ' ' ? c : '.');
+        }
+        if (t.read_ms() > 1000*1) {
+            t.reset();
+            intf->putc('A'+ n%26);
+            n++;
+        }
+    }
 }
 
 int main() {
diff -r 2385683c867a -r ea8e179320d7 tests/test_USBMSD2_HID.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_USBMSD2_HID.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,107 @@
+// test_USBMSD2_HID.cpp 2013/9/28
+#if 0
+#include "mbed.h"
+#include "USBMSD_Drop.h"
+#include "BaseDAP.h"
+#define MY_DEBUG 1
+#include "mydebug.h"
+#include "mytest.h"
+
+Serial pc(USBTX, USBRX);
+
+#ifdef TARGET_LPC1768
+Serial target_uart(p9,p10); // RXD(dp15),TXD(dp16)
+SWD swd(p21,p22,p17); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+DigitalOut connected(LED1);
+DigitalOut running(LED2);
+class myDAP : public BaseDAP {
+public:
+    myDAP(SWD* swd):BaseDAP(swd){};
+    virtual void infoLED(int select, int value) {
+        switch(select) {
+            case 0: connected = value; break;
+            case 1: running = value; break;
+        }
+    } 
+};
+#endif
+
+#ifdef TARGET_KL25Z
+SWD swd(PTB8,PTB9,PTB10); // SWDIO(dp12),SWCLK(dp3),nReset(dp23)
+DigitalOut connected(LED_GREEN);
+DigitalOut running(LED_RED);
+class myDAP : public BaseDAP {
+public:
+    myDAP(SWD* swd):BaseDAP(swd){};
+    virtual void infoLED(int select, int value) {
+        switch(select) {
+            case 0:
+                connected = value^1; 
+                running = 1;
+                break;
+            case 1: 
+                running = value^1; 
+                connected = 1;
+                break;
+        }
+    } 
+};
+#endif
+
+class myUSBMSD_Drop : public USBMSD_Drop {
+public:
+    virtual void Drop(const uint8_t* data, int len, int offset, int total) {
+        TEST_PRINT("offset=%d, total=%d", offset, total);
+    }
+};
+
+HID_REPORT send_report;
+HID_REPORT recv_report;
+
+myDAP* dap;
+myUSBMSD_Drop* hid;
+
+TEST(USBMSD2_HID,test1) {
+    dap = new myDAP(&swd);
+    hid = new myUSBMSD_Drop();
+}
+
+#if 0
+TEST(USBMSD2_HID,test2) {
+    while(1) { // forever
+        if(hid->readNB(&recv_report)) {
+            dap->Command(recv_report.data, send_report.data);
+            send_report.length = 64;
+            hid->send(&send_report);
+        }
+    }
+}
+#endif
+
+TEST(USBMSD2_HID,test3) {
+    while(1) { // forever
+        if(hid->readNB(&recv_report)) {
+            dap->Command(recv_report.data, send_report.data);
+            send_report.length = 64;
+            hid->send(&send_report);
+        }
+#ifdef TARGET_LPC1768
+        if (target_uart.readable()) {
+            hid->putc(target_uart.getc());
+        }
+        if(hid->readable()) {
+            target_uart.putc(hid->getc());
+        }
+#endif        
+    }
+}
+
+int main() {
+    pc.baud(921600);
+    //pc.baud(9600);
+    DBG("%s", __FILE__);
+
+    RUN_ALL_TESTS();
+    exit(0);
+}
+#endif
diff -r 2385683c867a -r ea8e179320d7 tests/test_USBMSD_Drop.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_USBMSD_Drop.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,44 @@
+// test_USBMSD_Drop.cpp 2013/9/26
+#if 0
+#include "mbed.h"
+#include "USBMSD_Drop.h"
+#include "mytest.h"
+#include "mydebug.h"
+
+Serial pc(USBTX, USBRX);
+
+class myUSBMSD_Drop : public USBMSD_Drop {
+public:
+    virtual void Drop(const uint8_t* data, int len, int offset, int total) {
+        TEST_PRINT("offset=%d, total=%d", offset, total);
+    }
+};
+
+TEST(USBMSD_Drop,test1) {
+    myUSBMSD_Drop* intf = new myUSBMSD_Drop();
+    Timer t;
+    t.reset();
+    t.start();
+    int n = 0;
+    while(1) { // forever
+        if (intf->readable()) {
+            int c = intf->getc();
+            debug("%02x[%c]\n", c, c > ' ' ? c : '.');
+        }
+        if (t.read_ms() > 1000*1) {
+            t.reset();
+            intf->putc('A'+ n%26);
+            n++;
+        }
+    }
+}
+
+int main() {
+    pc.baud(921600);
+    //pc.baud(9600);
+    DBG("%s", __FILE__);
+
+    RUN_ALL_TESTS();
+    exit(0);
+}
+#endif