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

Dependencies:   SWD USBDevice mbed BaseDAP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBMSD_Drop.cpp Source File

USBMSD_Drop.cpp

00001 // USBMSD_Drop.cpp 2013/9/26
00002 #include "mbed.h"
00003 #include "USBMSD_Drop.h"
00004 //#define MY_DEBUG
00005 #include "mydebug.h"
00006 
00007 USBMSD_Drop::USBMSD_Drop()
00008 {
00009     _seq = 0;
00010     _file = NULL;
00011     _drop_evt = NULL;  
00012 
00013     _status = 0x01;
00014     connect();
00015 }
00016 
00017 void USBMSD_Drop::attach(void (*fptr)(const uint8_t* data, int len, int offset, int total))
00018 {
00019     _drop_evt = fptr;     
00020 }
00021 
00022 /* virtual */ int USBMSD_Drop::disk_initialize()
00023 {
00024     _status = 0x00;
00025     return 0;
00026 }
00027 
00028 /* virtual */ int USBMSD_Drop::disk_status()
00029 {
00030     return _status;
00031 }
00032 
00033 /* virtual */ int USBMSD_Drop::disk_read(uint8_t * data, uint64_t block)
00034 {
00035     return _disk.read(data, block);
00036 }
00037 
00038 /* virtual */ int USBMSD_Drop::disk_write(const uint8_t * data, uint64_t block)
00039 {
00040     DBG("seq=%d block=%d", _seq, (int)block);
00041     DirEntry* entry;
00042     switch(_seq) {
00043         case 0:
00044             if (_disk.is_fat(block)) {
00045                 break;
00046             }    
00047             if (_disk.is_rootdir(block)) {
00048                 entry = findNewFile(data, block);
00049                 if (entry) {
00050                     _file = entry;
00051                 }
00052                 break;
00053             }     
00054             if (_file && _disk.cluster_to_sector(_file->cluster) == block) { // file head ?
00055                 _addr = 0;
00056                 _drop(data, 512, _addr, _file->size);
00057                 _prev_block = block;
00058                 _addr += 512;
00059                 _seq++;
00060             }
00061             break;
00062         case 1:    
00063             if ((_prev_block+1) != block) {
00064                 _seq = 0;
00065                 break;
00066             }
00067             _drop(data, 512, _addr, _file->size);
00068             _prev_block = block;
00069             _addr += 512;
00070             if (_addr >= _file->size) { // file tail ?
00071                 _seq = 0;
00072             }
00073             break;
00074     }    
00075     return _disk.write(data, block);
00076 }
00077 
00078 /* virtual */ uint64_t USBMSD_Drop::disk_sectors()
00079 {
00080     return _disk.sectors();
00081 }
00082 
00083 /* virtual */ uint64_t USBMSD_Drop::disk_size()
00084 {
00085     return _disk.sectors() * 512;
00086 }
00087 
00088 void USBMSD_Drop::_drop(const uint8_t* data, int len, int offset, int total)
00089 {
00090     Drop(data, len, offset, total);
00091     if (_drop_evt) {
00092         _drop_evt(data, len, offset, total);
00093     }
00094 }
00095 
00096 DirEntry* USBMSD_Drop::findNewFile(const uint8_t* data, uint32_t block)
00097 {
00098     int cnt = _disk.dir_count(block);
00099     if (cnt == (-1)) {
00100         return NULL;
00101     }
00102     CT_ASSERT(sizeof(DirEntry) == 32);
00103     if (cnt == 0) {
00104         _result = NULL;
00105     }    
00106     for(int pos = 0; pos < 512; pos += sizeof(DirEntry)) {
00107         DirEntry* entry = reinterpret_cast<DirEntry*>((uint8_t*)data+pos);
00108         if (entry->is_file() && entry->size > 0) {
00109             if (_result == NULL || entry->cmpDateTime(_result) > 0) {
00110                 _dir_entry = *entry;
00111                 _result = entry;
00112             }
00113         }
00114     }
00115     if (_result == NULL) {
00116         return NULL;
00117     }
00118     //DBG_HEX((uint8_t*)&_dir_entry, sizeof(DirEntry));
00119     return &_dir_entry;
00120 }