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

Dependencies:   SWD USBDevice mbed BaseDAP

USBMSD_Drop/USBMSD_Drop.cpp

Committer:
va009039
Date:
2013-09-28
Revision:
1:ea8e179320d7

File content as of revision 1:ea8e179320d7:

// 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;
}