2017-02-12 83 views
0

来自TI的ek-tm4c123gxl usb-dev-gamepad CCS示例的这段代码将中断禁用/使能对中的volatile枚举赋值包装为g_iGamepadState。对我来说,它看起来像一个bug;它应该包装发送报告功能USBDHIDGamepadSendReport()以防止中间发送中断。正如我所假设的那样,它可以防止单个存储指令的中断,这将是多余的。TI的游戏手柄示例项目中断禁用/启用对是否可以完成任何操作?

下面是所有代码引用枚举...

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(); 
     } 
    } 
} 
+0

中断禁用/启用的位置也会引起我的错误。在该示例中,如果在调用USBHIDGamepadSendReport之后但在IntMasterDisable()之前获得TX_COMPLETE响应的中断,会发生什么情况?你会遇到eStateSending状态。 – Prismatic

+0

@Prismatic通过TI代码,通常最好遵循它们的相同顺序 –

+0

尽管如此,我遇到了一个问题。以他们的例子为例,我的游戏手柄控制器在一段时间后停止工作(而不是一段时间后)。调试器似乎显示它卡在主while循环中。状态不是NotConfigured,Suspend或Idle,所以我猜测它坚持发送。它可能的中断禁用/启用放置不正确,导致我的问题。虽然TI工程师可以在e2e上发布,但可能会更好。 – Prismatic

回答

0

TI的E2E forum ...

我认为你是正确的。这可能是一个错误。

在发送报告和更改为发送状态枚举之间,Idle TX事件可能会返回,然后它将永远不会离开发送状态。这个解释似乎是最重要的,为什么禁用/启用中断对在那里。