USBHost custom library.

Dependents:   GR-PEACH_HVC-P2_sample_client mbed-os-storage-access GR-PEACH_Digital_Signage GR-PEACH_Audio_Playback_Sample ... more

Fork of USBHost by mbed official

Files at this revision

API Documentation at this revision

Comitter:
dkato
Date:
Thu Mar 16 04:38:43 2017 +0000
Parent:
38:dd168a3e4194
Child:
40:cdc0d2ab4678
Commit message:
Supports mbed os 5.4.

Changed in this revision

USBHost/USBEndpoint.h Show annotated file Show diff for this revision Revisions of this file
USBHostMSD/USBHostMSD.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostMSD/USBHostMSD.h Show annotated file Show diff for this revision Revisions of this file
--- a/USBHost/USBEndpoint.h	Tue Mar 14 05:38:25 2017 +0000
+++ b/USBHost/USBEndpoint.h	Thu Mar 16 04:38:43 2017 +0000
@@ -95,9 +95,7 @@
      * @param fptr function pointer
      */
     inline void attach(void (*fptr)(void)) {
-        if(fptr != NULL) {
             rx.attach(fptr);
-        }
     }
 
     /**
--- a/USBHostMSD/USBHostMSD.cpp	Tue Mar 14 05:38:25 2017 +0000
+++ b/USBHostMSD/USBHostMSD.cpp	Thu Mar 16 04:38:43 2017 +0000
@@ -29,13 +29,20 @@
 #define GET_MAX_LUN             (0xFE)
 #define BO_MASS_STORAGE_RESET   (0xFF)
 
-USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
+USBHostMSD::USBHostMSD()
 {
     host = USBHost::getHostInst();
-    init();
+    msd_init();
 }
 
-void USBHostMSD::init() {
+USBHostMSD::~USBHostMSD()
+{
+    if (_is_initialized) {
+        deinit();
+    }
+}
+
+void USBHostMSD::msd_init() {
     dev_connected = false;
     dev = NULL;
     bulk_in = NULL;
@@ -45,7 +52,7 @@
     blockCount = 0;
     msd_intf = -1;
     msd_device_found = false;
-    disk_init = false;
+    _is_initialized = false;
     dev_connected = false;
     nb_ep = 0;
 }
@@ -80,14 +87,14 @@
 
                 USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
                 dev->setName("MSD", msd_intf);
-                host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
+                host->registerDriver(dev, msd_intf, this, &USBHostMSD::msd_init);
 
                 dev_connected = true;
                 return true;
             }
         } //if()
     } //for()
-    init();
+    msd_init();
     return false;
 }
 
@@ -301,10 +308,17 @@
     return res;
 }
 
-int USBHostMSD::disk_initialize() {
-    USB_DBG("FILESYSTEM: init");
+#define USB_BLOCK_DEVICE_ERROR_WOULD_BLOCK        -5001 /*!< operation would block */
+#define USB_BLOCK_DEVICE_ERROR_UNSUPPORTED        -5002 /*!< unsupported operation */
+#define USB_BLOCK_DEVICE_ERROR_PARAMETER          -5003 /*!< invalid parameter */
+#define USB_BLOCK_DEVICE_ERROR_NO_INIT            -5004 /*!< uninitialized */
+#define USB_BLOCK_DEVICE_ERROR_NO_DEVICE          -5005 /*!< device is missing or not connected */
+#define USB_BLOCK_DEVICE_ERROR_WRITE_PROTECTED    -5006 /*!< write protected */
+
+int USBHostMSD::init() {
     uint16_t i, timeout = 10;
 
+    _lock.lock();
     getMaxLun();
 
     for (i = 0; i < timeout; i++) {
@@ -314,53 +328,116 @@
     }
 
     if (i == timeout) {
-        disk_init = false;
-        return -1;
+        return BD_ERROR_DEVICE_ERROR;
     }
 
     inquiry(0, 0);
-    disk_init = 1;
-    return readCapacity();
+    if (readCapacity() != 0) {
+        _lock.unlock();
+        return BD_ERROR_DEVICE_ERROR;
+    }
+    _is_initialized = true;
+    _lock.unlock();
+
+    return BD_ERROR_OK;
+}
+
+int USBHostMSD::deinit() {
+    return 0;
 }
 
