HID Advanced Remote

Table of Contents

Introduction

HID Advanced Remote is a demonstration which exercises many areas of the BLE stack in a single application. The application demonstrates an implementation of the (Human Interface Device) HID over GATT profile (HoGP) where Keyboard and Consumer Control reports are used. Voice is demonstrated using a custom Voice over GATT profile.

This document discusses the procedure use the HID Advanced Remote for evaluation, as well as how various systems within in demo function.

Hardware Prerequisites

The default HID Advanced Remote configuration requires the modified configuration of an CC2650RC kit, where the CC2650 is replaced by a CC2640R2F. The hardware is shown below:

Additionally, to program/debug the HID Advanced Remote Project, a Debugger DevPack should be used. Attach this as shown below, where the JTAG connector and Groove Connector are exposed.

For custom hardware, see the Running the SDK on Custom Boards section of the BLE-Stack User’s Guide for Bluetooth 4.2.

To test the Voice over GATT profile, a CC2650 Launchpad is needed.

To test the HID Profile, a BLE capable smart phone may be utilized.

Software Prerequisites

For information on what versions of Code Composer Studio and IAR Embedded Workbench to use, see the Release Notes located in the docs/blestack folder. For information on how to import this project into your IDE workspace and build/run, please refer to The CC2640R2F Platform section in the BLE-Stack User’s Guide for Bluetooth 4.2.

For Voice over GATT testing, refer to simple_central_audio_reciever for the Launchpad.

Functional Description

Hardware Overview

Hardware Available on Remote

The following table contains information on the hardware resources and peripherals on the Remote.

Component Manufacturer Product
Wireless MCU Texas Instruments CC2650
Digital Microphone Knowles SPH0641LM4H-1
Motion Sensor Invensense MPU-9250
Memory Macronix MX25R8035F
Load Switch Texas Instruments TPS22910AYZV
Shift Register Texas Instruments SN74LV164A
IR LED Everlight IR333-A
Bi-Color LED Kingbright APHB1608SGEC

Powering Remote

The remote can be powered by two ways, via AAA batteries, or by utilizing the Debugger DevPack.

To insert the batteries, ensure they are facing the correct direction, the positive ends of the batteries towards the bottom of the remote.

To power from the Debugger DevPack, simply connect a USB cable to the DevPack.

Software Overview

This section describes software components and the corresponding source file.

Application

Project Files Description
hid_adv_remote.c Top level application. Initialization of hardware, connection settings, key handling and voice streaming control.
kcb.c Key press handling.
util.c This file contains utility functions commonly used by BLE applications for CC26xx with TI-RTOS.

The main application task can be found hid_adv_remote.c. Besides setting up advertisement and scan response data and connection related parameters in HIDAdvRemote_init, this task processes key press events and handles the API for voice streaming.

Profiles And Services

Project Files Description
audio_profile.c TI Audio Profile Voice over BLE service.
hiddev.c HID Profile. Support HID reads, writes, queuing reports, register services and device states.
hidkbdccservice.c HID Service. Service for keyboard and consumer control reports.
battservice.c Battery Service.
devinfoservice.c Device Information Service.
scanparamsservice.c Scan Parameter Service.

HID Profile

All HID over GATT Profile related functionality is abstracted from the application task and is handled in a separate task implemented in hiddev.c. This task handles:

The following services are defined in the HID profile specification as either mandatory or optional. The hid_adv_remote project includes all these services:

Service Requirement Supported
HID Service Mandatory Yes
Battery Service Mandatory Yes
Device Information Service Mandatory Yes
Scan Parameter Service Optional Yes

The Battery Service, Device Information Service and Scan Parameter Service are all adopted services and the specification for each service can be found at developer.bluetooth.org.

HID Terminology

Name Description
HID Host The target machine that the user interacts with (e.g. Laptop, tablet, smartphone, etc…)
Report Host A Report Host is a HID Host that is required to support a HID Parser and be able to handle HID reports with arbitrary formats.
Boot Host A Boot Host is a HID Host that is not required to support a HID Parser as all Reports for the Boot Protocol Mode have predefined length and format.
HID Device The device that is used by the user to interact with the Host (e.g. Keyboard, mouse, remote control, game controller, etc…)
HID Report A data message sent between the host and device. Input Reports go from HID Device to HID Host, such as a key press. Output reports go from HID Host to HID Device, such as a PC changing the caps lock LED on a keyboard.
HID Report Descriptor A data structure that the device sends to the host which describes the HID device’s capabilities, including the types, sizes, and directions of the reports that are supported. In HID over GATT this is also referred to as the Report Map.

