Bluetooth HID Firmware Tested on HM-10

Months ago, I wrote a firmware to convert any HM-10 to a Bluetooth Low Energy HID device. The HM-10 arrived and today I finally have some spare time to test it out. Flashing the HM-10 wasn’t straightforward as I thought it would be, due to the confusing VDD lines from the CC Debugger. So here’s how mine’s connected:

CC Debugger - HM-10


The LED on the CC Debugger should lit green, indicating it has found the CC2541 or CC2540 on the HM-10. After that, Texas Instruments SmartRF Flash Programmer was used to program the chip.

A MSP430 Launchpad was used with this test program:

#include <msp430.h>
#include <stdint.h>
#include "KBD_HUT.h"

void printf(char *format, ...);
void pressKey(uint8_t keyCode);
void releaseKey(uint8_t keyCode);
void sendKbdReport(void);
void sendMouseReport(void);
void buildMouseReport(void);

typedef struct {
 uint8_t buttons;
 uint8_t dX;
 uint8_t dY;
 uint8_t dZ;

uint8_t index = 1;
MOUSE_REPORT mouseReport = { 0, 0, 0, 0 }; // HID report, to be sent to the PC.

const int8_t tableSinCosLookUp[16][2]; 

void main(void) {
 WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer


 //setup UART
 P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
 P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
 // 1000000 Hz 57600 bps
 UCA0BR0 = 0x11;
 UCA0BR1 = 0x00;
 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

 //setup LED
 P1OUT = 0;
 P1DIR |= BIT0;
 //setup button
 P1DIR &= ~BIT3;
 P1OUT |= BIT3; //pull-up, active low
 P1REN |= BIT3;

 while(1) {
 if((P1IN & BIT3) == BIT3) {
 P1OUT &= ~BIT0;
 } else {
 if((P1IN & BIT3) != BIT3) {
 P1OUT |= BIT0;


void buildMouseReport(void) {
 mouseReport.dX =
 (tableSinCosLookUp[index][0] -
 tableSinCosLookUp[index - 1][0]) >> 1;
 mouseReport.dY =
 (tableSinCosLookUp[index][1] -
 tableSinCosLookUp[index - 1][1]) >> 1;

 if (index++ >= 90){
 index = 1;

void pressKey(uint8_t keyCode) {
 printf("KD%c\r\n", keyCode); //send keycode as a character

void releaseKey(uint8_t keyCode) {
 printf("KU%c\r\n", keyCode); //send keycode as a character

void sendKbdReport(void) {

void sendMouseReport(void) {

const int8_t tableSinCosLookUp[16][2] = {

The test program demonstrates the Bluetooth HID firmware’s keyboard capability beautifully but there’s still a hiccup with the mouse movement, definitely because of that poor looking look-up table.

I shall have the TrackPoint setup and tested in a few days. Until then, thanks for reading and have fun!


18 thoughts on “Bluetooth HID Firmware Tested on HM-10

  1. I’m glad to see you’re still working on this!

    I have a question: If someone is completely new to soldering, would this be a difficult project to start with? Or if I’m careful, should I be able to cope with your kit?

    I have grand intentions of shoving a small USB battery and one of your kits inside a USB Thinkpad Keyboard case, to make a bluetooth keyboard. That’s a few steps off, but it would be fun to start with just the basic piece!

    1. ThinkClamp v0.6.x is very difficult to solder for newcomers. It cannot interface with Bluetooth modules due to the lack of a UART port. v0.7 will solve most of these problems and include an on-board battery charger for 1-cell LiPo.

  2. Hi, i am looking for a special firmware, and found your page, but i have a question. the module shall act similar to a SPP UART-Bridge module, but with HID instead of SPP. so everything, coming along from UART shall be sent as keypress via HID. is this what you firmware does? thanks, Daniel

  3. Hello, your code works fine on my CC2541 chips in translation mode

    1. How do I enter command mode?
    2. could you please insert the command to change the name!
    3. And maybe you could also implement a pin which gets HIGH if a connection is established?!

    I am not really awesome at this topics and I guess for you it´s just piece of cake… 😉

    Thanks so much,


    1. Hi, glad it works reasonably well on your module. I’ve updated the README.MD for the mode switch. Sending @@@ put the chip into command mode, $$$ put the chip back into translation mode. Translation mode is the default mode I think.

      I am very busy at the moment and I don’t think I can add any features. I will do when I can.

  4. Hi flashandrc,

    programm works fine, the HM-11 drains about 8.5 mA constantly, is there anykind of power saving sleep mode implemented?

    Could you do that?

    Thanks in advance Andi

      1. uint16 HidKbdMouse_ProcessEvent( uint8 task_id, uint16 events ) in hidKbdMouse.c is what you’re looking for. It wakes up the device every 50 seconds to make sure the connection is kept alive. IIRC, 60 seconds is the default idle time before cc254x disconnects from the host. It’s too long ago.

  5. I’m wondering if it’s real to write a controller-level HID implementation for those modules (i.e. arduino/atmega controlled, using plain C). Or it’s technically impossible? Why write firmware? Can you explain?

    1. The existing programmable Bluetooth modules at the time were relatively expensive, especially if you were to make lots of them, and tied down to specific software. The HM-10/11 are cheap, and getting cheaper. It’s an investment.

      When you say controller level, I assume communication via the link layer or network layer. I didn’t want to invest time into learning the inner working of BT4 and the CC254x series so I chose instead to write the firmware using their BLE SDK.

  6. Flashandrc

    Would you be able to write a quick flash for the hm-10 that has all the GPIO pins where I can turn them HIGH (on) or LOW (off). I’m looking for a way to use the hm-10 without the need of an arduino with it.


    1. I’d suggest looking at ATSAMB11-ZR modules from Microchip. They’ve got a free IDE, tons of examples and the modules are FCC certified at $8 each.

Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s