Adaptation of the official mbed USBHost repository to work with the LPC4088 Display Module

Dependents:   DMSupport DMSupport DMSupport DMSupport

Fork of DM_USBHost by EmbeddedArtists AB

Files at this revision

API Documentation at this revision

Comitter:
embeddedartists
Date:
Tue Dec 02 15:16:39 2014 +0000
Parent:
26:607951c26872
Child:
28:a55c5a98d5e9
Commit message:
Adaptation of the official mbed USBHost repository to work with the LPC4088 Display Module. The changes include: basic setup, move of all memory to the AHBSRAM0, switch to USB port 2, adding a memory allocator for users.

Changed in this revision

FATFileSystem.lib Show diff for this revision Revisions of this file
USBHost/USBHALHost.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHALHost.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHost.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHost.h Show annotated file Show diff for this revision Revisions of this file
USBHost/dbg.h Show annotated file Show diff for this revision Revisions of this file
USBHostHub/USBHostHub.cpp 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
mbed-rtos.lib Show diff for this revision Revisions of this file
--- a/FATFileSystem.lib	Mon Aug 18 13:45:26 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- a/USBHost/USBHALHost.cpp	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHost/USBHALHost.cpp	Tue Dec 02 15:16:39 2014 +0000
@@ -39,7 +39,28 @@
 
 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
 
-static volatile uint8_t usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM1"),aligned(256)));  //256 bytes aligned!
+// Put the USB structures in the only memory accessible by the USB stack - the AHBSRAM0
+static volatile uint8_t usb_buf[TOTAL_SIZE] __attribute__((section("AHBSRAM0"),aligned(256)));// __attribute__((section("AHBSRAM0"),aligned(256)));  //256 bytes aligned!
+
+// A very basic implementation of malloc to allocate in the AHBSRAM0
+#define SAFE_MEM_TO_USE     (10*1024)
+#define SAFE_MEM_BLOCK_SIZE (512)
+#define SAFE_MEM_NUM_BLOCKS (SAFE_MEM_TO_USE/SAFE_MEM_BLOCK_SIZE)
+typedef struct {
+    volatile uint8_t* ptr;
+    bool used;
+} safe_mem_info_t;
+static safe_mem_info_t safe_mem_list[SAFE_MEM_NUM_BLOCKS];
+static uint8_t safe_mem_data[SAFE_MEM_TO_USE] __attribute__((section("AHBSRAM0"),aligned(256)));//__attribute__((section("AHBSRAM0"),aligned));  //256 bytes aligned!
+
+// To detect when memory outside of the AHBSRAM0 is passed to the USB stack
+void assert_mem_region(uint32_t ptr)
+{
+    if (( ptr != 0) && ((ptr & 0xff000000) != 0x20000000)) {
+        USB_ERR("0x%08x not in USB MEM", ptr);
+        mbed_die();
+    }
+}
 
 USBHALHost * USBHALHost::instHost;
 
@@ -53,23 +74,64 @@
     for (int i = 0; i < MAX_TD; i++) {
         tdBufAlloc[i] = false;
     }
+    for (int i = 0; i < SAFE_MEM_NUM_BLOCKS; i++) {
+        safe_mem_list[i].used = false;
+        safe_mem_list[i].ptr = safe_mem_data + SAFE_MEM_BLOCK_SIZE*i;
+    }
 }
 
