Не работает вход / выход конечной точки контроллера LUFA XInput - PullRequest
0 голосов
/ 22 февраля 2019
  • Введение:

Я пытался (и до сих пор не получалось целых четыре дня подряд) заставить мое устройство 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 Task (вызывается каждый цикл):

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?Я в недоумении здесь.

...