Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768

Dependencies:   FATFileSystem

Dependents:   F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld

Fork of KL46Z-USBHost by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHostHub.cpp Source File

USBHostHub.cpp

00001 #include "USBHost.h"
00002 
00003 #define PORT_CONNECTION   0
00004 #define PORT_ENABLE       1
00005 #define PORT_SUSPEND      2
00006 #define PORT_OVER_CURRENT 3
00007 #define PORT_RESET        4
00008 #define PORT_POWER        8
00009 #define PORT_LOW_SPEED    9
00010 
00011 #define C_PORT_CONNECTION   16
00012 #define C_PORT_ENABLE       17
00013 #define C_PORT_SUSPEND      18
00014 #define C_PORT_OVER_CURRENT 19
00015 #define C_PORT_RESET        20
00016 
00017 bool USBHost::Hub(USBDeviceConnected* dev) {
00018     USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p]", dev->getVid(), dev->getPid(), dev);
00019     HubDescriptor hubdesc;
00020     // get HUB descriptor
00021     int rc = controlRead(dev, 
00022                         USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
00023                         GET_DESCRIPTOR,
00024                         0x29 << 8, 0, reinterpret_cast<uint8_t*>(&hubdesc), 
00025                         sizeof(HubDescriptor));
00026     USB_TEST_ASSERT(rc == USB_TYPE_OK);
00027     if (rc != USB_TYPE_OK) {
00028         return false;
00029     }
00030     USB_DBG_HEX((uint8_t*)&hubdesc, sizeof(hubdesc));
00031 
00032     uint32_t status;
00033     rc = controlRead( dev,
00034                       0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4);
00035     USB_TEST_ASSERT(rc == USB_TYPE_OK);
00036     if (rc != USB_TYPE_OK) {
00037         return false;
00038     }
00039     USB_DBG("HUB STATUS: %08X\n", status);
00040 
00041     for(int i = 1; i <= hubdesc.bNbrPorts; i++) {
00042         SetPortPower(dev, i); // power on
00043         wait_ms(hubdesc.bPwrOn2PwrGood*2);
00044         uint32_t status;
00045         GetPortStatus(dev, i, &status);
00046         USB_DBG("port: %d status: %08X\n", i, status);
00047         if (status & 0x010000) { // Connect Status Change, has changed
00048             USB_TEST_ASSERT(status & 0x000001);
00049             ClearPortFeature(dev, C_PORT_CONNECTION, i);
00050             int lowSpeed = 0;
00051             if (status & 0x0200) {
00052                 lowSpeed = 1;
00053             }
00054             PortReset(dev, i);
00055             if (!addDevice(dev, i, lowSpeed)) {
00056                 ClearPortPower(dev, i); // power off
00057             }
00058         } else {
00059             ClearPortPower(dev, i); // power off
00060         }
00061     }
00062     return false;
00063 }
00064 
00065 
00066 int USBHost::SetPortPower(USBDeviceConnected* dev, int port)
00067 {
00068     return SetPortFeature(dev, PORT_POWER, port);
00069 }
00070 
00071 int USBHost::ClearPortPower(USBDeviceConnected* dev, int port)
00072 {
00073     return ClearPortFeature(dev, PORT_POWER, port);
00074 }
00075 
00076 int USBHost::SetPortFeature(USBDeviceConnected* dev, int feature, int index)
00077 {
00078     return controlWrite(dev, 0x23, SET_FEATURE,feature,index,0,0);
00079 }
00080 
00081 int USBHost::ClearPortFeature(USBDeviceConnected* dev, int feature, int index)
00082 {
00083     return controlWrite(dev, 0x23, CLEAR_FEATURE,feature,index,0,0);
00084 }
00085 
00086 int USBHost::SetPortReset(USBDeviceConnected* dev, int port)
00087 {
00088     return SetPortFeature(dev, PORT_RESET, port);
00089 }
00090 
00091 int USBHost::GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status)
00092 {
00093     return controlRead(dev, 0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
00094 }
00095 
00096 int USBHost::PortReset(USBDeviceConnected* dev, int port)
00097 {
00098     USB_DBG("%p port=%d\n", this, port);
00099     USB_TEST_ASSERT(port >= 1);
00100     SetPortReset(dev, port);
00101     // wait reset
00102     for(int i = 0; i < 100; i++) {
00103         uint32_t status;    
00104         GetPortStatus(dev, port, &status);
00105         USB_DBG("RESET port: %d status: %08X\n", port, status);
00106         if (status & 0x100000) { // Reset change , Reset complete
00107             return USB_TYPE_OK;
00108         }
00109         wait_ms(5);
00110      }
00111      return USB_TYPE_ERROR;
00112 }