cancel
Showing results for 
Search instead for 
Did you mean: 

USB HID Get Report Callback data is different from Bus Hound sniff data

CYH
Associate II

Hi,

I would like to consult the USB HID GetReport feature.
The issue is that the printout data from MCU log is different from bus hound displayed result.

Bus hound is trial version, the data length indeed is 16.

CYH_0-1749920225104.png

This is the log I set to printout from USBD_HID_Keyboard_SetReport

CYH_2-1749920268498.png

#define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 32
static uint8_t g_last_input_report[17]; // adjust size to match your report
static UINT g_last_input_report_len = 0;

/**
 * @brief  USBD_HID_Keyboard_GetReport
 *         This function is invoked when host is requesting event through
 *         control GET_REPORT request.
 *   hid_instance: Pointer to the hid class instance.
 *   hid_event: Pointer to structure of the hid event.
 * @retval status
 */
UINT USBD_HID_Keyboard_GetReport(UX_SLAVE_CLASS_HID *hid_instance,
		UX_SLAVE_CLASS_HID_EVENT *hid_event) {
	printf(">>> USBD_HID_Keyboard_GetReport invoked\r\n");

	static uint32_t get_report_counter = 0;
	printf("=== GET_REPORT #%lu at %lu ms ===\r\n", ++get_report_counter, HAL_GetTick());

	if (hid_event == UX_NULL || g_last_input_report_len == 0)
		return UX_ERROR;

	//Type1:Input ;; Type3:Feature
	printf(">>> GetReport Request: type=%lu, id=0x%02lX\r\n, Buffer len: %lu\r\n",
			hid_event->ux_device_class_hid_event_report_type,
			hid_event->ux_device_class_hid_event_report_id,
			g_last_input_report_len);

	if (hid_event->ux_device_class_hid_event_report_id== 0x01&&
	    hid_event->ux_device_class_hid_event_report_type == UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT)
	{
		if (g_last_input_report_len <= UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) {
			memcpy(hid_event->ux_device_class_hid_event_buffer,
					g_last_input_report, g_last_input_report_len);
			hid_event->ux_device_class_hid_event_length =
					g_last_input_report_len;

			printf("GetReport:");
			for (UINT i = 0; i < g_last_input_report_len; i++) {
				printf("%02X,", g_last_input_report[i]);
			}
			printf("\r\n");
			return UX_SUCCESS;
		}
	}
	printf("ERROR: Conditions not met, returning UX_ERROR\r\n");
	return UX_ERROR;
}

Also add the log in _ux_device_class_hid_report_get

CYH_3-1749920634381.png

However, in here is still show the different data from bus hound capture though it is still aligned the data in GetReport Callback.

 

The HID descriptor is set as below

__ALIGN_BEGIN uint8_t USBD_HID_KEYBOARD_ReportDesc[]
__ALIGN_END =
{
  /* USER CODE BEGIN USBD_HID_KEYBOARD_ReportDesc             */
  //Wedy Change for customized report
  0x06, 0x00, 0xFF,                   // USAGE PAGE (Vendor Defined)
  0x09, 0xFF,                         // USAGE (Vendor Usage)
  0xA1, 0x01,                         // COLLECTION (Application)

  // Feature Report - Report ID 1
  0x85, 0x01,                       //   REPORT_ID (1)
  0x15, 0x00,                       //   LOGICAL_MINIMUM (0)
  0x25, 0xFF,                       //   LOGICAL_MAXIMUM (255)
  0x75, 0x08,                       //   REPORT_SIZE (8)
  0x95, 0x10,                       //   REPORT_COUNT (16)
  0x09, 0x01,                       //   USAGE (Vendor Specific)
  0x81, 0x02,                       //   INPUT (Data,Var,Abs)

  // Feature Report - Report ID 1 (16 bytes)
  0x85, 0x01,                       //   REPORT_ID (1)
  0x95, 0x10,                       //   REPORT_COUNT (16)
  0x09, 0x02,                       //   USAGE (Vendor Specific)
  0xB1, 0x02,                       //   FEATURE (Data,Var,Abs)

  // Output Report - Report ID 2
  0x85, 0x02,                       //   REPORT_ID (2)
  0x95, 0x11,                       //   REPORT_COUNT (17)
  0x09, 0x01,                       //   USAGE (Vendor Specific)
  0x91, 0x02,                       //   OUTPUT (Data,Var,Abs)
  /* USER CODE END USBD_HID_KEYBOARD_ReportDesc               */
  0xc0               /* End Collection                        */
};

 