+uint8_t* USBHALHost::getSafeMem(uint32_t size) {
+    uint8_t* result = NULL;
+    if (size > 512) {
+        USB_ERR("getSafeMem(%u) not supported", size);
+    } else {
+        safemem_mutex.lock();
+        for (int i = 0; i < SAFE_MEM_NUM_BLOCKS; i++) {
+            if (!safe_mem_list[i].used) {
+                safe_mem_list[i].used = true;
+                result = (uint8_t*)safe_mem_list[i].ptr;
+                break;
+            }
+        }
+        safemem_mutex.unlock();
+    }
+    if (result == NULL) {
+        USB_ERR("getSafeMem(%u) failed to allocate", size);
+    }
+    return result;
+}
+
+void USBHALHost::returnSafeMem(uint8_t* mem) {
+    safemem_mutex.lock();
+    int i;
+    for (i = 0; i < SAFE_MEM_NUM_BLOCKS; i++) {
+        if (safe_mem_list[i].ptr == mem) {
+            safe_mem_list[i].used = false;
+            break;
+        }
+    }
+    safemem_mutex.unlock();
+    if (i == SAFE_MEM_NUM_BLOCKS) {
+      USB_ERR("returnSafeMem(%p) not allocated", mem);
+    }
+}
+
+
 void USBHALHost::init() {
     NVIC_DisableIRQ(USB_IRQn);
 
     //Cut power
     LPC_SC->PCONP &= ~(1UL<<31);
-    wait_ms(100);
+    wait_ms(1000);
 
     // turn on power for USB
     LPC_SC->PCONP       |= (1UL<<31);
 
     // Enable USB host clock, port selection and AHB clock
-    LPC_USB->USBClkCtrl |= CLOCK_MASK;
+    LPC_USB->USBClkCtrl = 0x19;
 
     // Wait for clocks to become available
-    while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK);
+    while ((LPC_USB->USBClkSt & 0x19) != 0x19);
 
     // it seems the bits[0:1] mean the following
     // 0: U1=device, U2=host
@@ -77,25 +139,39 @@
     // 2: reserved
     // 3: U1=host, U2=device
     // NB: this register is only available if OTG clock (aka "port select") is enabled!!
-    // since we don't care about port 2, set just bit 0 to 1 (U1=host)
-    LPC_USB->OTGStCtrl |= 1;
-
-    // now that we've configured the ports, we can turn off the portsel clock
-    LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
+    LPC_USB->OTGStCtrl = 1;
 
     // configure USB D+/D- pins
-    // P0[29] = USB_D+, 01
-    // P0[30] = USB_D-, 01
-    LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
-    LPC_PINCON->PINSEL1 |=  ((1<<26) | (1<<28));
+
+    LPC_IOCON->P0_29 &= ~0x9F; // USB_D+1
+    LPC_IOCON->P0_29 |=  0x01; // USB_D+1
+    LPC_IOCON->P0_30 &= ~0x9F; // USB_D-1
+    LPC_IOCON->P0_30 |=  0x01; // USB_D-1
+
+    LPC_IOCON->P0_31 &= ~0x9F; // USB_D+2
+    LPC_IOCON->P0_31 |=  0x01; // USB_D+2
+
+    LPC_IOCON->P1_30 &= ~0x1F; // USB_PWRD2
+    LPC_IOCON->P1_30 |=  0x01; // USB_PWRD2
+    LPC_IOCON->P1_31 &= ~0x1F; // USB_OVRCR2
+    LPC_IOCON->P1_31 |=  0x01; // USB_OVRCR2
+
+    LPC_IOCON->P0_14 &= ~0x1F; // USB ID Pin as GPIO, output, high
+    LPC_GPIO0->DIR   |= (1<<14);
+    LPC_GPIO0->SET    = (1<<14);
+    LPC_IOCON->P4_31 &= ~0x1F; // USB CONN Pin as GPIO, output, low
+    LPC_GPIO4->DIR   |= (1UL<<31);
+    LPC_GPIO4->CLR    = (1UL<<31);
+
+    USB_DBG("initialize OHCI\n");
+
+    // Wait 100 ms before apply reset
+    wait_ms(100);
 
     LPC_USB->HcControl       = 0; // HARDWARE RESET
     LPC_USB->HcControlHeadED = 0; // Initialize Control list head to Zero
     LPC_USB->HcBulkHeadED    = 0; // Initialize Bulk list head to Zero
 
