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 🙂

59 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

    Like

    • 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?

      Like

        • 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.

          Like

  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

    Like

  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)

    Like

    • 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 😦

      Like

  6. Hello Erich

    i have a problem running the mouse example. Just startet to work with the freedom board.
    I have a KL46Z board. I have imported the “FRDM-KL46Z48M_USB_HID_Mouse” to KDS 3.0 (with KSDK 12) and
    Generated the PE Code.
    When i try to build the project i got 3 warnings (Invalid project path) for:
    \ARM_GCC_Support\ewl\EWL_C\include)
    \ARM_GCC_Support\ewl\EWL_Runtime\include
    \Project_Headers

    The EWL files found under C:\Freescale\CW MCU v10.6\MCU\ARM_GCC_Support\ewl, but dont know how to Change the include path in this project, to point to the right folder.

    The Project_Headers i coulnd find anywhere, there i missing a lot of .h files (USB1.h, USB0.h, HIDM1.h, Tx3.h, CS1.h)

    What can i do about it?

    Best regards
    Dorian

    Like

    • Hi Dorian,
      the EWL includes are CodeWarrior specific. Remove them from the compiler include path settings (project properties). KDS is using GNU gcc, and it will find its own header files automatically.
      About USB1.h, etc: they shall be present by Processor Expert code generation in Generated_Code folder.

      I hope this helps,
      Erich

      Like

      • Hello Erich,
        i’m sorry i didn’t answer before.
        Thank you very much for your answer, now i could get it working in Codewarrior 🙂 In KDS i still have some minor problems, but i’ll get it to work.
        One of my problems was that i copyed the McuOnEclipse_PEx library to the wrong place.

        Best regards,
        Dorian

        Like

  7. Greetings, im having trouble moving mouse cursor… im using 2 chanels of ADC wich each one configures vertical and horizontal movement depending on ADC ranges… for example: in vertical chanel is in the “down” range so set movement like this (void)HIDM1_Send(0,2);
    And then goes back to read ADC.
    But cursor wont move… I hope you can help me… everything else seems good as PCs detect my KL25Z as a FSL HID Mouse.

    Like

    • Hello, does it move if you don’t do the ADC sampling? Not sure what your sampling frequency is, but if your microcontroller is busy doing only the sampling and not serving the USB requests, no mouse movement will be sent.

      Like

      • I didn’t use it without ADC, besides, I had the ADC in continuous sampling, I changed it to one conversion but it still don´t move… should I do the ADC by interruption?

        Like

        • Try to reduce your problem. Turn off everything you don’t need. ADC sampling is not what you need now, so don’t do it. Just do USB communication. Use my working example as base and go from there. Make baby steps and debug them and check if it is working or not. If it is not working, check the difference from the previous working step.

          Like

      • Erich,
        I’ve done a new project with nothing but sequential functions that call HIDM1_Move/Click but cursor still don´t move, but my PC still recognizes kl25z as a mouse.
        (I’m so sorry for being so bad but its the fist time i use usb configuration… and thank you a lot for the support ).

        Like

        • Are you using my example as posted with this article: here the mouse shall move. Verify that, and then add your ADC code to it. I believe you are still missing something, so I recommend to use that code/example as a base.

          Like

    • I finally did it, my basic problem was that i didn’t undestantd the concept that the functions MOVE and CLICK only filled the buffers that later are send by APP_TASK… so I only was filling buffers without sending them… Besides I can say that it actually can work with 2 channels of ADC in continuous sampling, the only thing that “lags” its when you configure ADC’s in average mode.
      Excelent work and thank you very much Erich. 😀

      Like

      • Ah, that makes sense now. If you just created the events but were not sending them they won’t reach the other side :-). The reason is that as a device you cannot send USB messages: they have to be requested by the host. So all what you can do is to queue messages, and hope that they are retrieved by the host which is handled with the AppTask() routine.
        In average ADC mode the sampling takes longer for the averaging.

        Like

  8. Hi! Please help me with a very desperating situation. I`m trying to make an air-mouse but it doesnt appear the option HID MOUSE DEVICE. It only appears the option HID KEYBOARD DEVICE and I cant figure out why. Please, help me! What should I do?

    Like

  9. Hi again,

    I hope you won`t block me because im already annoying. I want to ask you one more thing: I made a project like yours and when I run the project on my KL25Z, nothing happens and I want to know what I am doing wrong. Do I have to change some settings in my laptop? I mean: do I have to set the board to be seen as a mouse from my laptop? Am I jumping some steps?
    I mention that I`ve downloaded https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/CodeWarrior/FRDM-KL25Z/Freedom_USB_HID_Mouse and opened with CodeWarrior and again, when I press run nothing happens. Please give me an advice or something. Thank you for your time.
    Regards!

    Like

  10. Hi Erich,
    It wasn`t a trick. I was confused of how should I use the open SDA port and USB port. First, I had to run the application using SDA port and then I had to switch the cable into the USB port. I was really confused, especially because I`m a very begginer. Now I want to remove the usb cable and make an wireless connection and I`m searching for the best solution. Can you give me an advice or something? Thank you and sorry for the late response, I`ve just seen your answer!

    Regards!

    Like

  11. Hi Erich,
    can I use this PEx component to make the board act like a MIDI USB device? If so, what should I change to make the computer recognize it as such device and how do I send the data?
    Thanks in advance for the reply 🙂

    Like

    • No, not really. With USB, the device needs to confirm to a certain protocol/class, e.g. USB HID or USB CDC. I have not used MIDI over USB, and I believe there is a USB MIDI class defined. But that class/protocol in not implemented with this component set. You certainly could change/extend the existing code to implement a USB MIDI device, but this will require some USB knowledge on your side.

      Like

  12. Hi Erich,

    As the device class is specified in the FSL USB component, is there any way to use two device classes with the same USB of KL25Z? For instance, HID mouse and HID keyboard devices ?

    Best Regards,

    Marcelo

    Like

      • Hi Erich,
        OK, I understand. but how can I do it if the FSL_USB_Stack component allow me to choose just one single device class?
        Marcelo

        Like

        • Hi Marcelo,
          I had no need for it, so I did not implement it. But you certainly can do it yourself and combine multiple device classes (not sure how familiar you are with USB).
          You can generate code for one class and then disable the code generation (https://mcuoneclipse.com/2012/03/23/disable-my-code-generation/) and then add the other class.
          You have to come up with your own USB device descriptor, best if you search the USB specifications (or the internet) for that level of information.
          I hope this helps,
          Erich

          Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.