espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.77k stars 7.31k forks source link

Can't use PS4 controller when run esp_hid_host demo (IDFGH-8282) #9767

Open wushifu32 opened 2 years ago

wushifu32 commented 2 years ago

Answers checklist.

General issue report

I run the esp_hid_host example to connect to PS4 controller. From the uart.log, the controller is connected. But after that, the controller power led off, and lost the connection. It seems the controller send many input reporter before it power off:

I (12965) ESP_HIDH_DEMO: a0:ab:51:0e:60:2d INPUT:  GAMEPAD, MAP:  0, ID:   1, Len: 9, Data:
I (12975) ESP_HIDH_DEMO: 7c 7f 80 7d 08 00 00 00 00 
I (12985) ESP_HIDH_DEMO: a0:ab:51:0e:60:2d INPUT:  GAMEPAD, MAP:  0, ID:   1, Len: 9, Data:
I (12985) ESP_HIDH_DEMO: 7c 7f 81 7c 08 00 00 00 00 
I (12995) ESP_HIDH_DEMO: a0:ab:51:0e:60:2d INPUT:  GAMEPAD, MAP:  0, ID:   1, Len: 9, Data:
I (13005) ESP_HIDH_DEMO: 7c 7f 82 7c 08 00 00 00 00 

I guess the PS4 controller need some reply form ESP32 to continue? Is there anybody also use esp-idf to connect PS4 controller and meet this issue?

BillPlunkett commented 1 year ago

I experienced the same problem. I believe there are a couple of reasons:

1 - the amount of data received in hidh_callback() appears to cause a deadlock of some kind. To work around this I did the following: case ESP_HIDH_INPUT_EVENT: {

if true

    printf("!\n");
    #else
    const uint8_t *bda = esp_hidh_dev_bda_get(param->input.dev);
    ESP_LOGI(TAG, ESP_BD_ADDR_STR " INPUT: %8s, MAP: %2u, ID: %3u, Len: %d, Data:", ESP_BD_ADDR_HEX(bda), esp_hid_usage_str(param->input.usage), param->input.map_index, param->input.report_id, param->input.length);
    ESP_LOG_BUFFER_HEX(TAG, param->input.data, param->input.length);
    #endif
    break;
}

2 - hid_demo_task() exits. To work around this I did the following:

if true

while (true)
{
    vTaskDelay(1000);
    printf(".\n");
}
#else
vTaskDelete(NULL);
#endif

With these changes, the esp_hid_host_demo example code maintains a connection to the PS4 controller.

boblane1 commented 8 months ago

Hi @wushifu32,

Is this issue still exist? It seems that @BillPlunkett have solve this issue.

leonrinkel commented 8 months ago

@boblane1 I don't think this is solved yet. I'm having the same issue with a PS5 controller. Even with the changes suggested by @BillPlunkett.

BillPlunkett commented 8 months ago

The PS5 is a different story. I was also unable to get it to work.

boblane1 commented 8 months ago

@BillPlunkett @leonrinkel Can you provide some log with PS5?

leonrinkel commented 8 months ago

@boblane1 Here you go. Output stops after a second or so, but esp & controller stay connected.

log.esp_hid_host.20240307122116.txt

boblane1 commented 8 months ago

Hi @leonrinkel,

Thanks for your log. Since I don't have a PS5 on hand, I can only give my guess here.

  1. The log printing in the hidh_callback may take too much time, you can disable the printing
  2. Try to enlarge the queue_size of event_task_args in esp-idf/components/esp_hid/src/bt_hidh.c
  3. Try to increase the task_priority of event_task_args in esp-idf/components/esp_hid/src/bt_hidh.c. For now, the value of task_priority is same with the app_main task, which is equal to 1.

Please let me know if these changes take effect, thanks.

leonrinkel commented 8 months ago

Hi @boblane1, one thing that I tried already is removing the event loop entirely and only calling a small, interrupt-like function instead of esp_event_post_to() for the input event. This still has the same effect of receiving reports for like a second before hanging.

leonrinkel commented 8 months ago

I managed to get it working with the PS5 controller by moving Bluedroid to core 1 (CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=y) and keeping hidh_callback() as slim as possible, i.e. no printing.

boblane1 commented 8 months ago

Great, I am glad you resolved this issue.