[ FORK ] USBFileSytem; fork from sissors/USBFileSystem

Dependents:   USBMSD_CDC_11U35test

Fork of USBFileSystem by Erik -

USBFileSystem.cpp

Committer:
k4zuki
Date:
2015-04-21
Revision:
9:98a97b7d56a8
Parent:
8:a9e1dffac4bd

File content as of revision 9:98a97b7d56a8:

#include "USBFileSystem.h"

#define USBWRITE_TIMEOUT 100

USBFileSystem::USBFileSystem(const char* n) : FATFileSystem_ds(n) {
  localFunction = NULL;
  usbFunction = NULL;
  usbfree = true;
  local_count = 0;
  usbMode(1);
}


FileHandle* USBFileSystem::open(const char* name, int flags){    
    char n[64];
    sprintf(n, "%d:/%s", _fsid, name);
    bool write = true;
    
    /* POSIX flags -> FatFS open mode */
    BYTE openmode;
    if (flags & O_RDWR) {
        openmode = FA_READ|FA_WRITE;
        localOpen(true);
    } else if(flags & O_WRONLY) {
        openmode = FA_WRITE;
        localOpen(true);
    } else {
        openmode = FA_READ;
        write = false;
    }
    if(flags & O_CREAT) {
        if(flags & O_TRUNC) {
            openmode |= FA_CREATE_ALWAYS;
        } else {
            openmode |= FA_OPEN_ALWAYS;
        }
    }
    
    FIL fh;
    FRESULT res = f_open(&fh, n, openmode);
    if (res) {
        if (write)
            local_count--;
        return NULL;
    }
    if (flags & O_APPEND) {
        f_lseek(&fh, fh.fsize);
    }
    return new USBFileHandle(fh, this, write);
}

bool USBFileSystem::localSafe( void ){
    return (local_count == 0);
}

bool USBFileSystem::usbSafe( void ){
    return usbfree;
}

int USBFileSystem::disk_status_fat() { 
    int retval = _disk_status();
    
    if ((retval == 0) && (!usbSafe()))
        return 4;
    else 
        return retval;
 }
 
 int USBFileSystem::disk_status_msd() { 
    int retval = _disk_status();
    
    if ((retval == 0) && (!localSafe()))
        return 4;
    else 
        return retval;
 }
 
int USBFileSystem::disk_write(const uint8_t * data, uint64_t block, uint8_t count) {
    if (localSafe()) {
        if (usbfree && (usbFunction!=NULL) )
            usbFunction(false);
            
        usbfree = false;
        }
  
    int retval= _disk_write(data, block, count);

    if (localSafe())
        usb_write.attach_us(this, &USBFileSystem::usbFree, USBWRITE_TIMEOUT * 1000);

    return retval;
}

void USBFileSystem::localOpen(bool open) {
    if (open) {
        local_count++;
    } else {
        local_count--;
    }
    
    //Pseudo-IRQ
    if (open && (local_count == 1)) {
        if (usbmode == 1)
            disconnect();
        if (localFunction != NULL) 
            (*localFunction)(false);
    }
    if (!open && (local_count == 0)) {
        if (usbmode == 1)
            connect();
        if (localFunction != NULL) 
            (*localFunction)(true);
    }
}
    
void USBFileSystem::attachLocal(void (*function)(bool)) {
    localFunction = function;
}   

void USBFileSystem::attachUSB(void (*function)(bool)) {
    usbFunction = function;
}   

void USBFileSystem::usbFree( void ) {
    usbfree = true;
    if (usbFunction != NULL)
        usbFunction(true);
}

void USBFileSystem::usbMode(int mode) {
    usbmode = mode;
}