Manage HID output reports in nrf connect sdk

(context nrfconnect, nrf52840)

Hello Hakon,

I am making a USB HID, with 2 OUT reports in my descriptor. 

I use the .int_out_ready

interrupt with some success to get my out report from a PC.

(CONFIG_USB_HID_REPORTS not set)

however,with a 

hid_int_ep_read(hdev,data_from_pc,64,&ret_bytes);

the USB frames for out reports bigger than 16 bytes get sliced in chuncks of 16 bytes (4 .int_out_ready interrupts of 16 bytes each, for a 57 bytes out report).

My descriptor has already been used in another product with no problem.

I have tried what you describe, but I don't even get the 

.set_report interrupt.
when I send the out report from the PC

which is worse in a sense.


I come here because doing what's described here does not help me.

And the CONFIG_USB_HID_REPORTS=2 does not make any sense for me.

I have no problem with the IN reports.

I use hidapi on the PC. And the 

Here is the current state of my code (in report code  not shown ).


static void int_in_ready_cb(const struct device *dev)
{
    ARG_UNUSED(dev);
    if (!atomic_test_and_clear_bit(hid_ep_busyHID_EPIN_BUSY_FLAG)) {
        LOG_WRN("IN endpoint callback without preceding buffer write");
    }
}

uint8_t data_from_pc[65];

static void int_out_ready_cb(const struct device *dev)
{
    ARG_UNUSED(dev);
    uint32_t ret_bytes;
    hid_int_ep_read(hdev,data_from_pc,64,&ret_bytes);
    if (ret_bytes>2)
        processReceivedUSBMessage(data_from_pc);
}


int set_report_cb(const struct device *devstruct usb_setup_packet *setupint32_t *lenuint8_t **data)
{
    uint8_t request_value[2];
    sys_put_le16(setup->wValuerequest_value);
    switch (request_value[1]) {
        case 0x02: // REPORT_TYPE_FEATURE
//          LOG_INF("Output report ID: %x", request_value[0]);
            processReceivedUSBMessage(*data);

            break;
        default:
            LOG_INF("Req: %x"request_value[1]);
            break;
    }
    return 0;
}

static const struct hid_ops ops =
{
    .int_in_ready = int_in_ready_cb,
//  .on_idle = on_idle_cb,
//  .protocol_change = protocol_cb,
//  .int_out_ready = int_out_ready_cb,
    .set_report = set_report_cb
};

static void status_cb(enum usb_dc_status_code statusconst uint8_t *param)
{
    switch (status) {
    case USB_DC_RESET:
    case USB_DC_DISCONNECTED:
        configured = false;
        break;
    case USB_DC_CONFIGURED:
        if (!configured) {
            int_in_ready_cb(hdev);
            configured = true;
        }
        break;
    case USB_DC_SOF:
        break;
    default:
        LOG_DBG("status %u unhandled"status);
        break;
    }
}

void usbEnable(void)
{
    int ret = usb_enable(status_cb);
    if (ret != 0)
    {
        LOG_ERR("Failed to enable USB");
        return;
    }
}



static int composite_pre_init(const struct device *dev)
{
    hdev = device_get_binding("HID_0");
    if (hdev == NULL) {
        LOG_ERR("Cannot get USB HID Device");
        return -ENODEV;
    }

    LOG_INF("HID Device: dev %p"hdev);

    usb_hid_register_device(hdevhid_report_descsizeof(hid_report_desc), &ops);

    atomic_set_bit(hid_ep_busyHID_EPIN_BUSY_FLAG);

    if (usb_hid_set_proto_code(hdevHID_BOOT_IFACE_CODE_NONE))
    {
        LOG_WRN("Failed to set Protocol Code");
    }

    return usb_hid_init(hdev);
}

SYS_INIT(composite_pre_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);



###########################################
# Configs for USB
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_HID=y
CONFIG_USB_DEVICE_PRODUCT="xxxx"
#CONFIG_USB_HID_BOOT_PROTOCOL=y
CONFIG_USB_DEVICE_VID=0xxxxx
CONFIG_USB_DEVICE_MANUFACTURER="xxxx"
CONFIG_USB_DEVICE_PID=0xxxx

CONFIG_LOG=y
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y

CONFIG_USB_DEVICE_SOF=n
CONFIG_USB_HID_REPORTS=2
CONFIG_ENABLE_HID_INT_OUT_EP=y
#################################
#end of the report descriptor for the out reports
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x85, 0x80, // REPORT_ID (128)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x10, // REPORT_COUNT (16)
0x09, 0x00, // USAGE (Undefined)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)
0x85, 0x81, // REPORT_ID (129)
0x95, 0x38, // REPORT_COUNT (36)
0x09, 0x00, // USAGE (Undefined)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)
0xC0 /*     END_COLLECTION              */
when I was using the .int_out_ready
received ID= 129 reports were sliced by chunks of 16 bytes, I have changed the report so that both 128 and 129 reports can accept 36 bytes.
I have paid attention to uninstall the usb hid drivers in the PC 
But that would not be enough.
Related