-    // Wait 100 ms before apply reset
-    wait_ms(100);
-
     // software reset
     LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
 
@@ -105,6 +181,7 @@
 
     // Put HC in operational state
     LPC_USB->HcControl  = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
+
     // Set Global Power
     LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;
 
@@ -119,15 +196,19 @@
     NVIC_SetVector(USB_IRQn, (uint32_t)(_usbisr));
     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
+    LPC_USB->HcRhPortStatus2 = OR_RH_PORT_CSC;
+    LPC_USB->HcRhPortStatus2 = OR_RH_PORT_PRSC;
+    
+    resetRootHub();
 
+    NVIC_SetPriority(USB_IRQn, 0);
     NVIC_EnableIRQ(USB_IRQn);
 
-    // Check for any connected devices
-    if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
+    if (LPC_USB->HcRhPortStatus2 & OR_RH_PORT_CCS) {
         //Device connected
         wait_ms(150);
-        USB_DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus1);
-        deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
+        USB_DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus2);
+        deviceConnected(0, 2, LPC_USB->HcRhPortStatus2 & OR_RH_PORT_LSDA);
     }
 }
 
@@ -216,8 +297,8 @@
             return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
         }
     }
-    perror("Could not allocate ED\r\n");
-    return NULL; //Could not alloc ED
+    USB_ERR("Could not allocate ED\r\n");
+    return NULL;
 }
 
 volatile uint8_t * USBHALHost::getTD() {
@@ -228,8 +309,8 @@
             return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
         }
     }
-    perror("Could not allocate TD\r\n");
-    return NULL; //Could not alloc TD
+    USB_ERR("Could not allocate TD\r\n");
+    return NULL;
 }
 
 
@@ -247,6 +328,11 @@
 
 
 void USBHALHost::resetRootHub() {
+
+    DigitalOut usb2_vbus_en(P0_12);
+    usb2_vbus_en = 1;
+    wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */
+
     // Initiate port reset
     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
 
@@ -254,6 +340,19 @@
 
     // ...and clear port reset signal
     LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
+
+    usb2_vbus_en = 0;
+
+    // Initiate port reset
+    LPC_USB->HcRhPortStatus2 = OR_RH_PORT_PRS;
+
+    while (LPC_USB->HcRhPortStatus2 & OR_RH_PORT_PRS);
+    
+    // ...and clear port reset signal
+    LPC_USB->HcRhPortStatus2 = OR_RH_PORT_PRSC;
+    
+    usb2_vbus_en = 1;
+    wait_ms(200); /* Wait for 100 MS after port reset  */
 }
 
 