Voice over GATT Profile

The audio data is transmitted using a proprietary service with UUID 0xF000B00004514000B000000000000000. This service is composed of the following 2 characteristics:

Name UUID Description Properties
AUDIOPROFILE_START 0xF000B00104514000B000000000000000 Audio control point, it accepts start/stop commands GATT_PROP_READ | GATT_PROP_NOTIFY
AUDIOPROFILE_AUDIO 0xF000B00204514000B000000000000000 Audio data stream, streams actual audio data GATT_PROP_READ | GATT_PROP_NOTIFY

The primary vehicle for streaming audio data is BLE notifications. This scheme was chosen in order to optimize throughput by selecting a message type that has little overhead. Before the voice stream begins, the peer device must enable notifications by writing 01:00 to the CCCD of the AUDIOPROFILE_START and AUDIOPROFILE_AUDIO. If notifications are not enabled, HID Advanced Remote will not stream voice data.

The basic flow of a voice transmission is:

  1. HID Advanced Remote sends a start command (0x04) notification (if enabled) on the AUDIOPROFILE_START characteristic.
  2. HID Advanced Remote starts streaming voice data. See Voice Over BLE section for more details
  3. HID Advanced Remote sends a stop command (0x00) notification on the AUDIOPROFILE_START characteristic.

Report Map Characteristic

The Report Map characteristic contains the HID Report Descriptor which is used to define formatting information for Input Report, Output Report, and Feature Report data transferred between a HID Device and Report Host.

Each HID Service can only include one instance of the Report Map characteristic. The length of the Report Map characteristic value is limited to 512 bytes.

Report Map as shown at the right side is included in the HID Service in the hid_adv_remote project:

HID Reports

The Report Reference characteristic descriptors contain the Report ID and Report Type for each Report Characteristic defined in the Report Map. This information is used on the Report Host to route USB HID class driver data into and out of GATT characteristic values.

Report IDs in hidkbdccservice.h:

    // HID Report IDs for the service
    #define HID_RPT_ID_KEY_IN        1  // Keyboard input report ID
    #define HID_RPT_ID_CC_IN         2  // Consumer Control input report ID 
    #define HID_RPT_ID_LED_OUT       0  // LED output report ID

Report Types in hiddev.h:

    /* HID Report type */
    #define HID_REPORT_TYPE_INPUT 1 // Keyboard input report ID
    #define HID_REPORT_TYPE_OUTPUT 2 // Consumer Control input report ID
    #define HID_REPORT_TYPE_FEATURE 3 // LED output report ID

The Report ID is not transmitted as a part of the HID Report over-the-air but is prepended by the Report Host, using the information in Report Reference characteristic descriptors, to each received HID report before passing them to a USB HID Class driver.

Key Board Input Reports

The Report Map includes the full 101-key part of the Keyboard Usage Page. This gives a one-to-one mapping between the transmitted report and the Usage ID in the usage table. The Usage IDs can be found in hiddev.c.

Consumer Control Input Reports

Only a subset of the Consumer Control Usage Page is included in the Report Map. The HID Report transmitted is in this case not the Usage ID but the index of the report as include in the Report Map.

The Consumer Control reports that can be sent can be found in hid_adv_remote.h as:

    // HID Consumer Control keycodes
    // (based on the HID Report Map characteristic value)
    #define HID_CC_RPT_POWER                    1
    #define HID_CC_RPT_PLAY_PAUSE               2
    #define HID_CC_RPT_STOP                     3
    #define HID_CC_RPT_SCAN_NEXT_TRK            4
    #define HID_CC_RPT_SCAN_PREV_TRK            5
    #define HID_CC_RPT_FAST_FWD                 6
    #define HID_CC_RPT_REWIND                   7
    #define HID_CC_RPT_RECORD                   8
    #define HID_CC_RPT_VOLUME_UP                9
    #define HID_CC_RPT_VOLUME_DOWN              10
    #define HID_CC_RPT_MUTE                     11

LED Output Reports

The LED Output reports are set in the Report Map to be a 5 bit bit-vector where each bit represents a report value. When an output is received on the CC2650RC it will be passed to the application callback in hid_adv_remote.c:

    static uint8_t HIDAdvRemote_handleReportCB(uint8_t id, uint8_t type,
                                               uint16_t uuid, uint8_t oper,
                                               uint16_t *pLen, uint8_t *pData)
    {
      // Intentionally left blank
      return SUCCESS;
    }

No specific handling of received Output Reports is implanted hid_adv_remote project so the correct handling must be added to use the information in the LED Output Report.

Key Scanning

This section describes the key scanner.

