x-post from this Stack Overflow question.
This code from TI's ek-tm4c123gxl usb-dev-gamepad CCS example wraps an volatile enum assignment to g_iGamepadState in an interrupt disable/enable pair. To me it looks like a bug; that it should instead be wrapping the send report function USBDHIDGamepadSendReport() to prevent mid-send interruption. As is I would assume this it's preventing the interrupt of a single store instruction, which would be redundant.
Below is the all code which references the enum...
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(); } } }