Go Down

Topic: [solved] Unable to receive HID reports from computer using pluggableUSB (Read 1 time) previous topic - next topic

arandomdev

Hello!

I'm trying to receive HID reports from my computer to my arduino micro, I made my own library that was modeled off of the CDC (Serial), MIDI, and HID-Project libraries. But whenever I call USB_Available, it always returns 0.

I'm using the "SimpleHIDWrite" tool to write data, but when I press write, it says "WRITE ERROR: A device attached to the system is not functioning (1F)." But strangely enough, whenever I press it the RX light blinks, which makes me think that the endpoints are not configured correctly.

Any help is appreciated!

Arandom"dev"

arandomdev

I found the problem, apparently switching the out endpoint from type bulk to interrupt fixed it!

Here's the code with the fix.

USBController.cpp
Code: [Select]
#include "USBController.h"
#include "Arduino.h"

USBController::USBController() : PluggableUSBModule(2, 1, endpointTypes) {
endpointTypes[0] = EP_TYPE_BULK_IN;
endpointTypes[1] = EP_TYPE_INTERRUPT_OUT;
PluggableUSB().plug(this);
}

int USBController::getInterface(uint8_t *interfaceNumber) {
interfaceNumber[0] += 1;
USBControllerHIDDescriptor interfaceDescriptor = {
D_INTERFACE(USBControllerInterface, 2, USB_DEVICE_CLASS_HUMAN_INTERFACE, 0, 0),
USBController_D_HIDREPORT(sizeof(USBControllerReportDescriptor)),
D_ENDPOINT(USB_ENDPOINT_IN(USBControllerEndpointIn), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0),
D_ENDPOINT(USB_ENDPOINT_OUT(USBControllerEndpointOut), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0),
};
return USB_SendControl(0, &interfaceDescriptor, sizeof(interfaceDescriptor));
}

int USBController::getDescriptor(USBSetup &setup) {
// code copied and modified from NicoHood's HID-Project
// check if it is a HID class Descriptor request
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }

// In a HID Class Descriptor wIndex cointains the interface number
if (setup.wIndex != pluggedInterface) { return 0; }

protocol = HID_REPORT_PROTOCOL;

return USB_SendControl(TRANSFER_PGM, USBControllerReportDescriptor, sizeof(USBControllerReportDescriptor));
}

bool USBController::setup(USBSetup &setup) {
// code copied from NicoHood's HID-Project
if (pluggedInterface != setup.wIndex) {
return false;
}

uint8_t request = setup.bRequest;
uint8_t requestType = setup.bmRequestType;

if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
{
if (request == HID_GET_REPORT) {
// TODO: HID_GetReport();
return true;
}
if (request == HID_GET_PROTOCOL) {
// TODO: Send8(protocol);
return true;
}
}

if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
{
if (request == HID_SET_PROTOCOL) {
protocol = setup.wValueL;
return true;
}
if (request == HID_SET_IDLE) {
idle = setup.wValueL;
return true;
}
if (request == HID_SET_REPORT)
{
}
}

return false;
}

int USBController::write(const uint8_t *buffer, size_t size) {
return USB_Send(USBControllerTX, buffer, size);
}

int USBController::read() {
if (USB_Available(USBControllerRX)) {
return USB_Recv(USBControllerRX);
}
else {
return 0;
}
}


USBController.h
Code: [Select]
#ifndef USBController_h
#define USBController_h
#include "Arduino.h"

// make sure that it is a supported Architecture
#ifndef ARDUINO_ARCH_AVR
#error "Unsupported Architecture"
#endif

#include "PluggableUSB.h"
#include "HID.h"

#define USBController_D_HIDREPORT(length) { 9, 0x21, 0x11, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
typedef struct {
InterfaceDescriptor hid;
  HIDDescDescriptor desc;
  EndpointDescriptor in;
EndpointDescriptor out;
} USBControllerHIDDescriptor;
typedef union {
uint8_t dataInHeader[0];
uint8_t dataInBlock[0];
uint8_t dataOutHeader[0];
uint8_t dataOutBlock[0];
struct {
uint8_t dataIn;
uint8_t dataOut;
};
} USBControllerDataPacket;

static const uint8_t USBControllerReportDescriptor[] PROGMEM = {
0x06, 0x00, 0xff,              // USAGE_PAGE (vendor defined page 1)
0x09, 0x00,                    // USAGE (Undefined)
0xa1, 0x01,                    // COLLECTION (Application)
0x85, 0x01,                    //   REPORT_ID (1)
0x09, 0x00,                    //   USAGE (Undefined)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
0x75, 0x08,                    //   REPORT_SIZE (8)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x81, 0x06,                    //   INPUT (Data,Var,Rel)
0x85, 0x02,                    //   REPORT_ID (2)
0x09, 0x00,                    //   USAGE (Undefined)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
0x75, 0x08,                    //   REPORT_SIZE (8)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x91, 0x06,                    //   OUTPUT (Data,Var,Rel)
0xc0                           // END_COLLECTION
};

#define USBControllerInterface pluggedInterface
#define USBControllerEndpointIn pluggedEndpoint
#define USBControllerEndpointOut (pluggedEndpoint + 1)
#define USBControllerTX USBControllerEndpointIn
#define USBControllerRX USBControllerEndpointOut

class USBController : public PluggableUSBModule {
public:
USBController();
int write(const uint8_t *buffer, size_t size);
int read();
private:

protected:
uint8_t endpointTypes[2];
uint8_t protocol;
uint8_t idle;

int getInterface(uint8_t *interfaceNumber);
int getDescriptor(USBSetup &setup);
bool setup(USBSetup &setup);
};

#endif // USBController_h import guard


sketch
Code: [Select]
#include <USBController.h>

USBController controller;
void setup(){
  Serial.begin(9600);
}

void loop(){
  int recv = controller.read();
  if (recv != 0) {
    Serial.println(recv);
  }
}

Go Up