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

Dependencies:   SWD USBDevice mbed BaseDAP

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?

UserRevisionLine numberNew 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 }