@@ -266,25 +365,24 @@
 void USBHALHost::UsbIrqhandler() {
     if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
     {
-
         uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
-
+        
         // Root hub status change interrupt
         if (int_status & OR_INTR_STATUS_RHSC) {
-            if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
+            if (LPC_USB->HcRhPortStatus2 & OR_RH_PORT_CSC) {
                 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
                     // When DRWE is on, Connect Status Change
                     // means a remote wakeup event.
                 } else {
 
                     //Root device connected
-                    if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
+                    if (LPC_USB->HcRhPortStatus2 & OR_RH_PORT_CCS) {
 
                         // wait 150ms to avoid bounce
                         wait_ms(150);
 
-                        //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
-                        deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
+                        //Hub 0 (root hub), Port 2 (count starts at 1), Low or High speed
+                        deviceConnected(0, 2, LPC_USB->HcRhPortStatus2 & OR_RH_PORT_LSDA);
                     }
 
                     //Root device disconnected
@@ -297,7 +395,7 @@
                         // wait 200ms to avoid bounce
                         wait_ms(200);
 
-                        deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
+                        deviceDisconnected(0, 2, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
 
                         if (int_status & OR_INTR_STATUS_WDH) {
                             usb_hcca->DoneHead = 0;
@@ -305,10 +403,10 @@
                         }
                     }
                 }
-                LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
+                LPC_USB->HcRhPortStatus2 = OR_RH_PORT_CSC;
             }
-            if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
-                LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
+            if (LPC_USB->HcRhPortStatus2 & OR_RH_PORT_PRSC) {
+                LPC_USB->HcRhPortStatus2 = OR_RH_PORT_PRSC;
             }
             LPC_USB->HcInterruptStatus = OR_INTR_STATUS_RHSC;
         }
--- a/USBHost/USBHALHost.h	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHost/USBHALHost.h	Tue Dec 02 15:16:39 2014 +0000
@@ -19,13 +19,36 @@
 
 #include "USBHostTypes.h"
 #include "USBHostConf.h"
+#include "rtos.h"
 
 class USBHostHub;
 
+#if defined(TARGET_LPC4088)
+  #define HcRevision        Revision
+  #define HcControl         Control
+  #define HcCommandStatus   CommandStatus
+  #define HcInterruptStatus InterruptStatus
+  #define HcInterruptEnable InterruptEnable
+  #define HcHCCA            HCCA
+  #define HcControlHeadED   ControlHeadED
+  #define HcBulkHeadED      BulkHeadED
+  #define HcFmInterval      FmInterval
+  #define HcFmNumber        FmNumber
+  #define HcPeriodicStart   PeriodicStart
+  #define HcRhStatus        RhStatus
+  #define HcRhPortStatus1   RhPortStatus1
+  #define HcRhPortStatus2   RhPortStatus2
+  #define OTGStCtrl         StCtrl
+#endif
+
 /**
 * USBHALHost class
 */
 class USBHALHost {
+public:
+    uint8_t* getSafeMem(uint32_t size);
+    void returnSafeMem(uint8_t* mem);
+        
 protected:
 
     /**
@@ -164,6 +187,8 @@
 
     bool volatile  edBufAlloc[MAX_ENDPOINT];
     bool volatile tdBufAlloc[MAX_TD];
+
+    Mutex safemem_mutex;
 };
 
 #endif
--- a/USBHost/USBHost.cpp	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHost/USBHost.cpp	Tue Dec 02 15:16:39 2014 +0000
@@ -53,7 +53,8 @@
     bool interruptListState;
     USBEndpoint * ep;
     uint8_t i, j, res, timeout_set_addr = 10;
-    uint8_t buf[8];
+#define SAFE_USB_PROCESS_BUFF_SIZE (8)
+    uint8_t* buf = getSafeMem(SAFE_USB_PROCESS_BUFF_SIZE);
     bool too_many_hub;
     int idx;
 
@@ -121,7 +122,7 @@
                           // get first 8 bit of device descriptor
                           // and check if we deal with a hub
                           USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
-                          res = getDeviceDescriptor(&devices[i], buf, 8);
+                          res = getDeviceDescriptor(&devices[i], buf, SAFE_USB_PROCESS_BUFF_SIZE);
 
                           if (res != USB_TYPE_OK) {
                               USB_ERR("usb_thread could not read dev descr");
@@ -143,7 +144,7 @@
 
                           // try to read again the device descriptor to check if the device
                           // answers to its new address
-                          res = getDeviceDescriptor(&devices[i], buf, 8);
+                          res = getDeviceDescriptor(&devices[i], buf, SAFE_USB_PROCESS_BUFF_SIZE);
 
                           if (res == USB_TYPE_OK) {
                               break;
@@ -223,10 +224,10 @@
 #if DEBUG_TRANSFER
                         if (ep->getDir() == IN) {
                             buf_transfer = ep->getBufStart();
-                            printf("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ",  ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress());
+                            USB_DBG_X("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ",  ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress());
                             for (int i = 0; i < ep->getLengthTransferred(); i++)
-                                printf("%02X ", buf_transfer[i]);
-                            printf("\r\n\r\n");
+                                USB_DBG_X("%02X ", buf_transfer[i]);
+                            USB_DBG_X("\r\n\r\n");
                         }
 #endif
                         ep->call();
@@ -261,6 +262,9 @@
     tailInterruptEndpoint = NULL;
 
     lenReportDescr = 0;
+    
+    setupPacket = getSafeMem(SAFE_USB_HOST_SETUP_PACKET_BUFF_SIZE);
+    data = getSafeMem(SAFE_USB_HOST_DATA_BUFF_SIZE);
 
     controlEndpointAllocated = false;
 
@@ -678,22 +682,22 @@
     const char * type_str = (type == BULK_ENDPOINT) ? "BULK" :
                             ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" :
                             ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS"));
-    printf("State of %s:\r\n", type_str);
+    USB_DBG_X("State of %s:\r\n", type_str);
     while (hced != NULL) {
         uint8_t dir = ((hced->control & (3 << 11)) >> 11);
-        printf("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced,
+        USB_DBG_X("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced,
                                                    hced->control & 0x7f,
                                                    (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"),
                                                     (hced->control & (0xf << 7)) >> 7);
         hctd = (HCTD *)((uint32_t)(hced->headTD) & ~(0xf));
         while (hctd != hced->tailTD) {
-            printf("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN");
+            USB_DBG_X("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN");
             hctd = hctd->nextTD;
         }
-        printf("\thctd: %p\r\n", hctd);
+        USB_DBG_X("\thctd: %p\r\n", hctd);
         hced = hced->nextED;
     }
-    printf("\r\n\r\n");
+    USB_DBG_X("\r\n\r\n");
 #endif
 }
 
@@ -701,6 +705,9 @@
 // add a transfer on the TD linked list
 USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
 {
+    ASSERT_MEM_REGION(buf);
+    
+
     td_mutex.lock();
 
     // allocate a TD which will be freed in TDcompletion
@@ -860,7 +867,7 @@
 
       pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
 
-      res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
+      res = getConfigurationDescriptor(dev, data, SAFE_USB_HOST_DATA_BUFF_SIZE/*sizeof(data)*/, &total_conf_descr_length);
       if (res != USB_TYPE_OK) {
           return res;
       }
@@ -868,8 +875,8 @@
   #if (DEBUG > 3)
       USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
       for (int i = 0; i < total_conf_descr_length; i++)
-          printf("%02X ", data[i]);
-      printf("\r\n\r\n");
+          USB_DBG_X("%02X ", data[i]);
+      USB_DBG_X("\r\n\r\n");
   #endif
 
       // Parse the configuration descriptor
@@ -990,8 +997,9 @@
     return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false);
 }
 
-USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
-
+USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write)
+{
+    
 #if DEBUG_TRANSFER
     const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
     USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
@@ -1031,8 +1039,8 @@
     if (write) {
         USB_DBG_TRANSFER("%s WRITE buffer", type_str);
         for (int i = 0; i < ep->getLengthTransferred(); i++)
-            printf("%02X ", buf[i]);
-        printf("\r\n\r\n");
+            USB_DBG_X("%02X ", buf[i]);
+        USB_DBG_X("\r\n\r\n");
     }
 #endif
     addTransfer(ep, buf, len);
@@ -1087,12 +1095,12 @@
 #if DEBUG_TRANSFER
     USB_DBG_TRANSFER("SETUP PACKET: ");
     for (int i = 0; i < 8; i++)
-        printf("%01X ", setupPacket[i]);
-    printf("\r\n");
+        USB_DBG_X("%01X ", setupPacket[i]);
+    USB_DBG_X("\r\n");
 #endif
 
     control->setNextToken(TD_SETUP);
-    addTransfer(control, (uint8_t*)setupPacket, 8);
+    addTransfer(control, (uint8_t*)setupPacket, SAFE_USB_HOST_SETUP_PACKET_BUFF_SIZE);
 
     control->ep_queue.get();
     res = control->getState();
@@ -1106,6 +1114,7 @@
     if (length_transfer) {
         token = (write) ? TD_OUT : TD_IN;
         control->setNextToken(token);
+
         addTransfer(control, (uint8_t *)buf, length_transfer);
 
         control->ep_queue.get();
@@ -1116,13 +1125,13 @@
         if (write) {
             USB_DBG_TRANSFER("CONTROL WRITE buffer");
             for (int i = 0; i < control->getLengthTransferred(); i++)
-                printf("%02X ", buf[i]);
-            printf("\r\n\r\n");
+                USB_DBG_X("%02X ", buf[i]);
+            USB_DBG_X("\r\n\r\n");
         } else {
             USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred());
             for (int i = 0; i < control->getLengthTransferred(); i++)
-                printf("%02X ", buf[i]);
-            printf("\r\n\r\n");
+                USB_DBG_X("%02X ", buf[i]);
+            USB_DBG_X("\r\n\r\n");
         }
 #endif
 
@@ -1133,6 +1142,7 @@
 
     token = (write) ? TD_IN : TD_OUT;
     control->setNextToken(token);
+
     addTransfer(control, NULL, 0);
 
     control->ep_queue.get();
--- a/USBHost/USBHost.h	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHost/USBHost.h	Tue Dec 02 15:16:39 2014 +0000
@@ -264,7 +264,8 @@
 #endif
 
     // to store a setup packet
-    uint8_t  setupPacket[8];
+#define SAFE_USB_HOST_SETUP_PACKET_BUFF_SIZE (8)
+    uint8_t*   setupPacket;
 
     typedef struct {
         uint8_t event_id;
@@ -284,8 +285,9 @@
     Mutex td_mutex;
 
     // buffer for conf descriptor
-    uint8_t data[415];
-
+#define SAFE_USB_HOST_DATA_BUFF_SIZE (415)
+    uint8_t* data;
+    
     /**
     * Add a transfer on the TD linked list associated to an ED
     *
--- a/USBHost/dbg.h	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHost/dbg.h	Tue Dec 02 15:16:39 2014 +0000
@@ -17,50 +17,54 @@
 #ifndef USB_DEBUG_H
 #define USB_DEBUG_H
 
+#include "DMBoard.h" // To replace the std::printf calls
+
 //Debug is disabled by default
-#define DEBUG 3 /*INFO,ERR,WARN*/
+#define DEBUG 2 /*ERR,WARN*/
 #define DEBUG_TRANSFER 0
 #define DEBUG_EP_STATE 0
 #define DEBUG_EVENT 0
 
 #if (DEBUG > 3)
-#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_DBG(x, ...) DMBoard::instance().logger()->printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#define USB_DBG_X(...)  DMBoard::instance().logger()->printf(__VA_ARGS__)
 #else
 #define USB_DBG(x, ...)
 #endif
 
 #if (DEBUG > 2)
-#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_INFO(x, ...) DMBoard::instance().logger()->printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
 #else
 #define USB_INFO(x, ...)
 #endif
 
 #if (DEBUG > 1)
-#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_WARN(x, ...) DMBoard::instance().logger()->printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
 #else
 #define USB_WARN(x, ...)
 #endif
 
 #if (DEBUG > 0)
-#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_ERR(x, ...) DMBoard::instance().logger()->printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
 #else
 #define USB_ERR(x, ...)
 #endif
 
 #if (DEBUG_TRANSFER)
-#define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_DBG_TRANSFER(x, ...) DMBoard::instance().logger()->printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
 #else
 #define USB_DBG_TRANSFER(x, ...)
 #endif
 
 #if (DEBUG_EVENT)
-#define USB_DBG_EVENT(x, ...) std::printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_DBG_EVENT(x, ...) DMBoard::instance().logger()->printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__)
 #else
 #define USB_DBG_EVENT(x, ...)
 #endif
 
 
+void assert_mem_region(uint32_t ptr);
+#define ASSERT_MEM_REGION(__x) assert_mem_region((uint32_t)(__x))
+
 #endif
 
-
-
--- a/USBHostHub/USBHostHub.cpp	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHostHub/USBHostHub.cpp	Tue Dec 02 15:16:39 2014 +0000
@@ -220,7 +220,7 @@
 void USBHostHub::portReset(uint8_t port) {
     // reset port
     uint32_t status;
-    USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
+    USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this);
     setPortFeature(PORT_RESET_FEATURE, port);
     while(1) {
         status = getPortStatus(port);
--- a/USBHostMSD/USBHostMSD.cpp	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHostMSD/USBHostMSD.cpp	Tue Dec 02 15:16:39 2014 +0000
@@ -33,6 +33,21 @@
 {
     host = USBHost::getHostInst();
     init();
+    
+    cbw = (CBW*)host->getSafeMem(sizeof(CBW));
+    csw = (CSW*)host->getSafeMem(sizeof(CSW));
+}
+
+USBHostMSD::~USBHostMSD()
+{
+    if (cbw != NULL) {
+        host->returnSafeMem((uint8_t*)cbw);
+        cbw = NULL;
+    }
+    if (csw != NULL) {
+        host->returnSafeMem((uint8_t*)csw);
+        csw = NULL;
+    }
 }
 
 void USBHostMSD::init() {
@@ -40,13 +55,11 @@
     dev = NULL;
     bulk_in = NULL;
     bulk_out = NULL;
-    dev_connected = false;
     blockSize = 0;
     blockCount = 0;
     msd_intf = -1;
     msd_device_found = false;
     disk_init = false;
-    dev_connected = false;
     nb_ep = 0;
 }
 
@@ -131,13 +144,14 @@
 int USBHostMSD::readCapacity() {
     USB_DBG("Read capacity");
     uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
-    uint8_t result[8];
+    uint8_t* result = host->getSafeMem(8);
     int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
     if (status == 0) {
         blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
         blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
         USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize);
     }
+    host->returnSafeMem(result);
     return status;
 }
 
@@ -145,8 +159,9 @@
 int USBHostMSD::SCSIRequestSense() {
     USB_DBG("Request sense");
     uint8_t cmd[6] = {0x03,0,0,0,18,0};
-    uint8_t result[18];
+    uint8_t* result = host->getSafeMem(18);
     int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
+    host->returnSafeMem(result);
     return status;
 }
 
@@ -155,7 +170,7 @@
     USB_DBG("Inquiry");
     uint8_t evpd = (page_code == 0) ? 0 : 1;
     uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
-    uint8_t result[36];
+    uint8_t* result = host->getSafeMem(36);
     int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
     if (status == 0) {
         char vid_pid[17];
@@ -171,6 +186,7 @@
         vid_pid[4] = 0;
         USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid);
     }
+    host->returnSafeMem(result);
     return status;
 }
 
