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

Dependencies:   SWD USBDevice mbed BaseDAP

Revision:
1:ea8e179320d7
--- /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;
+}