There are 32 buttons on the Remote Control that are scanned with a 3x11 matrix.

Normally, a total of 14 IOs would be required to perform key scanning in this configuration. To save IOs, shift registers are used to extend the number of IOs. A single shift register can be used to get 8 IOs from 3. When cascading shift registers, the same 3 IOs can emulate additional IOs. The two shift registers used in this example, can support up to 16 IOs, but only 11 are used for the rows. Including 3 IOs for the columns, 6 IOs are used perform key scanning. The spare IOs are connected to the DevPack connector.

Note. that these 32 buttons could have been scanned with 12 IOs in a 6x6 matrix.

Algorithm

As shown in the there are 3 IOs for columns and 11 IOs for rows. When the remote is in standby the IOs are configured such that a button press generates an interrupt. The interrupt triggers on the column pins.

  1. Interrupt detected
  2. Start de-bounce timer
  3. Key scan is repeated periodically as long as a press is detected.

De-bounce : Refers to unintentional changes in voltage, or that the voltage “bounce”. This typically happens as the button is pressed. As the button shorts the connection between row and column the voltage can “bounce”. We don’t want to scan the keys as this happens. Thus, the keys are only scanned after some time has passed. This time is greater than the time it takes for the voltage to settle.

Implementation

The key scan algorithm discussed above is implemented in the module key_scan.c/.h. This module has two public functions:

  1. KeyInit(void)
  2. KeyConfig(KeyEvtCBack_t key_cback, uint16_t initialKeyRepeatInterval, uint16_t debounceTime, uint16_t pollRate)

KeyInit

This function must be called before KeyConfig() is called. It initializes and configures all IOs. It also constructs the timer resources the key scanner requires.

KeyConfigure

This function is called to register callbacks and configure timer values. The parameters are as follows:

  1. debounceTime, de-bounce period
  2. pollRate, scanning period.
  3. initialKeyRepeatInterval. It determines how frequent the callback key_cback is called. If a key is kept pressed for a longer duration, then the callback is called every initialKeyRepeatInterval/pollRate ms.

Usage

This section describes how to exercise various parts of the HID Advanced Remote.

Key Mapping

The following shows a mapping of which key pressed on the Remote Controller corresponds to which HID report or application action.

Key HID Advanced Remote
NUM_0 HID_KEYBOARD_0
NUM_1 HID_KEYBOARD_1
NUM_2 HID_KEYBOARD_2
NUM_3 HID_KEYBOARD_3
NUM_4 HID_KEYBOARD_4
NUM_5 HID_KEYBOARD_5
NUM_6 HID_KEYBOARD_6
NUM_7 HID_KEYBOARD_7
NUM_8 HID_KEYBOARD_8
NUM_9 HID_KEYBOARD_9
UP HID_KEYBOARD_UP_ARROW
DOWN HID_KEYBOARD_DOWN_ARROW
LEFT HID_KEYBOARD_LEFT_ARROW
RIGHT HID_KEYBOARD_RIGHT_ARROW
Power None
PLAY/PAUSE HID_CC_RPT_PLAY_PAUSE
MUTE HID_CC_RPT_MUTE
V+ HID_CC_RPT_VOLUME_UP
V- HID_CC_RPT_VOLUME_DOWN
REC None
FAST FORWARD HID_CC_RPT_SCAN_NEXT_TRK
FAST REWIND HID_CC_RPT_SCAN_PREV_TRK
MIC Start streaming Voice
MENU None
PAIR None
INFINITE None
STB None
BACK None
OK None
HOME None
(Red LED) Indicates streaming Voice when flashing
AV None
TV None

Voice over GATT Profile

With the CC2650 Launchpad, the simple_central_audio_reciever is designed to automatically connect, pair, and bond with the HID Advanced Remote when found during scanning.

View Simple Audio Receiver for information on how to use the CC2650 Launchpad with HID Advanced Remote to test voice streaming.

On the Remote, simply press the MIC Key to begin an Audio Stream. Release the MIC Key once stream is no longer desired. To indicate streaming is in progress, the RED LED will flash.

HID over GATT Profile

Using a smart phone, HID over GATT can be tested by connecting via Bluetooth. In this section an Android Phone is used to connect to the device. Once connected, the Remote will emulate a keyboard with various functions as HID Reports. See Key Mapping.

Access the Bluetooth Menu of the smart phone.

Ensure the Remote is advertising by pressing any key on the Remote. And verify that the smart phone can detect the remote.

Connect to the device, during pairing the phone will display a passcode to enter in the Remote.

Enter this code onto the Remote via the keypad; after a few moments, the Remote can be used as a input device.