-int USBHostMSD::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) {
-    USB_DBG("FILESYSTEM: write block: %lld, count: %d", block_number, count);
-    if (!disk_init) {
-        disk_initialize();
+int USBHostMSD::program(const void *b, bd_addr_t addr, bd_size_t size)
+{
+    if (!is_valid_program(addr, size)) {
+        return USB_BLOCK_DEVICE_ERROR_PARAMETER;
+    }
+
+    _lock.lock();
+    if (!_is_initialized) {
+        _lock.unlock();
+        return USB_BLOCK_DEVICE_ERROR_NO_INIT;
     }
-    if (!disk_init)
-        return -1;
-    for (uint32_t b = block_number; b < block_number + count; b++) {
-        if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
-            return -1;
+
+    const uint8_t *buffer = static_cast<const uint8_t*>(b);
+    while (size > 0) {
+        bd_addr_t block = addr / 512;
+
+        // send the data block
+        if (dataTransfer((uint8_t*)buffer, block, 1, HOST_TO_DEVICE)) {
+            _lock.unlock();
+            return BD_ERROR_DEVICE_ERROR;
+        }
+
         buffer += 512;
+        addr += 512;
+        size -= 512;
     }
+    _lock.unlock();
     return 0;
 }
 
-int USBHostMSD::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) {
-    USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count);
-    if (!disk_init) {
-        disk_initialize();
+int USBHostMSD::read(void *b, bd_addr_t addr, bd_size_t size)
+{
+    if (!is_valid_read(addr, size)) {
+        return USB_BLOCK_DEVICE_ERROR_PARAMETER;
+    }
+
+    _lock.lock();
+    if (!_is_initialized) {
+        _lock.unlock();
+        return USB_BLOCK_DEVICE_ERROR_PARAMETER;
     }
-    if (!disk_init)
-        return -1;
-    for (uint32_t b = block_number; b < block_number + count; b++) {
-        if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
-            return -1;
+
+    uint8_t *buffer = static_cast<uint8_t *>(b);
+    while (size > 0) {
+        bd_addr_t block = addr / 512;
+
+        // receive the data
+        if (dataTransfer((uint8_t*)buffer, block, 1, DEVICE_TO_HOST)) {
+            _lock.unlock();
+            return BD_ERROR_DEVICE_ERROR;
+        }
         buffer += 512;
+        addr += 512;
+        size -= 512;
     }
+    _lock.unlock();
     return 0;
 }
 
-uint32_t USBHostMSD::disk_sectors() {
-    USB_DBG("FILESYSTEM: sectors");
-    if (!disk_init) {
-        disk_initialize();
+int USBHostMSD::erase(bd_addr_t addr, bd_size_t size)
+{
+    return 0;
+}
+
+bd_size_t USBHostMSD::get_read_size() const
+{
+    return 512;
+}
+
+bd_size_t USBHostMSD::get_program_size() const
+{
+    return 512;
+}
+
+bd_size_t USBHostMSD::get_erase_size() const
+{
+    return 512;
+}
+
+bd_size_t USBHostMSD::size() const
+{
+    bd_size_t sectors = 0;
+    if(_is_initialized) {
+        sectors = blockCount;
     }
-    if (!disk_init)
-        return 0;
-    return blockCount;
+    return 512*sectors;
+}
+
+void USBHostMSD::debug(bool dbg)
+{
+//    _dbg = dbg;
 }
 
 #endif
+
--- a/USBHostMSD/USBHostMSD.h	Tue Mar 14 05:38:25 2017 +0000
+++ b/USBHostMSD/USBHostMSD.h	Thu Mar 16 04:38:43 2017 +0000
@@ -22,19 +22,20 @@
 #if USBHOST_MSD
 
 #include "USBHost.h"
-#include "FATFileSystem.h"
+#include "BlockDevice.h"
 
 /**
  * A class to communicate a USB flash disk
  */
-class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
+class USBHostMSD : public IUSBEnumerator, public BlockDevice {
 public:
     /**
     * Constructor
     *
     * @param rootdir mount name
     */
-    USBHostMSD(const char * rootdir);
+    USBHostMSD();
+    virtual ~USBHostMSD();
 
     /**
     * Check if a MSD device is connected
@@ -50,20 +51,86 @@
      */
     bool connect();
 
+    /** Initialize a block device
+     *
+     *  @return         0 on success or a negative error code on failure
+     */
+    virtual int init();
+
+    /** Deinitialize a block device
+     *
+     *  @return         0 on success or a negative error code on failure
+     */
+    virtual int deinit();
+
+    /** Read blocks from a block device
+     *
+     *  @param buffer   Buffer to write blocks to
+     *  @param addr     Address of block to begin reading from
+     *  @param size     Size to read in bytes, must be a multiple of read block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
+
+    /** Program blocks to a block device
+     *
+     *  The blocks must have been erased prior to being programmed
+     *
+     *  @param buffer   Buffer of data to write to blocks
+     *  @param addr     Address of block to begin writing to
+     *  @param size     Size to write in bytes, must be a multiple of program block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
+
+    /** Erase blocks on a block device
+     *
+     *  The state of an erased block is undefined until it has been programmed
+     *
+     *  @param addr     Address of block to begin erasing
+     *  @param size     Size to erase in bytes, must be a multiple of erase block size
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int erase(bd_addr_t addr, bd_size_t size);
+
+    /** Get the size of a readable block
+     *
+     *  @return         Size of a readable block in bytes
+     */
+    virtual bd_size_t get_read_size() const;
+
+    /** Get the size of a programable block
+     *
+     *  @return         Size of a programable block in bytes
+     *  @note Must be a multiple of the read size
+     */
+    virtual bd_size_t get_program_size() const;
+
+    /** Get the size of a eraseable block
+     *
+     *  @return         Size of a eraseable block in bytes
+     *  @note Must be a multiple of the program size
+     */
+    virtual bd_size_t get_erase_size() const;
+
+    /** Get the total size of the underlying device
+     *
+     *  @return         Size of the underlying device in bytes
+     */
+    virtual bd_size_t size() const;
+
+    /** Enable or disable debugging
+     *
+     *  @param          State of debugging
+     */
+    virtual void debug(bool dbg);
+
 protected:
     //From IUSBEnumerator
     virtual void setVidPid(uint16_t vid, uint16_t pid);
     virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
     virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
 
-    // From FATFileSystem
-    virtual int disk_initialize();
-    virtual int disk_status() {return 0;};
-    virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count);
-    virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count);
-    virtual int disk_sync() {return 0;};
-    virtual uint32_t disk_sectors();
-
 private:
     USBHost * host;
     USBDeviceConnected * dev;
@@ -93,6 +160,7 @@
 
     CBW cbw;
     CSW csw;
+    Mutex _lock;
 
     int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
     int testUnitReady();
@@ -108,12 +176,13 @@
 
     int msd_intf;
     bool msd_device_found;
-    bool disk_init;
+    bool _is_initialized;
 
-    void init();
+    void msd_init();
 
 };
 
 #endif
 
 #endif
+