@@ -198,20 +214,20 @@
 
     int res = 0;
 
-    cbw.Signature = CBW_SIGNATURE;
-    cbw.Tag = 0;
-    cbw.DataLength = transfer_len;
-    cbw.Flags = flags;
-    cbw.LUN = 0;
-    cbw.CBLength = cmd_len;
-    memset(cbw.CB,0,sizeof(cbw.CB));
+    cbw->Signature = CBW_SIGNATURE;
+    cbw->Tag = 0;
+    cbw->DataLength = transfer_len;
+    cbw->Flags = flags;
+    cbw->LUN = 0;
+    cbw->CBLength = cmd_len;
+    memset(cbw->CB,0,sizeof(cbw->CB));
     if (cmd) {
-        memcpy(cbw.CB,cmd,cmd_len);
+        memcpy(cbw->CB,cmd,cmd_len);
     }
 
     // send the cbw
     USB_DBG("Send CBW");
-    res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
+    res = host->bulkWrite(dev, bulk_out,(uint8_t *)cbw, 31);
     if (checkResult(res, bulk_out))
         return -1;
 
@@ -233,26 +249,26 @@
     }
 
     // status stage
-    csw.Signature = 0;
+    csw->Signature = 0;
     USB_DBG("Read CSW");
-    res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
+    res = host->bulkRead(dev, bulk_in,(uint8_t *)csw, 13);
     if (checkResult(res, bulk_in))
         return -1;
 
