Changing ble_app_hids_mouse for trackpad application

Hello guys. I'm helping a customer to work with a trackpad application using the nRF52840 and the nRF5_SDK_17.0.2_d674dde.

For this customer, she wants to use Microchip's touchpad solution (like https://www.microchip.com/en-us/solutions/machine-learning/smart-human-machine-interface)

and add nRF for BLE HID. Since the rep_map_data[] already has the mouse buttons, scroll/pan, mouse motion, advanced buttons (play pause volume down up etc),

I thought I simply need to call mouse_movement_send() - ble_hids_inp_rep_send(INPUT_REP_MOVEMENT_INDEX, INPUT_REP_MOVEMENT_LEN), using the trackpad as the parameter input.

First, for trackpads, do I need to change the rep_map_data[] or can I use it as it is?

We want to create a simple trackpad, like a mouse with volume control gestures, no keys/keyboard.

I was wondering whether a trackpad like this needs additional report map data during the initialization in hids_init().

Next, is it true that DIS - PnP characteristic is mandatory for wireless trackpad/mouse/keyboard applications?

Also, regarding DIS PnP,

PNP_ID_VENDOR_ID_SOURCE = 0x02 /**< Vendor ID Source. */
PNP_ID_VENDOR_ID = 0x1915 /**< Vendor ID. */

am I allowed to use these DIS PNP vendor ID values for this nRF product?

I'm slightly confused with this Nordic thread here  nRF52840 - USB Vendor ID and USB Product ID 

so I was wondering whether I have to register my own vendor ID.

 

Lastly, I want to check how to send a volume key. Is it ble_hids_inp_rep_send(INPUT_REP_MPLAYER_INDEX, INPUT_REP_MEDIA_PLAYER_LEN) ?

I read that I have to send a "mask" value to stop increasing or decreasing the volume so I need your help how to do this properly.

Thank you so much for your help!

REFERENCEs

https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/

https://www.usb.org/sites/default/files/hid1_11.pdf

Parents
  • Hello,

    This sounds like a solution that would require a driver from Microchip. I think you should reach out to them to ask what usb report maps they intended to be used with the trackpad that you are using.

    If they don't have anything to share, this is a more generic USB question than a Nordic Specific. Trust me, if I knew exactly how you needed to set up this report map, I would tell you, but I think you need to look at how report maps are built up and how they are used. 

    Best regards,

    Edvin

  • Thank you for replying Edvin. I think the USB HID spec is the document that describes how report maps are built.

    Let me search for the Microchip driver.

    Come to think of it, if I use Microchip’s USB HID report map for this BLE trackpad application, do I have to use Microchip’s vendor ID for the DIS PnP characteristic?

  • Oh, sorry. Yes. Well, this sample only shows moving the mouse. So each packet consists of a move in x,y directions. Mouses only send changes in position, and not speed, so there is no need to send a message saying it is no longer moving. If you do mouse clicking (left mouse button and right mouse button, for instance), then you need to send a new message with the button no longer being pressed. If not, it will think that the mouse button is being held down forever.

    I don't remember the values for mouse button clicks, but you can use bt_hids_inp_rep_send, with rep_index = INPUT_REP_BUTTONS_INDEX (= 0)

  • Thank you Edvin. Then back to my original questions,

    I want to check how to send a volume key in the mouse example.

    Is it

    uint8_t media_buffer[INPUT_REP_MEDIA_PLAYER_LEN] = {0xEA} // from rep_map_data[] Volume Down ?

    ble_hids_inp_rep_send(&m_hids, INPUT_REP_MPLAYER_INDEX, INPUT_REP_MEDIA_PLAYER_LEN,

    media_buffer, m_conn_handle) ?

    I wasn't sure what value should I send for Volume Down.

    Back to your Microchip touchpad driver part,

    https://github.com/MikroElektronika/mikrosdk_click_v2/blob/master/clicks/touchpad/lib/src/touchpad.c

    just like this code, the drivers I found were SPI drivers.

    The input on the touchpad was sent to a microcontroller using SPI.

    In that case, I can simply use that SPI data to map the mouse data (x_delta and y_delta) and

    send it using

    ble_hids_inp_rep_send(INPUT_REP_MOVEMENT_INDEX, INPUT_REP_MOVEMENT_LEN)

    right?

    Or do I still need to modify the rep_map_data[] in this case?

    Thank you so much for your help!

  • So what do you see when you apply the SPI driver? I assume it will be able to provide you with x and y coordinates, but is it supposed to handle double touch? How about clicks? Does it handle that at all, or is that something that you need to implement on your own?

    BR,

    Edvin

  • Hi Edvin. Yes, the SPI driver handles:

    x y coordinates - touchpad_get_touch_coordinate()

    read single touch / click - touchpad_get_event_state(), I need to implement double touch on my own

    gesture (zoom in/out, two finger touch for mouse right click) - touchpad_get_gesture_type()

    Is a double touch something similar to a mouse double click where the HID rep_map_data[] has to change?

    Thanks for your help

  • Matthew K said:
    Is a double touch something similar to a mouse double click where the HID rep_map_data[] has to change?

    I would think. This is probably something you would want to reach out to USB to know for sure. But a double click is just two single clicks from the nRF's point of view, if I remember correctly. 

    Unfortunately, from a USB HID point of view, we deliver the framework, but as you see, the samples are unfortunately a bit limited, and so is the documentation

    So I think you should look elsewhere for how the report maps work, and then use what we provide to send the reports. 

    Best regards,

    Edvin

