Using the FRDM-KL25Z as a USB Mouse Device


I finally completed my project turning the FRDM-KL25Z board into a USB mouse device :-). The form factor and the capabilities of the Freedom board makes it a great board for implementing it as a ‘custom mouse’. All what I need is the USB stack running on it and have it acting as USB HID Mouse device.

FRDM-KL25Z enumerated as USB HID Mouse Device

FRDM-KL25Z enumerated as USB HID Mouse Device

In this post I turned the FRDM-KL25Z into a USB HID keyboard device. Having the same thing, but as USB HID Mouse device is not much different. Although the FSL USB components had to be updated to make things really easy.

USB HID Mouse Project

Creation of a USB HID Mouse project is the same procedure as for the USB HID Keyboard project here: Make sure you set up the clock to 48 MHz and enable the bus clock for the USB block. You might copy or change the USB HID Keyboard project and change it to a USB HID Mouse project too. A link to my project is posted at the end of this article.

FSL USB HID Keyboard Device Component

In the FSL USB component, there is now a selection for the HID Mouse Device:

HID Mouse Device Selection

HID Mouse Device Selection

With this, I can use the FSL_USB_HID_Mouse_Device component:

FSL_USB_HID_Mouse_Device

FSL_USB_HID_Mouse_Device

In that component, similar to the HID Keyboard device, I select the CPU:

Selected Kinetis KL25 CPU

Selected Kinetis KL25 CPU

Optionally I can specify a string for the vendor and the device which will show up on the host. A buffer is used for the update messages sent to the host which can be configured as needed. It is just that this buffer needs to have 4 byte entries as I’m using 4 bytes for the USB messages:

Buffer settings for USB HID Mouse Device

Buffer settings for USB HID Mouse Device

Using the USB HID Mouse Device Class

The component offers the following methods and events:

FSL_USB_Stack with FSL_USB_HID_Mouse_Device

FSL_USB_Stack with FSL_USB_HID_Mouse_Device

  • App_Task() needs to be called periodically by the application. The method sends the data from the buffer.
  • isEnumerated() return TRUE or FALSE to know if the mouse device has been enumerated on the USB bus.
  • Send() is used to add ‘raw’ data packets to the buffer to be sent. This allows greater flexibility.
  • Move() is using internally Send(), with a simpler interface. With Move() I can send a message that the mouse has moved, with x and y (delta) values.
  • Click() is used to send a mouse click message. It uses a parameter to tell which button(s) are pressed.
  • Init() initializes the module, and is called automatically from the FSL_USB_Stack component.

Example Project

To test the functionality, I’m using this source:

void APP_Run(void) {
  int cnt=0; /* counter to slow down LED blinking */

  for(;;) {
    WAIT1_Waitms(10);
    cnt++;
    if (HIDK2_App_Task()==ERR_BUSOFF) {
      if ((cnt%128)==0) { /* just slow down blinking */
        LEDG_Off();
        LEDR_Neg();
      }
    } else {
      if ((cnt%128)==0) { /* just slow down blinking */
        LEDR_Off();
        LEDG_Neg();
      }
      if (SW1_GetVal()==0) { /* button pressed */
        WAIT1_Waitms(100); /* wait for debouncing */
        if (SW1_GetVal()==0) { /* still pressed */
          //(void)HIDK2_Send(0, 8, 8); /* raw move message */

          //(void)HIDK2_Send(HIDK2_MOUSE_LEFT, 0, 0); /* send left mouse button */
          //(void)HIDK2_Send(0, 0, 0); /* send release button message */

          //(void)HIDK2_Move(-8, 0); /* moving the cursor up */

          //HIDK2_Click(HIDK2_MOUSE_LEFT); /* left mouse click */

          HIDK2_Click(HIDK2_MOUSE_RIGHT); /* right mouse click */
        }
        while(SW1_GetVal()==0) {} /* wait until button is released */
      }
    }
  }
}

:!: Depending on how Processor Expert names your components, you might need to use something like HIDM1_ instead of HIDK2_ as in my example.

The application is using the reset button on the FRDM-KL25Z board to send mouse messages. As long the board is not connected, it is blinking the red RGB LED. Once connected, it blinks green.

Enumerated HID Mouse Device in Windows

Enumerated HID Mouse Device in Windows

Pressing the SW1 button will send one of the messages in the examples.

HIDK2_Click(HIDK2_MOUSE_LEFT);

sends a click message, followed by a release event. This would be the same as sending the ‘raw’ date with

(void)HIDK2_Send(HIDK2_MOUSE_LEFT, 0, 0); /* send left mouse button */
(void)HIDK2_Send(0, 0, 0); /* send release button message */

With the Send() method, the first parameter is the state of the button, followed by x and y offsets for moves.

Moving the mouse is done with

(void)HIDK2_Move(3, 5); /* moving the cursor*/

which uses an x and a y offset.

Summary

An example project is available on GitHub here. Make sure you update your Processor Expert components (see here). I have now a simple starting point for using the KL25Z as a USB mouse device. It should be easy to add the accelerometer part to it, so I can have an ‘air mouse’. Let’s see if I’ll find time to add that functionality. Additionally, as the USB HID allows great flexibility, a generic USB HID device would be something I’m interested in. Or a USB composite device with USB HID Keyboard and USB HID mouse.

Happy Mousing :-)

About these ads

17 thoughts on “Using the FRDM-KL25Z as a USB Mouse Device

  1. Pingback: How to use the Kenetis KL25Z Freedom board as an HID mouse

  2. Pingback: USB for the Freescale ARM Kinetis KL46Z and K21D50M | MCU on Eclipse

  3. Hi!
    I have a problem with USB initialization. It looks like after USB1_init() ( USB1 is FSL_USB_Stack ) processor is stuck at USB_ISR() ( callback in usb_dci_kinetis.c ). Device is not found by a system ( Win7 ).
    What should I do?
    Thanks in advance!
    MG

    • Hi MG,
      I don’t have hardware with me, so I cannot check it. But maybe it is because of a recent change I did? :-(. If you are using my latest example project with source, can you add the following define to
      #define USB_USER_CONFIG_USE_STACK_INIT 1
      (either as a compiler predefine or add it temporarily to usb_user_config.h
      to check if this helps?

      • Hi MG,
        Happy New Year to you too. Sorry about this problem, I should have it tested more with all my boards. I have commited a fix already on GitHub (sources only, not to the *.PEupd Files).
        I tested it with the FRDM-KL26Z (this is the only board I have right now with me), and it works. I need to complete some driver work for the FRDM-KL26Z, then I will publish new *.PEupd files.

  4. Hi Erich, You know whether it is possible implement the USB HID class (neither hid mouse nor hid keyboard) on the kinetis kl25z for sending data to the host ( either VB.NET or another software)!

    Best regards

  5. Hi Erich,

    I was just playing about this this code, making an air mouse of my own and was trying to add vertical and horizontal scrolling capacity.

    From what I can decipher from http://msdn.microsoft.com/en-us/library/windows/hardware/Dn613912%28v=vs.85%29.aspx , the data should be sent as byte 4 and 5 of the input report, but unfortunately the USB stack component only allows buffer up to 4.

    Is there any way I could change to a 5 bit buffer?
    (note: I have no experience building or modifying PE component templates at the moment)

    • Changing the buffer descriptor from 4 to 5 bytes is not so difficult in the component. I think I should provide a setting for this. What will not be so straight forwared is extending the ring buffer to 5 byte elements: that’s something I need to carefully look at. I need to see how much time I could spend on this as time is not what I have right now :-(

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s