This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

HID Mouse keeps sending unneeded data!

Hi,

I've got my USB HID Mouse and Keyboard working perfectly. However, I can't seem to figure out how to prevent the device from sending unneeded packets whenever there is no movement (00 00 00 00 ....) How can I prevent this and only allow packets to be send when the device senses movement (button push).

Thank you!

  • This post is the sequel of this thread.
    http://www.keil.com/forum/docs/thread11461.asp

    When you follow Keil example, you may send the Input report in the USB IN Endpoint (EP) interrupt handler (ISR). The ISR is called every time when the host reads out the IN EP. That is, this interrupt is triggered by the host side event. However, you want to send the report just when you detect button change. That is, it is triggered by the device side (user) event.

    That is why the EP ISR is not suitable for your purpose.
    Simply send the Input report when you detect button change.
    It means that the FIFO filler routine, USB_WriteEP(), is called in the main loop task, or in another ISR like timer ISR.

    Most of USB examples handles the USB FIFO in its EP ISR.
    This method is applied just when you need maximum transfer speed.
    You have to know that it isn't the only way to handle the USB FIFO.
    You can fill or unload USB FIFO anywhere on your firmware.
    This understanding brings you flexibility of the control scheme of the firmware.

    When you call USB_WriteEP or USB_ReadEP outside of the USB ISR, you have to disable USB interrupt around these calls. These FIFO handler accesses to the USB registers. If the USB interrupt occurs while these routines touch the USB registers, conflict occurs between these routine and the USB ISR. This is the reason why the USB interrupt is disabled around these routine.

    volatile BOOL usb_InEP_empty = TRUE;
    BOOL key_changed = FALSE;
    
    //
    // Endpoint 1 interrupt handler
    //
    void USB_EndPoint1 (DWORD event) {
       if ( event == USB_EVT_IN )
          usb_InEP_empty = TRUE;           // just set the empty flag
    }
    
    //
    // send keyboard report to host
    //
    BOOL send_keyboard_report( void ) {
       if ( usb_InEP_empty ) {
          //
          // fill an input report to InReport here
          //
          usb_InEP_empty = FALSE;
    
          VICIntEnClr  |= 0x00400000;      // Disable USB Interrupt
          USB_WriteEP( 0x81, &InReport, sizeof(InReport) );
          VICIntEnable |= 0x00400000;      // Enable USB Interrupt
    
          return TRUE;
       }
       return FALSE;
    }
    
    //
    // Default Interrupt Function: may be called when USB ISR is disabled
    //
    void DefISR (void) __irq  {
      ;
    }
    
    int main( void ) {
       //
       // initialization comes here
       //
                                  // ISR for un-assigned VIC interrupts
       VICDefVectAddr = (unsigned long) DefISR;
    
       while (1) {                // main loop
          if ( timer_flag ) {     // task1: key scan
             timer_flag = FALSE;
             scan_keyboard();
          }
          if ( key_changed )      // task2: send keyboard report
             key_changed = ! send_keyboard_report();
          }
          //
          // other tasks comes here
          //
       }
       return 0;
    }