Достигает ли что-нибудь эта пара прерывания-отключения-включения из примера проекта TI на геймпаде?

Этот код из примера CCS TI ek-tm4c123gxl usb-dev-gamepad оборачивает энергозависимое присваивание перечисления g_iGamepadState в паре прерывание / включение. Для меня это выглядит как ошибка; что вместо этого следует обернуть функцию отчета об отправке USBDHIDGamepadSendReport(), чтобы предотвратить прерывание во время посылки. Как я полагаю, это предотвращает прерывание одной инструкции хранилища, которая была бы избыточной.

Ниже приведен весь код, который ссылается на перечисление...

volatile enum {
    eStateNotConfigured,            // Not yet configured.
    eStateIdle,                     // Connected, not waiting on data to be sent
    eStateSuspend,                  // Suspended
    eStateSending                   // Connected, waiting on data to be sent out
} g_iGamepadState;

...

//*****************************************************************************
//
// Handles asynchronous events from the HID gamepad driver.
//
// \param pvCBData is the event callback pointer provided during
// USBDHIDGamepadInit().  This is a pointer to our gamepad device structure
// (&g_sGamepadDevice).
// \param ui32Event identifies the event we are being called back for.
// \param ui32MsgData is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the HID gamepad driver to inform the application
// of particular asynchronous events related to operation of the gamepad HID
// device.
//
// \return Returns 0 in all cases.
//
//*****************************************************************************
uint32_t GamepadHandler(void *pvCBData, uint32_t ui32Event,
        uint32_t ui32MsgData, void *pvMsgData) {
    switch (ui32Event) {
    case USB_EVENT_CONNECTED: {
        g_iGamepadState = eStateIdle;
        break;
    }
    case USB_EVENT_DISCONNECTED: {
        g_iGamepadState = eStateNotConfigured;
        break;
    }
    case USB_EVENT_TX_COMPLETE: {
        g_iGamepadState = eStateIdle;
        break;
    }
    case USB_EVENT_SUSPEND: {
        g_iGamepadState = eStateSuspend;
        break;
    }
    case USB_EVENT_RESUME: {
        g_iGamepadState = eStateIdle;
        break;
    }

    ...

    default: {
        break;
    }
    }

    return (0);
}

...

int main(void) {

    ...

    // Not configured initially.
    g_iGamepadState = eStateNotConfigured;

    ...


    while (1) {
        //
        // Wait here until USB device is connected to a host.
        //
        if (g_GamepadState == eStateIdle) {

            ...

            USBDHIDGamepadSendReport(&g_sGamepadDevice, &sReport,
                    sizeof(sReport));

            //
            // Now sending data but protect this from an interrupt since
            // it can change in interrupt context as well.
            //
            IntMasterDisable();
            g_iGamepadState = eStateSending;
            IntMasterEnable();
        }
    }
}

1 ответ

С форума TI E2E...

Я думаю, что вы правы. Это может быть ошибкой.

Событие Idle TX может вернуться между отправкой отчета и переходом в перечисление состояния отправки, которое затем никогда не покинет состояние отправки. Это объяснение, по-видимому, имеет смысл в том, почему пара прерываний "отключить / включить" существует в первую очередь.

Другие вопросы по тегам