Не работает вход / выход конечной точки контроллера LUFA XInput
- Вступление:
Я пытался (и безуспешно целых четыре дня подряд) заставить свое устройство Atmega32u4 (Arduino Pro Micro) эмулировать контроллер Xbox.
Не нужно делать вид, что это контроллер Xbox, но мне нужно общаться с драйвером XInput, поэтому эмуляция официального контроллера казалась лучшим способом начать.
- Эта проблема:
При использовании примера кода XInputPadMicro от Bootsector он получает меня точно на полпути. Мое устройство может либо читать, либо записывать из / в драйвер устройства. Но не оба. Получение обоих на работу имеет важное значение для моего проекта.
- Код:
Дескриптор устройства / конфигурации можно найти в XInputPadMicro (я не изменил их).
Событие изменения конфигурации: включение конечной точки "OUT" приведет к поломке конечной точки "IN".
#define JOYSTICK_EPADDR_IN (ENDPOINT_DIR_IN | 1)
#define JOYSTICK_EPADDR_OUT (ENDPOINT_DIR_OUT | 1)
void EVENT_USB_Device_ConfigurationChanged(void)
{
bool ConfigSuccess = true;
ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_EPADDR_IN, EP_TYPE_INTERRUPT, 20, 1);
//If I enable this, the "IN" Endpoint will stop sending data.
//ConfigSuccess &= Endpoint_ConfigureEndpoint(JOYSTICK_EPADDR_OUT, EP_TYPE_INTERRUPT, 8, 1);
}
Событие запроса управления USB:
void EVENT_USB_Device_ControlRequest(void)
{
/* Handle HID Class specific requests */
switch (USB_ControlRequest.bRequest)
{
case HID_REQ_GetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(&gamepad_state, 20);
Endpoint_ClearIN();
}
break;
case HID_REQ_SetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(&RXData, 8);
Endpoint_ClearOUT();
}
break;
}
}
HID Задача (называется каждый цикл):
void HID_Task(void)
{
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(JOYSTICK_EPADDR_OUT);
if (Endpoint_IsOUTReceived())
{
toggle = !toggle;
SetLED(LED3, toggle);
Endpoint_Read_Stream_LE(&RXData, 8, NULL);
SetLED(LED1, RXData[3] > 0 || RXData[4] > 0);
Endpoint_ClearOUT();
}
/* Select the Joystick Report Endpoint */
Endpoint_SelectEndpoint(JOYSTICK_EPADDR_IN);
/* Check to see if the host is ready for another packet */
if (Endpoint_IsINReady())
{
/* Write Joystick Report Data */
Endpoint_Write_Stream_LE(&gamepad_state, 20, NULL);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
}
}
Я что-то упустил? Возможно, о внутренней работе протокола USB? Я в недоумении здесь.