USB composite device example program, drag-and-drop flash writer.
Dependencies: SWD USBDevice mbed BaseDAP
USBMSD_Drop/USBMSD_Drop.cpp@1:ea8e179320d7, 2013-09-28 (annotated)
- Committer:
- va009039
- Date:
- Sat Sep 28 03:21:14 2013 +0000
- Revision:
- 1:ea8e179320d7
add USBMSD_Drop class. add CDC(Virtual COM) and HID(for example CMSIS-DAP), but KL25Z not work.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 1:ea8e179320d7 | 1 | // USBMSD_Drop.cpp 2013/9/26 |
va009039 | 1:ea8e179320d7 | 2 | #include "mbed.h" |
va009039 | 1:ea8e179320d7 | 3 | #include "USBMSD_Drop.h" |
va009039 | 1:ea8e179320d7 | 4 | //#define MY_DEBUG |
va009039 | 1:ea8e179320d7 | 5 | #include "mydebug.h" |
va009039 | 1:ea8e179320d7 | 6 | |
va009039 | 1:ea8e179320d7 | 7 | USBMSD_Drop::USBMSD_Drop() |
va009039 | 1:ea8e179320d7 | 8 | { |
va009039 | 1:ea8e179320d7 | 9 | _seq = 0; |
va009039 | 1:ea8e179320d7 | 10 | _file = NULL; |
va009039 | 1:ea8e179320d7 | 11 | _drop_evt = NULL; |
va009039 | 1:ea8e179320d7 | 12 | |
va009039 | 1:ea8e179320d7 | 13 | _status = 0x01; |
va009039 | 1:ea8e179320d7 | 14 | connect(); |
va009039 | 1:ea8e179320d7 | 15 | } |
va009039 | 1:ea8e179320d7 | 16 | |
va009039 | 1:ea8e179320d7 | 17 | void USBMSD_Drop::attach(void (*fptr)(const uint8_t* data, int len, int offset, int total)) |
va009039 | 1:ea8e179320d7 | 18 | { |
va009039 | 1:ea8e179320d7 | 19 | _drop_evt = fptr; |
va009039 | 1:ea8e179320d7 | 20 | } |
va009039 | 1:ea8e179320d7 | 21 | |
va009039 | 1:ea8e179320d7 | 22 | /* virtual */ int USBMSD_Drop::disk_initialize() |
va009039 | 1:ea8e179320d7 | 23 | { |
va009039 | 1:ea8e179320d7 | 24 | _status = 0x00; |
va009039 | 1:ea8e179320d7 | 25 | return 0; |
va009039 | 1:ea8e179320d7 | 26 | } |
va009039 | 1:ea8e179320d7 | 27 | |
va009039 | 1:ea8e179320d7 | 28 | /* virtual */ int USBMSD_Drop::disk_status() |
va009039 | 1:ea8e179320d7 | 29 | { |
va009039 | 1:ea8e179320d7 | 30 | return _status; |
va009039 | 1:ea8e179320d7 | 31 | } |
va009039 | 1:ea8e179320d7 | 32 | |
va009039 | 1:ea8e179320d7 | 33 | /* virtual */ int USBMSD_Drop::disk_read(uint8_t * data, uint64_t block) |
va009039 | 1:ea8e179320d7 | 34 | { |
va009039 | 1:ea8e179320d7 | 35 | return _disk.read(data, block); |
va009039 | 1:ea8e179320d7 | 36 | } |
va009039 | 1:ea8e179320d7 | 37 | |
va009039 | 1:ea8e179320d7 | 38 | /* virtual */ int USBMSD_Drop::disk_write(const uint8_t * data, uint64_t block) |
va009039 | 1:ea8e179320d7 | 39 | { |
va009039 | 1:ea8e179320d7 | 40 | DBG("seq=%d block=%d", _seq, (int)block); |
va009039 | 1:ea8e179320d7 | 41 | DirEntry* entry; |
va009039 | 1:ea8e179320d7 | 42 | switch(_seq) { |
va009039 | 1:ea8e179320d7 | 43 | case 0: |
va009039 | 1:ea8e179320d7 | 44 | if (_disk.is_fat(block)) { |
va009039 | 1:ea8e179320d7 | 45 | break; |
va009039 | 1:ea8e179320d7 | 46 | } |
va009039 | 1:ea8e179320d7 | 47 | if (_disk.is_rootdir(block)) { |
va009039 | 1:ea8e179320d7 | 48 | entry = findNewFile(data, block); |
va009039 | 1:ea8e179320d7 | 49 | if (entry) { |
va009039 | 1:ea8e179320d7 | 50 | _file = entry; |
va009039 | 1:ea8e179320d7 | 51 | } |
va009039 | 1:ea8e179320d7 | 52 | break; |
va009039 | 1:ea8e179320d7 | 53 | } |
va009039 | 1:ea8e179320d7 | 54 | if (_file && _disk.cluster_to_sector(_file->cluster) == block) { // file head ? |
va009039 | 1:ea8e179320d7 | 55 | _addr = 0; |
va009039 | 1:ea8e179320d7 | 56 | _drop(data, 512, _addr, _file->size); |
va009039 | 1:ea8e179320d7 | 57 | _prev_block = block; |
va009039 | 1:ea8e179320d7 | 58 | _addr += 512; |
va009039 | 1:ea8e179320d7 | 59 | _seq++; |
va009039 | 1:ea8e179320d7 | 60 | } |
va009039 | 1:ea8e179320d7 | 61 | break; |
va009039 | 1:ea8e179320d7 | 62 | case 1: |
va009039 | 1:ea8e179320d7 | 63 | if ((_prev_block+1) != block) { |
va009039 | 1:ea8e179320d7 | 64 | _seq = 0; |
va009039 | 1:ea8e179320d7 | 65 | break; |
va009039 | 1:ea8e179320d7 | 66 | } |
va009039 | 1:ea8e179320d7 | 67 | _drop(data, 512, _addr, _file->size); |
va009039 | 1:ea8e179320d7 | 68 | _prev_block = block; |
va009039 | 1:ea8e179320d7 | 69 | _addr += 512; |
va009039 | 1:ea8e179320d7 | 70 | if (_addr >= _file->size) { // file tail ? |
va009039 | 1:ea8e179320d7 | 71 | _seq = 0; |
va009039 | 1:ea8e179320d7 | 72 | } |
va009039 | 1:ea8e179320d7 | 73 | break; |
va009039 | 1:ea8e179320d7 | 74 | } |
va009039 | 1:ea8e179320d7 | 75 | return _disk.write(data, block); |
va009039 | 1:ea8e179320d7 | 76 | } |
va009039 | 1:ea8e179320d7 | 77 | |
va009039 | 1:ea8e179320d7 | 78 | /* virtual */ uint64_t USBMSD_Drop::disk_sectors() |
va009039 | 1:ea8e179320d7 | 79 | { |
va009039 | 1:ea8e179320d7 | 80 | return _disk.sectors(); |
va009039 | 1:ea8e179320d7 | 81 | } |
va009039 | 1:ea8e179320d7 | 82 | |
va009039 | 1:ea8e179320d7 | 83 | /* virtual */ uint64_t USBMSD_Drop::disk_size() |
va009039 | 1:ea8e179320d7 | 84 | { |
va009039 | 1:ea8e179320d7 | 85 | return _disk.sectors() * 512; |
va009039 | 1:ea8e179320d7 | 86 | } |
va009039 | 1:ea8e179320d7 | 87 | |
va009039 | 1:ea8e179320d7 | 88 | void USBMSD_Drop::_drop(const uint8_t* data, int len, int offset, int total) |
va009039 | 1:ea8e179320d7 | 89 | { |
va009039 | 1:ea8e179320d7 | 90 | Drop(data, len, offset, total); |
va009039 | 1:ea8e179320d7 | 91 | if (_drop_evt) { |
va009039 | 1:ea8e179320d7 | 92 | _drop_evt(data, len, offset, total); |
va009039 | 1:ea8e179320d7 | 93 | } |
va009039 | 1:ea8e179320d7 | 94 | } |
va009039 | 1:ea8e179320d7 | 95 | |
va009039 | 1:ea8e179320d7 | 96 | DirEntry* USBMSD_Drop::findNewFile(const uint8_t* data, uint32_t block) |
va009039 | 1:ea8e179320d7 | 97 | { |
va009039 | 1:ea8e179320d7 | 98 | int cnt = _disk.dir_count(block); |
va009039 | 1:ea8e179320d7 | 99 | if (cnt == (-1)) { |
va009039 | 1:ea8e179320d7 | 100 | return NULL; |
va009039 | 1:ea8e179320d7 | 101 | } |
va009039 | 1:ea8e179320d7 | 102 | CT_ASSERT(sizeof(DirEntry) == 32); |
va009039 | 1:ea8e179320d7 | 103 | if (cnt == 0) { |
va009039 | 1:ea8e179320d7 | 104 | _result = NULL; |
va009039 | 1:ea8e179320d7 | 105 | } |
va009039 | 1:ea8e179320d7 | 106 | for(int pos = 0; pos < 512; pos += sizeof(DirEntry)) { |
va009039 | 1:ea8e179320d7 | 107 | DirEntry* entry = reinterpret_cast<DirEntry*>((uint8_t*)data+pos); |
va009039 | 1:ea8e179320d7 | 108 | if (entry->is_file() && entry->size > 0) { |
va009039 | 1:ea8e179320d7 | 109 | if (_result == NULL || entry->cmpDateTime(_result) > 0) { |
va009039 | 1:ea8e179320d7 | 110 | _dir_entry = *entry; |
va009039 | 1:ea8e179320d7 | 111 | _result = entry; |
va009039 | 1:ea8e179320d7 | 112 | } |
va009039 | 1:ea8e179320d7 | 113 | } |
va009039 | 1:ea8e179320d7 | 114 | } |
va009039 | 1:ea8e179320d7 | 115 | if (_result == NULL) { |
va009039 | 1:ea8e179320d7 | 116 | return NULL; |
va009039 | 1:ea8e179320d7 | 117 | } |
va009039 | 1:ea8e179320d7 | 118 | //DBG_HEX((uint8_t*)&_dir_entry, sizeof(DirEntry)); |
va009039 | 1:ea8e179320d7 | 119 | return &_dir_entry; |
va009039 | 1:ea8e179320d7 | 120 | } |