-    if (csw.Signature != CSW_SIGNATURE) {
+    if (csw->Signature != CSW_SIGNATURE) {
         return -1;
     }
 
-    USB_DBG("recv csw: status: %d", csw.Status);
+    USB_DBG("recv csw: status: %d", csw->Status);
 
     // ModeSense?
-    if ((csw.Status == 1) && (cmd[0] != 0x03)) {
+    if ((csw->Status == 1) && (cmd[0] != 0x03)) {
         USB_DBG("request mode sense");
         return SCSIRequestSense();
     }
 
     // perform reset recovery
-    if ((csw.Status == 2) && (cmd[0] != 0x03)) {
+    if ((csw->Status == 2) && (cmd[0] != 0x03)) {
 
         // send Bulk-Only Mass Storage Reset request
         res = host->controlWrite(   dev,
@@ -273,7 +289,7 @@
 
     }
 
-    return csw.Status;
+    return csw->Status;
 }
 
 
@@ -294,10 +310,12 @@
 }
 
 int USBHostMSD::getMaxLun() {
-    uint8_t buf[1], res;
+    uint8_t res;
+    uint8_t* buf = host->getSafeMem(1);
     res = host->controlRead(    dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
                                 0xfe, 0, msd_intf, buf, 1);
     USB_DBG("max lun: %d", buf[0]);
+    host->returnSafeMem(buf);
     return res;
 }
 
@@ -330,11 +348,16 @@
     }
     if (!disk_init)
         return -1;
+    uint8_t* safe = host->getSafeMem(512);
     for (uint64_t b = block_number; b < block_number + count; b++) {
-        if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
+        memcpy(safe, buffer, 512);
+        if (dataTransfer((uint8_t*)safe, b, 1, HOST_TO_DEVICE)) {
+            host->returnSafeMem(safe);
             return -1;
+        }
         buffer += 512;
     }
+    host->returnSafeMem(safe);
     return 0;
 }
 