Reply
  • Matthew K said:
    Is a double touch something similar to a mouse double click where the HID rep_map_data[] has to change?

    I would think. This is probably something you would want to reach out to USB to know for sure. But a double click is just two single clicks from the nRF's point of view, if I remember correctly. 

    Unfortunately, from a USB HID point of view, we deliver the framework, but as you see, the samples are unfortunately a bit limited, and so is the documentation

    So I think you should look elsewhere for how the report maps work, and then use what we provide to send the reports. 

    Best regards,

    Edvin

Children
  • Thank you Edvin. Then back to my last original question

    I want to check how to send a volume key in the mouse example.

    Is it

    uint8_t media_buffer[INPUT_REP_MEDIA_PLAYER_LEN] = {0xEA} // from rep_map_data[] Volume Down ?

    ble_hids_inp_rep_send(&m_hids, INPUT_REP_MPLAYER_INDEX, INPUT_REP_MEDIA_PLAYER_LEN,

    media_buffer, m_conn_handle) ?

    I wasn't sure what value should I send for Volume Down.

  • What I tried to say is that these are more generic USB questions than Nordic related questions. 

    Perhaps you want to have a look at the Zephyr sample found in NCS\zephyr\samples\subsys\usb\hid-cnc

    Look in the main.c file, in the function ascii_to_hid, and you will see the enum from NCS\zephyr\include\zephyr\usb\class\hid.h.

    This is an enum (that should have been used in our samples as well). It doesn't cover volume control, but you can look in usb_audio.h.

    Perhaps something like this is what you are looking for:

    https://usb.org/sites/default/files/hut1_3_0.pdf

    Scroll down to page 91, and search for "volume". 

    Best regards,

    Edvin

  • Hi Edvin. Luckily, I found a old nRF51 example sending volume up/down

    https://github.com/Rallare/nrf51_ble_app_hids_kbd_consumercontrol/blob/eb9253685fe097f9b0c88212bb51c5e5ff3f7e08/main.c#L220

    consumer_control_send(CONSUMER_CTRL_VOL_UP)

    consumer_control_send(RELEASE_KEY) // not pressed

    where the ENUM (consumer_control_t) was following the usage order from the report_map_data[]:

    0x09, 0xCD,                     //     Usage (Play/Pause) = CONSUMER_CTRL_PLAY 0x01

    0x0A, 0x83, 0x01,               //     Usage (AL Consumer Control Configuration) = CONSUMER_CTRL_ALCCC 0x02

    0x09, 0xB5,                     //     Usage (Scan Next Track) = CONSUMER_CTRL_SCAN_NEXT_TRACK 0x04

    0x09, 0xB6,                     //     Usage (Scan Previous Track) = CONSUMER_CTRL_SCAN_PREV_TRACK 0x08

    0x09, 0xEA,                     //     Usage (Volume Down) = CONSUMER_CTRL_VOL_DW 0x10

    0x09, 0xE9,                     //     Usage (Volume Up) = CONSUMER_CTRL_VOL_UP 0x20

    0x0A, 0x25, 0x02,               //     Usage (AC Forward) = CONSUMER_CTRL_AC_FORWARD 0x40

    0x0A, 0x24, 0x02,               //     Usage (AC Back) = CONSUMER_CTRL_AC_BACK 0x80

    Now I understood so let's close this ticket. Thanks for the help!

Related