10 REPLIES 10
CYH
Associate II

Hi @FBL ,
I found that if I don't proceed _ux_device_class_hid_event_set() inside Keyboard_SendReport as below makred, then I could get the matched data from GetReport.

UINT USBD_HID_Keyboard_GetReport(UX_SLAVE_CLASS_HID *hid_instance,
		UX_SLAVE_CLASS_HID_EVENT *hid_event) {

	/* USER CODE BEGIN USBD_HID_Keyboard_GetReport */
    printf("\r\n=== [GET_REPORT] ===\r\n");

    if (hid_event == UX_NULL || g_last_input_report_len == 0) {
        if (hid_event != UX_NULL) {
            memset(hid_event->ux_device_class_hid_event_buffer, 0, HID_REPORT_TOTAL_SIZE);
            hid_event->ux_device_class_hid_event_length = HID_REPORT_TOTAL_SIZE;
        }
        printf("GetReport ERROR: No data available\r\n");
        return UX_SUCCESS;
    }

    if (hid_event->ux_device_class_hid_event_report_id == 0x01 &&
        hid_event->ux_device_class_hid_event_report_type == UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT) {

        memcpy(hid_event->ux_device_class_hid_event_buffer,
               g_last_input_report, HID_REPORT_TOTAL_SIZE);
        hid_event->ux_device_class_hid_event_length = g_last_input_report_len;

        printf("Final length set = %lu\r\n", hid_event->ux_device_class_hid_event_length);

        printf("USBX sending to host: ");
        for (UINT i = 0; i < hid_event->ux_device_class_hid_event_length; i++) {
          printf("%02X ", hid_event->ux_device_class_hid_event_buffer[i]);
        }
        printf("\r\n");

        return UX_SUCCESS;
    }

    printf("ERROR: Report type/id mismatch or unsupported\r\n");
    return UX_ERROR;
    /* USER CODE END USBD_HID_Keyboard_GetReport */
}

/* USER CODE BEGIN 1 */
///////////////////HID_INPUT_to_HOST//////////////////////
UINT USBD_HID_Keyboard_SendReport(UX_SLAVE_CLASS_HID *hid_instance, uint8_t *report, UINT length)
{
	if (hid_instance == UX_NULL || report == UX_NULL || length == 0)
		return UX_ERROR;

	if (length > HID_REPORT_TOTAL_SIZE) {
	    printf("Error: Output report too large\r\n");
	    return UX_ERROR;
	}

	full_report[0] = 0x01; // Report ID
	memcpy(&full_report[1], report, length);

	// Store for GetReport
	memcpy(g_last_input_report, full_report, HID_REPORT_TOTAL_SIZE);
	g_last_input_report_len = HID_REPORT_TOTAL_SIZE;

	printf("GetReport prepared (Report ID 0x01): ");
	for (UINT i = 0; i < g_last_input_report_len; i++) {
	    printf("%02X ", g_last_input_report[i]);
	}
	printf("\r\n");

	// Do NOT call _ux_device_class_hid_event_set() here if need to support GetReport instead of OutputReport
	/*UX_SLAVE_CLASS_HID_EVENT hid_event;
	hid_event.ux_device_class_hid_event_report_id = 0x01;
	hid_event.ux_device_class_hid_event_report_type =
			UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT;
	hid_event.ux_device_class_hid_event_length = sizeof(full_report)-1;
	memcpy(hid_event.ux_device_class_hid_event_buffer, full_report,
			sizeof(full_report)-1);

	printf("Input report to host: ");
	for (UINT i = 0; i < sizeof(full_report)-1; i++) {
		printf("%02X ", full_report[i]);
	}
	printf("\r\n");

	ux_device_class_hid_event_set(hid_instance, &hid_event);*/

	return UX_SUCCESS;
}

 Does it sounds reasonable? Is that expected to not have input report while system would like to proceed GetReport?