@@ -345,11 +368,16 @@
     }
     if (!disk_init)
         return -1;
+    uint8_t* safe = host->getSafeMem(512);
     for (uint64_t b = block_number; b < block_number + count; b++) {
-        if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
+        if (dataTransfer((uint8_t*)safe, b, 1, DEVICE_TO_HOST)) {
+            host->returnSafeMem(safe);
             return -1;
+        }
+        memcpy(buffer, safe, 512);
         buffer += 512;
     }
+    host->returnSafeMem(safe);
     return 0;
 }
 
--- a/USBHostMSD/USBHostMSD.h	Mon Aug 18 13:45:26 2014 +0100
+++ b/USBHostMSD/USBHostMSD.h	Tue Dec 02 15:16:39 2014 +0000
@@ -35,6 +35,7 @@
     * @param rootdir mount name
     */
     USBHostMSD(const char * rootdir);
+    virtual ~USBHostMSD();
 
     /**
     * Check if a MSD device is connected
@@ -91,8 +92,8 @@
         uint8_t  Status;
     } PACKED CSW;
 
-    CBW cbw;
-    CSW csw;
+    CBW* cbw;
+    CSW* csw;
 
     int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
     int testUnitReady();
--- a/mbed-rtos.lib	Mon Aug 18 13:45:26 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#29007aef10a4