![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
USB composite device example program, drag-and-drop flash writer.
Dependencies: SWD USBDevice mbed BaseDAP
Diff: USBMSD_Drop/USBMSD_Drop.cpp
- 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; +}