Per Mårtensson 3 жил өмнө
parent
commit
59421f0834
10 өөрчлөгдсөн 679 нэмэгдсэн , 46 устгасан
  1. 65 16
      src/configparse.cpp
  2. 197 0
      src/keybboarddecode.cpp
  3. 251 0
      src/keyboardpipe.cpp
  4. 77 0
      src/keyboardpipe.h
  5. 12 13
      src/parse_hid.cpp
  6. 1 1
      src/parse_hid.h
  7. 26 12
      src/pipe.cpp
  8. 6 2
      src/pipe.h
  9. 2 0
      src/port.h
  10. 42 2
      src/usb.h

+ 65 - 16
src/configparse.cpp

@@ -12,7 +12,7 @@
 #include "hcd.h"
 #include "esp_log.h"
 #include "configparse.h"
-
+static const char TAG[] = __FILE__;
 
 char *USBHostConfigParser::class_to_str(uint8_t cls)
 {
@@ -83,7 +83,6 @@ uint8_t* USBHostConfigParser::parse_cfg_descriptor(uint8_t *data_buffer, uint8_t
     uint8_t type = *(&data_buffer[0] + offset + 1);
     do
     {
-        ESP_LOGD("", "type: %d", type);
         *_type = type;
         switch (type)
         {
@@ -118,6 +117,7 @@ uint8_t* USBHostConfigParser::parse_cfg_descriptor(uint8_t *data_buffer, uint8_t
         }
         case USB_W_VALUE_DT_INTERFACE:
         {
+
             ESP_LOGV("", "Interface:");
             usb_desc_intf_t *data = (usb_desc_intf_t *)(data_buffer + offset);
             offset += data->bLength;
@@ -133,7 +133,8 @@ uint8_t* USBHostConfigParser::parse_cfg_descriptor(uint8_t *data_buffer, uint8_t
         case USB_W_VALUE_DT_ENDPOINT:
         {
             ESP_LOGV("", "Endpoint:");
-            usb_desc_ep_t *data = (usb_desc_ep_t *)(data_buffer + offset);
+            usb_desc_ep_t 
+            *data = (usb_desc_ep_t *)(data_buffer + offset);
             offset += data->bLength;
             ESP_LOGV("", "bEndpointAddress: 0x%02x", data->bEndpointAddress);
             ESP_LOGV("", "bmAttributes: 0x%02x", data->bmAttributes);
@@ -146,10 +147,23 @@ uint8_t* USBHostConfigParser::parse_cfg_descriptor(uint8_t *data_buffer, uint8_t
         case 0x21:
         {
             ESP_LOGD("", "HID descriptor");
-            uint8_t *data = (data_buffer + offset);
-            offset += data[0];
-            ESP_LOGD("Report map size", "0x%x", (uint16_t)data[7]);
-            // report_map_size = (uint16_t)data[7];
+            usb_desc_hid_t 
+            *data = (usb_desc_hid_t *)(data_buffer + offset);
+            offset += data->bLength;
+            ESP_LOGV(TAG,"Length %i",data->bLength);
+            ESP_LOGV("", "bDescriptorType: %d", data->bDescriptorType);
+            ESP_LOGV("", "HIDBCD: %d", data->wBcdHID);
+            ESP_LOGV("", "CountryCode: 0x%02x", data->bCountryCode);
+            ESP_LOGV("", "bNumDescriptor: %d", data->bNumDescriptors);
+            ESP_LOGV("", "wDescriptorLength: %d", data->wDescriptorLength);
+            ESP_LOGV("", "bDescrType: 0x%02x", data->bDescrType);
+            	for (uint32_t i = 0; i < data->bNumDescriptors; ++i)
+                {
+                    hid_class_descriptor_len_and_type	*pLT = (hid_class_descriptor_len_and_type*)&(data->bDescrType);
+
+                    ESP_LOGV("","ConfigDescParser::PrintHidDescriptor : bDescrType: %d\r\n", pLT[i].bDescrType);
+                    ESP_LOGV("","ConfigDescParser::PrintHidDescriptor : wDescriptorLength: %d\r\n", pLT[i].wDescriptorLength);
+                }
             *out = (uint8_t *)data;
             break;
         }
@@ -174,24 +188,53 @@ uint8_t* USBHostConfigParser::parse_cfg_descriptor(uint8_t *data_buffer, uint8_t
 uint8_t* USBHostConfigParser::getInterfaceByClass(uint8_t *data, uint8_t cls)
 {
     uint8_t *ep;
+    uint8_t *ep2;
     uint8_t type;
     uint8_t *next = data + sizeof(usb_ctrl_req_t);
+
+    bool output = false;
     do
     {
+        ESP_LOGV(TAG,"cfg_desc");
+
         next = parse_cfg_descriptor(next, &ep, &type);
         if (type == 0x0)
             break;
-        if (ep && type == USB_W_VALUE_DT_INTERFACE)
+        if (ep && type == USB_W_VALUE_DT_INTERFACE && (((usb_desc_intf_t *)ep)->bInterfaceProtocol == 0x01 /*|| ((usb_desc_intf_t *)ep)->bInterfaceProtocol == 0x00 */ )) // Last part is just to get only keyboards
         {
-            ESP_LOGV("", "find interface class: %s", class_to_str(cls));
+            ESP_LOGV("", "Keyboard: %s", class_to_str(cls));
+            ESP_LOGV("", "Find interface class: %s", class_to_str(cls));
             if (!cls || ((usb_desc_intf_t *)ep)->bInterfaceClass == cls) // IN EP
             {
-                ESP_LOGV("", "found interface class: %s", class_to_str(((usb_desc_intf_t *)ep)->bInterfaceClass));
-                return ep;
+                ESP_LOGV("", "Found interface class: %s", class_to_str(((usb_desc_intf_t *)ep)->bInterfaceClass));
+                output=true;
+                ep2=ep;
+
             }
         }
-    } while (1);
+        
+        if (ep && type == USB_W_VALUE_DT_INTERFACE && (((usb_desc_intf_t *)ep)->bInterfaceProtocol == 0x20 )) // Last part is just to get only keyboards
+        {
+            ESP_LOGV("", "Keyboard: %s", class_to_str(cls));
+            ESP_LOGV("", "Find interface class: %s", class_to_str(cls));
+            if (!cls || ((usb_desc_intf_t *)ep)->bInterfaceClass == cls) // IN EP
+            {
+                ESP_LOGV("", "Found interface class: %s", class_to_str(((usb_desc_intf_t *)ep)->bInterfaceClass));
+                output=true;
+                ep2=ep;
+
+            }
+        }
+        
+        if (ep && type == USB_W_VALUE_DT_INTERFACE && ((usb_desc_intf_t *)ep)->bInterfaceProtocol == 0x02 ) // Last part is just to get only mouse
+        {
+            ESP_LOGV("", "Mouse: %s", class_to_str(cls));
 
+        }
+    } while (1);
+    if (output){
+        return ep2;
+    }
     return NULL;
 }
 
@@ -200,21 +243,27 @@ uint8_t* USBHostConfigParser::getEndpointByDirection(uint8_t *interface, uint8_t
     uint8_t *ep;
     uint8_t type;
     uint8_t *next = interface;
+    bool match = false;
+
     do
     {
+        
         next = parse_cfg_descriptor(next, &ep, &type);
         if (type == 0x0)
             break;
-        if (ep && type == USB_W_VALUE_DT_ENDPOINT)
+        if (ep && type == USB_W_VALUE_DT_ENDPOINT )
         {
-            ESP_LOGV("", "we have new endpoint");
+            ESP_LOGV(TAG, "We have new endpoint %02x",USB_DESC_EP_GET_EP_NUM((usb_desc_ep_t *)ep) );
             if (!dir || (USB_DESC_EP_GET_EP_DIR((usb_desc_ep_t *)ep) == dir)) // IN EP == 1
             {
-                return ep;
+                match=true;
+                break;
             }
         }
     } while (1);
-
+    if (match){
+        return ep;
+    }   
     return NULL;
 }
 

+ 197 - 0
src/keybboarddecode.cpp

@@ -0,0 +1,197 @@
+/*
+    if(inByte == 27)
+    {
+       flag_esc = 1;
+    }   
+    else
+    {
+      if(flag_esc==1)
+      {
+        // Previous char was ESC - Decode all the escaped keys
+        switch(inByte)
+        {
+            case 0x49:
+              Serial.print("[PgUp]");
+              break;
+            case 0x51:
+              Serial.print("[PgDn]");
+              break;    
+            case 0x47:
+              Serial.print("[Home]");
+              break;
+            case 0x4F:
+              Serial.print("[End]");
+              break;     
+            case 0x52:
+              Serial.print("[Ins]");
+              break;
+            case 0x53:
+              Serial.print("[Del]");
+              break;               
+            case 0x3B:
+              Serial.print("[F1]");
+              break;
+            case 0x3C:
+              Serial.print("[F2]");
+              break;    
+            case 0x3D:
+              Serial.print("[F3]");
+              break;
+            case 0x3E:
+              Serial.print("[F4]");
+              break;     
+            case 0x3F:
+              Serial.print("[F5]");
+              break;
+            case 0x40:
+              Serial.print("[F6]");
+              break;          
+            case 0x41:
+              Serial.print("[F7]");
+              break; 
+            case 0x42:
+              Serial.print("[F8]");
+              break; 
+            case 0x43:
+              Serial.print("[F9]");
+              break; 
+            case 0x44:
+              Serial.print("[F10]");
+              break; 
+            case 0x57:
+              Serial.print("[F11]");
+              break; 
+            case 0x58:
+              Serial.print("[F12]");
+              break;     
+            case 0x48:
+              Serial.print("[Up]");
+              break; 
+            case 0x50:
+              Serial.print("[Down]");
+              break; 
+            case 0x4B:
+              Serial.print("[Left]");
+              break; 
+            case 0x4D:
+              Serial.print("[Right]");
+              break;         
+            case 0x54:
+              Serial.print("[Print]");
+              break; 
+            case 0x5B:
+              Serial.print("[Windows]");
+              break;   
+            default:
+              Serial.print("[?]");
+              break;            
+        }
+        flag_esc=0;    
+      }
+      else
+      {  
+
+        if(inByte==1)
+        {
+           Serial.print("Control-A");
+        }  
+        else if(inByte==2)
+        {
+           Serial.print("Control-B");
+        }
+        else if(inByte==3)
+        {
+           Serial.print("Control-C");
+        }
+        else if(inByte==4)
+        {
+           Serial.print("Control-D");
+        }
+        else if(inByte==5)
+        {
+           Serial.print("Control-E");
+        }
+        else if(inByte==6)
+        {
+           Serial.print("Control-F");
+        }
+        else if(inByte==7)
+        {
+           Serial.print("Control-G");
+        }
+        // Dont decode 8 - backspace
+        else if(inByte==9)
+        {
+           Serial.print("Tab");
+        }
+        // Dont decode 10 - Line Feed
+        else if(inByte==11)
+        {
+           Serial.print("Control-K");
+        }
+        else if(inByte==12)
+        {
+           Serial.print("Control-L");
+        }
+        // Dont decode 13 - Carriage Return
+        else if(inByte==14)
+        {
+           Serial.print("Control-N");
+        }
+        else if(inByte==15)
+        {
+           Serial.print("Control-O");
+        }
+        else if(inByte==16)
+        {
+           Serial.print("Control-P");
+        }
+        else if(inByte==17)
+        {
+           Serial.print("Control-Q");
+        }
+        else if(inByte==18)
+        {
+           Serial.print("Control-R");
+        }
+        else if(inByte==19)
+        {
+           Serial.print("Control-S");
+        }
+        else if(inByte==20)
+        {
+           Serial.print("Control-T");
+        }
+        else if(inByte==21)
+        {
+           Serial.print("Control-U");
+        }
+        else if(inByte==22)
+        {
+           Serial.print("Control-V");
+        }
+        else if(inByte==23)
+        {
+           Serial.print("Control-W");
+        }
+        else if(inByte==24)
+        {
+           Serial.print("Control-X");
+        }
+        else if(inByte==25)
+        {
+           Serial.print("Control-Y");
+        }        
+        else if(inByte==26)
+        {
+           Serial.print("Control-Z");
+        }
+
+        else   
+        {
+          // Its a normal key
+          Serial.write(inByte);
+        }  
+      }
+    }  
+*/

+ 251 - 0
src/keyboardpipe.cpp

@@ -0,0 +1,251 @@
+#include <cstring>
+#include "configparse.h"
+#include "keyboardpipe.h"
+static const char TAG[] = __FILE__;
+extern void parse_hid_report_map(uint8_t *map, size_t size);
+
+ /** dont change order of callbacks
+ * port and EPs/pipes local callbacks
+ */
+IRAM_ATTR static void ctrl_pipe_cb(pipe_event_msg_t msg, usb_irp_t *irp, USBHostPipe *pipe)
+{
+    usb_ctrl_req_t *ctrl = (usb_ctrl_req_t *)irp->data_buffer;
+    ext_pipe_event_msg_t event = msg.event + BASE_PIPE_EVENT;
+    switch (msg.event)
+    {
+    case HCD_PIPE_EVENT_NONE:
+        break;
+    case HCD_PIPE_EVENT_IRP_DONE:
+    {
+        ESP_LOGI("Pipe: ", "XFER status: %d, num bytes: %d, actual bytes: %d", irp->status, irp->num_bytes, irp->actual_num_bytes);
+        usb_ctrl_req_t *ctrl = (usb_ctrl_req_t *)irp->data_buffer;
+
+        if (ctrl->bRequest == USB_B_REQUEST_GET_DESCRIPTOR)
+        {
+            event = BASE_PIPE_EVENT + ctrl->bRequest + (ctrl->wValue);
+            if (ctrl->wValue == USB_W_VALUE_DT_CONFIG << 8)
+            {
+                if (irp->actual_num_bytes)
+                {
+                    USBHostKeyboard *p = (USBHostKeyboard *)pipe->port;
+                    if (p->begin(irp->data_buffer))
+                    {
+                        usbh_keyboard_device_ready();
+                    }
+                } else if ((ctrl->wValue >> 8) == 0x22) // HID report map descriptor
+                {
+                    ESP_LOGI("", "HID report map");
+                    for (int i = 0; i < (irp->actual_num_bytes + 8); i++)
+                    {
+                        ets_printf("%02x ", irp->data_buffer[i]);
+                    }
+                    parse_hid_report_map(irp->data_buffer + 8, irp->actual_num_bytes);
+                }
+                
+            }
+        }
+        else if (ctrl->bRequest == USB_B_REQUEST_GET_CONFIGURATION)
+        {
+        }
+        else if (ctrl->bRequest == USB_B_REQUEST_SET_CONFIGURATION)
+        {
+        }
+        else if (ctrl->bRequest == USB_B_REQUEST_SET_ADDRESS)
+        {
+        }
+        // HID CLASS specific events
+
+        break;
+    }
+    }
+
+    if (pipe->port->ctrl_callback != NULL)
+    {
+        pipe->port->ctrl_callback(event, irp);
+    }
+}
+
+IRAM_ATTR static void port_cb(port_event_msg_t msg, USBHostPort *p)
+{
+    static USBHostKeyboard *port = (USBHostKeyboard *)p;
+    hcd_port_state_t state;
+    switch (msg.port_event)
+    {
+    case HCD_PORT_EVENT_CONNECTION:
+    {
+        ESP_LOGD("", "physical connection detected");
+        // we are ready to establish connection with device
+        if (port->connect())
+        {
+            // create ctrl callback
+            USBHostPipe *pipe = new USBHostPipe();
+            pipe->port = port;
+            port->addCTRLpipe(pipe);
+            pipe->onPipeEvent(ctrl_pipe_cb);
+            pipe->getDeviceDescriptor();
+            pipe->setDeviceAddress(port->address);
+        }
+        break;
+    }
+    case HCD_PORT_EVENT_SUDDEN_DISCONN:
+        // OPTIMIZE this is called before event in port.cpp to delete all pipes here to properly recover port later in port.cpp
+        if (port->inpipe)
+            delete (port->inpipe);
+        if (port->outpipe)
+            delete (port->outpipe);
+        break;
+
+    default:
+        ESP_LOGW("", "port event: %d", msg.port_event);
+        break;
+    }
+}
+
+static void in_pipe_cb(pipe_event_msg_t msg, usb_irp_t *irp, USBHostPipe *pipe)
+{
+    if (((USBHostKeyboard *)pipe->port)->data_in != NULL)
+    {
+        ESP_LOGV("", "callback IN: %d", irp->status);
+        ((USBHostKeyboard *)pipe->port)->data_in(msg.event, irp);
+    }
+    switch (msg.event)
+    {
+    case HCD_PIPE_EVENT_IRP_DONE:
+        ESP_LOGD("Pipe cdc: ", "XFER status: %d, num bytes: %d, actual bytes: %d", irp->status, irp->num_bytes, irp->actual_num_bytes);
+        break;
+
+    case HCD_PIPE_EVENT_ERROR_XFER:
+        ESP_LOGW("", "XFER error: %d", irp->status);
+        pipe->reset();
+        break;
+
+    case HCD_PIPE_EVENT_ERROR_STALL:
+        ESP_LOGW("", "Device stalled CDC pipe, state: %d", pipe->getState());
+        pipe->reset();
+        break;
+
+    default:
+        break;
+    }
+    // previous IRP dequeued, time to send another request
+    pipe->inData();
+}
+static void out_pipe_cb(pipe_event_msg_t msg, usb_irp_t *irp, USBHostPipe *pipe)
+{
+    if (((USBHostKeyboard *)pipe->port)->data_out != NULL)
+    {
+        ESP_LOGV("", "callback out: %d", irp->status);
+        ((USBHostKeyboard *)pipe->port)->data_out(msg.event, irp);
+    }
+    switch (msg.event)
+    {
+    case HCD_PIPE_EVENT_IRP_DONE:
+        ESP_LOGD("Pipe HID: ", "XFER status: %d, num bytes: %d, actual bytes: %d", irp->status, irp->num_bytes, irp->actual_num_bytes);
+        break;
+
+    case HCD_PIPE_EVENT_ERROR_XFER:
+        ESP_LOGW("", "XFER error: %d", irp->status);
+        pipe->reset();
+        break;
+
+    case HCD_PIPE_EVENT_ERROR_STALL:
+        ESP_LOGW("", "Device stalled HID pipe, state: %d", pipe->getState());
+        pipe->reset();
+        
+        break;
+
+    default:
+        break;
+    }
+    // previous IRP dequeued, time to send another request
+    //pipe->outData();
+}
+bool USBHostKeyboard::init()
+{
+    return USBHostPort::init(port_cb);
+}
+
+// initialize endpoints after getting config descriptor
+bool USBHostKeyboard::begin(uint8_t *irp)
+{
+    USBHostConfigParser parser;
+    uint8_t *itf1 = parser.getInterfaceByClass(irp, USB_CLASS_HID);
+    if (itf1 != nullptr)
+    {
+        uint8_t *ep = parser.getEndpointByDirection(itf1, 1);
+        if (ep)
+        {
+            inpipe = new USBHostPipe(handle);
+            inpipe->onPipeEvent(in_pipe_cb);
+            inpipe->init((usb_desc_ep_t *)ep, address);
+            inpipe->port = this;
+        }
+
+        ep = parser.getEndpointByDirection(itf1, 0);
+        if (ep)
+        {
+            outpipe = new USBHostPipe(handle);
+            outpipe->onPipeEvent(out_pipe_cb);
+            outpipe->init((usb_desc_ep_t *)ep, address);
+            outpipe->port = this;
+        }
+
+        if (inpipe != nullptr && outpipe != nullptr)
+            return true;
+    }
+    return false;
+}
+
+void USBHostKeyboard::setIdle()
+{
+    usb_irp_t *irp = ctrlPipe->allocateIRP(0);
+    USB_CTRL_SET_IDLE((usb_ctrl_req_t *)irp->data_buffer);
+
+    esp_err_t err;
+    if(ESP_OK != (err = hcd_irp_enqueue(ctrlPipe->getHandle(), irp))) {
+        ESP_LOGW("", "SET_IDLE enqueue err: 0x%x", err);
+    }
+}
+
+void USBHostKeyboard::getHidReportMap()
+{
+    usb_irp_t *irp = ctrlPipe->allocateIRP(70);
+    USB_CTRL_GET_HID_REPORT_DESC((usb_ctrl_req_t *)irp->data_buffer, 0, 70);
+
+    esp_err_t err;
+    if(ESP_OK != (err = hcd_irp_enqueue(ctrlPipe->getHandle(), irp))) {
+        ESP_LOGW("", "SET_IDLE enqueue err: 0x%x", err);
+    }
+}
+
+
+void USBHostKeyboard::onDataIn(ext_usb_pipe_cb_t cb)
+{
+    data_in = cb;
+    uint8_t *buf = new uint8_t[9];
+
+}
+
+void USBHostKeyboard::sendData(uint8_t *data2, size_t len)
+{
+                
+    
+    printf("TESTxxx");
+    usb_irp_t *irp = ctrlPipe->allocateIRP(8);
+    memcpy(irp->data_buffer, data2, len);
+    uint8_t data =data2[0];
+    USB_CTRL_SET_HID_REPORT_CONF((usb_ctrl_req_set_t *)irp->data_buffer,1,1,data);
+    esp_err_t err;
+    if (ESP_OK != (err = hcd_irp_enqueue(ctrlPipe->getHandle(), irp)))
+    {
+        ESP_LOGW("", "CTRL OUT enqueue err: 0x%x", err);
+    }
+}
+                
+
+
+
+void USBHostKeyboard::onDataOut(ext_usb_pipe_cb_t cb)
+{
+    data_out = cb;
+}

+ 77 - 0
src/keyboardpipe.h

@@ -0,0 +1,77 @@
+#pragma once
+#include "hcd.h"
+#include "usb.h"
+#include "port.h"
+#include "pipe.h"
+
+#define SET_VALUE       0x21
+#define SET_IDLE        0x0A
+
+#define USB_CTRL_SET_IDLE(ctrl_req_ptr) ({  \
+    (ctrl_req_ptr)->bRequestType = SET_VALUE;   \
+    (ctrl_req_ptr)->bRequest = SET_IDLE;  \
+    (ctrl_req_ptr)->wValue = (0x0);   \
+    (ctrl_req_ptr)->wIndex = (0);    \
+    (ctrl_req_ptr)->wLength = (0);   \
+})
+
+#define USB_CTRL_GET_HID_REPORT_DESC(ctrl_req_ptr, desc_index, desc_len) ({  \
+    (ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_IN | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_INTERFACE;   \
+    (ctrl_req_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR;   \
+    (ctrl_req_ptr)->wValue = (0x22<<8) | ((desc_index) & 0xFF); \
+    (ctrl_req_ptr)->wIndex = 0;    \
+    (ctrl_req_ptr)->wLength = (desc_len);  \
+})
+#define USB_CTRL_SET_HID_REPORT_CONF(ctrl_req_ptr, desc_index, desc_len,data) ({  \
+     (ctrl_req_ptr)->bRequestType = 0x21;   \
+    (ctrl_req_ptr)->bRequest =   USB_B_REQUEST_SET_CONFIGURATION;   \
+    (ctrl_req_ptr)->wValue = (0x02<<8); \
+    (ctrl_req_ptr)->wIndex = 0;    \
+    (ctrl_req_ptr)->wLength = (desc_len);  \
+    (ctrl_req_ptr)->data = data; \
+})
+
+void usbh_keyboard_device_ready();
+
+// TODO
+// FIXME refactor class to inherit from port class
+class USBHostKeyboard : public USBHostPort
+{
+private:
+
+public:
+    USBHostKeyboard() : USBHostPort() {}
+    USBHostKeyboard(uint8_t addr) : USBHostPort(addr) {}
+    bool begin(uint8_t *);
+    bool init();
+    void setIdle();
+    void getHidReportMap();
+
+    // OPTIMIZE move to parent class??
+    /**
+     * @brief Register on data IN callback
+     */
+    /**
+     * @brief Enqueue send data requests on OUT endpoint pipe
+     */
+    void sendData(uint8_t *, size_t);
+
+    // OPTIMIZE move to parent class??
+    /**
+     * @brief Register on data IN callback
+     */
+    void onDataIn(ext_usb_pipe_cb_t);
+
+    /**
+     * @brief Register on data OUT callback
+     */
+    void onDataOut(ext_usb_pipe_cb_t);
+    // OPTIMIZE make them private or protected
+    // class related callbacks and pipes
+    ext_usb_pipe_cb_t data_in;
+    ext_usb_pipe_cb_t data_out;
+    USBHostPipe *inpipe;
+    USBHostPipe *outpipe;
+};
+
+// USBH_WEAK_CB void usbh_mouse_device_ready(){}

+ 12 - 13
src/parse_hid.cpp

@@ -6,7 +6,7 @@
 #else
 #include "esp_log.h"
 #endif
-
+static const char TAG[] = __FILE__;
 static uint8_t global_item = 0;
 static uint8_t local_item = 0;
 static uint8_t usage_page_item = 0;
@@ -64,41 +64,40 @@ static void setup_input_device()
     switch (usage_page_item)
     {
     case GENERIC_DESKTOP_POINTER:
-        ets_printf("generic desktop pointer\n");
+        ESP_LOGI(TAG,"generic desktop pointer\n");
         if(set_x) setup_x_axis();
         // if(set_y) setup_y_axis();
         if(set_buttons) setup_buttons();
         if(set_wheel) setup_wheel();
-
         break;
 
     case GENERIC_DESKTOP_MOUSE:
-        ets_printf("generic desktop mouse\n");
+        ESP_LOGI(TAG,"generic desktop mouse\n");
         // setup_mouse();
         break;
 
     case GENERIC_DESKTOP_JOYSTICK:
-        ets_printf("generic desktop joystick\n");
+        ESP_LOGI(TAG,"generic desktop joystick\n");
         break;
 
     case GENERIC_DESKTOP_GAMEPAD:
-        ets_printf("generic desktop gamepad\n");
+        ESP_LOGI(TAG,"generic desktop gamepad\n");
         break;
 
-    case GENERIC_DESKTOP_KEYBAORD:
-        ets_printf("generic desktop keyboard\n");
+    case GENERIC_DESKTOP_KEYBOARD:
+        ESP_LOGI(TAG,"generic desktop keyboard\n");
         break;
 
     case GENERIC_DESKTOP_KEYPAD:
-        ets_printf("generic desktop keypad\n");
+        ESP_LOGI(TAG,"generic desktop keypad\n");
         break;
 
     case GENERIC_DESKTOP_MULTIAXIS:
-        ets_printf("generic desktop multi-axis\n");
+        ESP_LOGI(TAG,"generic desktop multi-axis\n");
         break;
 
     case GENERIC_DESKTOP_BUTTON:
-        ets_printf("generic desktop button\n");
+        ESP_LOGI(TAG,"generic desktop button\n");
         set_buttons = true;
         setup_buttons();
         break;
@@ -190,7 +189,7 @@ static void parse_local_item(uint8_t type, uint8_t len, uint8_t *val)
     {
         value += val[i] << (i * 8);
     }
-
+    ESP_LOGI(TAG,"feature type2: %02x \n", type);
     // ets_printf("local type: %02x, len: %d, value: %d\n", type, len, value);
     switch (type)
     {
@@ -231,7 +230,7 @@ inline void parse_feature_item(uint8_t type, uint8_t len, uint8_t *val)
         value += val[i] << (i * 8);
     }
 
-    // ets_printf("feature type: %02x, len: %d, value: %d\n", type, len, value);
+    ESP_LOGI(TAG,"feature type: %02x, len: %d, value: %d\n", type, len, value);
     switch (type)
     {
     case 0x80:

+ 1 - 1
src/parse_hid.h

@@ -38,7 +38,7 @@
 #define GENERIC_DESKTOP_MOUSE           0x02
 #define GENERIC_DESKTOP_JOYSTICK        0x04
 #define GENERIC_DESKTOP_GAMEPAD         0x05
-#define GENERIC_DESKTOP_KEYBAORD        0x06
+#define GENERIC_DESKTOP_KEYBOARD        0x06
 #define GENERIC_DESKTOP_KEYPAD          0x07
 #define GENERIC_DESKTOP_MULTIAXIS       0x08
 #define GENERIC_DESKTOP_BUTTON          0x09

+ 26 - 12
src/pipe.cpp

@@ -18,7 +18,7 @@ static void pipe_event_task(void *p)
 
         usb_ctrl_req_t *ctrl = (usb_ctrl_req_t *)irp->data_buffer;
         uint8_t* data = irp->data_buffer + sizeof(usb_ctrl_req_t);
-
+        bool cb_ok = true;
         switch (msg.event)
         {
         case HCD_PIPE_EVENT_NONE:
@@ -62,7 +62,11 @@ static void pipe_event_task(void *p)
             else if (ctrl->bRequest == USB_B_REQUEST_SET_CONFIGURATION)
             {
                 ESP_LOGD("", "set current configuration: %d", ctrl->wValue);
-                ctrl_pipe->getConfigDescriptor(255);
+                if (ctrl->wValue==512){
+                    cb_ok=false;
+                }else{
+                    ctrl_pipe->getConfigDescriptor(255);
+                }
             }
             else if (ctrl->bRequest == USB_B_REQUEST_SET_ADDRESS)
             {
@@ -74,6 +78,7 @@ static void pipe_event_task(void *p)
             {
                 ESP_LOG_BUFFER_HEX_LEVEL("Ctrl data", ctrl, sizeof(usb_ctrl_req_t), ESP_LOG_WARN);
                 ESP_LOGD("", "unknown request handled: %d", ctrl->bRequest);
+                cb_ok = false;
             }
 
             break;
@@ -93,7 +98,7 @@ static void pipe_event_task(void *p)
             break;
         }
 
-        if (ctrl_pipe && ctrl_pipe->callback != NULL)
+        if (ctrl_pipe && ctrl_pipe->callback != NULL )
         {
             ctrl_pipe->callback(msg, irp, ctrl_pipe);
         }
@@ -140,7 +145,7 @@ void USBHostPipe::onPipeEvent(pipe_cb_t cb)
     callback = cb;
 }
 
-void USBHostPipe::init(usb_desc_ep_t *ep_desc, uint8_t addr)
+void USBHostPipe::init(usb_desc_ep_t *ep_desc, uint8_t addr,uint8_t dir)
 {
     // TODO add config parse object to check if it is actually endpoint data
     usb_speed_t port_speed;
@@ -170,8 +175,12 @@ void USBHostPipe::init(usb_desc_ep_t *ep_desc, uint8_t addr)
     if (ESP_OK != hcd_pipe_alloc(port_hdl, &config, &handle))
         ESP_LOGE("", "cant allocate pipe");
 
-    if (ep_desc != NULL)
+    if (ep_desc != NULL && dir)
         memcpy(&endpoint, ep_desc, sizeof(usb_desc_ep_t));
+    if (ep_desc != NULL && !dir){
+        ESP_LOGD("TAG","VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\r\n");
+        memcpy(&endpointout, ep_desc, sizeof(usb_desc_ep_t));
+    }
 }
 
 void USBHostPipe::freePipe()
@@ -344,32 +353,37 @@ void USBHostPipe::freeIRP(usb_irp_t *irp)
 
 void USBHostPipe::inData(size_t size)
 {
-    ESP_LOGV("", "EP: 0x%02x", USB_DESC_EP_GET_EP_NUM(&endpoint));
-    if(!USB_DESC_EP_GET_EP_DIR(&endpoint)) return;
+    ESP_LOGV(TAG, "EP: 0x%02x, DIR:  0x%02x\r\n", USB_DESC_EP_GET_EP_NUM(&endpoint),USB_DESC_EP_GET_EP_DIR(&endpoint));
+
+    if(!USB_DESC_EP_GET_EP_DIR(&endpoint) ) return;
     size_t len = endpoint.wMaxPacketSize;
     usb_irp_t *irp = allocateIRP(size ? size : len);
 
     esp_err_t err;
     if (ESP_OK != (err = hcd_irp_enqueue(handle, irp)))
     {
-        ESP_LOGW("", "IN endpoint 0x%02x enqueue err: 0x%x", USB_DESC_EP_GET_EP_NUM(&endpoint), err);
+        ESP_LOGW(TAG, "IN endpoint 0x%02x enqueue err: 0x%x", USB_DESC_EP_GET_EP_NUM(&endpoint), err);
     }
 }
 
 void USBHostPipe::outData(uint8_t *data, size_t len)
 {
-    ESP_LOGV("", "EP: 0x%02x", USB_DESC_EP_GET_EP_NUM(&endpoint));
-    if(USB_DESC_EP_GET_EP_DIR(&endpoint)) return;
+    
+    ESP_LOGV("", "EP: 0x%02x, DIR:  0x%02x\r\n", USB_DESC_EP_GET_EP_NUM(&endpointout),USB_DESC_EP_GET_EP_DIR(&endpointout));
+    if(USB_DESC_EP_GET_EP_DIR(&endpointout)) return;
     usb_irp_t *irp = allocateIRP(len);
     memcpy(irp->data_buffer, data, len);
 
     esp_err_t err;
     if (ESP_OK != (err = hcd_irp_enqueue(handle, irp)))
     {
-        ESP_LOGW("", "BULK OUT enqueue err: 0x%x", err);
+        ESP_LOGW(TAG, "BULK OUT enqueue err: 0x%x", err);
     }
 }
-
+void USBHostPipe::outKeyboard(uint8_t *data, size_t len)
+{
+    
+}
 hcd_pipe_handle_t USBHostPipe::getHandle()
 {
     return handle;

+ 6 - 2
src/pipe.h

@@ -55,6 +55,7 @@ class USBHostPipe
 protected:
     //
     hcd_pipe_handle_t handle;
+     hcd_pipe_handle_t handleout;
     // 
     hcd_port_handle_t port_hdl;
     // 
@@ -62,7 +63,9 @@ protected:
 public:
     // friend void pipe_event_task(void *p);
     // 
+
     usb_desc_ep_t endpoint;
+    usb_desc_ep_t endpointout;
     // 
     pipe_cb_t callback = nullptr;
     // 
@@ -84,7 +87,7 @@ public:
     /**
      * @brief Initialize pipe from endpoint data
      */
-    void init(usb_desc_ep_t *ep_desc = nullptr, uint8_t addr = 0);
+    void init(usb_desc_ep_t *ep_desc = nullptr, uint8_t addr = 0,uint8_t dir = 1);
 
     /**
      * @brief Free all queues and pipe belongs to this object
@@ -130,11 +133,12 @@ public:
      * @brief Send data IN request
      */
     void inData(size_t size = 0);
-
+   
     /**
      * @brief Send data OUT request
      */
     void outData(uint8_t *data, size_t len);
+    void outKeyboard(uint8_t *data, size_t len);
 
 // ------------------- standard USB requests ------------------------ //
     /**

+ 2 - 0
src/port.h

@@ -44,12 +44,14 @@ class USBHostPort
 protected:
     // port handle
     hcd_port_handle_t handle;
+    hcd_port_handle_t handleout;
     // control pipe
     USBHostPipe *ctrlPipe;
     static bool port_ready;
 
 public:
     uint8_t address = 0;
+
     port_evt_cb_t callback;
     USBHostPort();
     USBHostPort(uint8_t addr);

+ 42 - 2
src/usb.h

@@ -159,7 +159,18 @@ typedef union {
     uint8_t val[USB_CTRL_REQ_SIZE];
 } usb_ctrl_req_t;
 _Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_req_t incorrect");
-
+typedef union {
+    struct {
+        uint8_t bRequestType;
+        uint8_t bRequest;
+        uint16_t wValue;
+        uint16_t wIndex;
+        uint16_t wLength;
+        uint8_t data;
+    } USB_CTRL_REQ_ATTR;
+    uint8_t val[USB_CTRL_REQ_SIZE];
+} usb_ctrl_req_set_t;
+_Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_req_t incorrect");
 /**
  * @brief Bit masks belonging to the bRequestType field of a setup packet
  */
@@ -423,6 +434,29 @@ typedef union {
 } usb_desc_ep_t;
 _Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t incorrect");
 
+#define USB_DESC_HID_SIZE      9
+
+
+typedef union {
+    struct {
+    uint8_t  bLength;
+    uint8_t  bDescriptorType;
+    uint16_t wBcdHID;           // Hid protocol version followed
+    uint8_t  bCountryCode;      // Country code
+    uint8_t  bNumDescriptors; 
+    uint8_t	 bDescrType;	  // The number of other special descriptors
+    uint16_t wDescriptorLength; // Length of other special descriptors
+        } USB_DESC_ATTR;
+    uint8_t val[USB_DESC_HID_SIZE];
+}usb_desc_hid_t;
+_Static_assert(sizeof(usb_desc_hid_t) == USB_DESC_HID_SIZE, "Size of usb_desc_hid_t incorrect");
+
+#define USB_DESC_HID_DESCRIPTOR_SIZE      3
+typedef struct
+{
+	uint8_t		bDescrType;				// Type of class descriptor
+    uint16_t	wDescriptorLength;		// Total size of the Report descriptor
+} hid_class_descriptor_len_and_type;
 /**
  * @brief Bit masks belonging to the bEndpointAddress field of an endpoint descriptor
  */
@@ -454,7 +488,13 @@ _Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t
 #define USB_DESC_EP_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
 #define USB_DESC_EP_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
 #define USB_DESC_EP_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
-
+#define USB_CTRL_SET_HID_REPORT_CONF(ctrl_req_ptr, desc_index, desc_len) ({  \
+    (ctrl_req_ptr)->bRequestType = 0x21; /*USB_B_REQUEST_TYPE_DIR_OUT | USB_B_REQUEST_TYPE_TYPE_CLASS | USB_B_REQUEST_TYPE_RECIP_INTERFACE;  \*/ \
+    (ctrl_req_ptr)->bRequest = USB_B_REQUEST_SET_CONFIGURATION;  \
+    (ctrl_req_ptr)->wValue = (0x02 ) ;\
+    (ctrl_req_ptr)->wIndex = (desc_len);    \
+    (ctrl_req_ptr)->wLength = (desc_len);   \
+})
 // ------------------ String Descriptor --------------------
 
 /**