Support Isochronous transfer additionally
Dependents: USBHostC270_example_GR-PEACH USBHostDac_example USBHostDac_Audio_in_out
Fork of USBHost_custom by
Revision 39:4a7c5479dc23, committed 2017-03-16
- 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
--- 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
+
