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;
} MOUSE_REPORT;

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

 BCSCTL1 = CALBC1_1MHZ;
 DCOCTL = CALDCO_1MHZ;

 //setup UART
 P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
 P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
 UCA0CTL1 |= UCSSEL_2; // SMCLK
 // 1000000 Hz 57600 bps
 UCA0BR0 = 0x11;
 UCA0BR1 = 0x00;
 UCA0MCTL = UCBRS_3 + UCBRF_0;
 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) {
 releaseKey(hutSpacebar);
 P1OUT &= ~BIT0;
 } else {
 __delay_cycles(1000);
 if((P1IN & BIT3) != BIT3) {
 P1OUT |= BIT0;
 pressKey(hutSpacebar);

 buildMouseReport();
 sendMouseReport();
 }
 }
 sendKbdReport();
 }
}

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) {
 printf("KUPDATE\r\n");
}

void sendMouseReport(void) {
 printf("M%c%c%c%c\r\n",mouseReport.buttons,mouseReport.dX,mouseReport.dY,mouseReport.dZ);
}

const int8_t tableSinCosLookUp[16][2] = {
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 4,0,
 -4,0,
 -4,0,
 -4,0,
 -4,0,
 -4,0,
 -4,0,
 -4,0,
 -4,0
};

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!

ThinkClamp v0.6 Support: FAQ and Customizing Keyboard Matrix

This blog post answers a few frequently asked questions and describes the difference between the two firmwares provided as well as outlines the steps to obtain the matrix of a ThinkPad keyboard connected to the computer via a ThinkClamp PCB, for both version 0.6.2 and version 0.6.1 Rev 1.1.

Frequently Asked Questions

  1. Will the board design and source code be made open-source? No.
  2. What are the maximum dimensions of a populated board? 50x50x6.5mm.
  3. Will you be making a case? Yes, but in a very distant future.
  4. Will there be a Bluetooth version? Yes, the Bluetooth implementation is currently in progress.
  5. I am only interested in using the TrackPoint as a mouse, how do I use it with your board? If you are only interested in the TrackPoint, there’s no need to get my boards. Grab an Arduino Micro or Leonardo and load in Felix Klee’s TrackPoint example.
  6. Where can I get the components? Local electronic parts shop, element14, Digikey, RS, Mouser…
  7. How do I flash the firmware? The steps to flash the firmware is provided on the product page, but here are the steps anyway.
    • Download TI MSP430 USB Firmware Upgrade Example
    • Start the program, click Next, read and accept the terms
    • Unplug USB cable if it’s plugged in
    • Hold down BSL button while re-inserting the cable
    • Release the BSL button. The software should now detect the device
    • Choose ‘Select firmware’ and browse to the firmware downloaded. Difference outlined in Customizing firmware’s keyboard matrix section below.
    • Click ‘Upgrade firmware’ to flash the device
  8. A lot of keys are not showing up, what’s going on? Resolder the MSP430. Make sure all the pins are soldered.
  9. Some of the pin are not showing up and I’ve made sure all the pins are soldered? You may have a different keyboard matrix. Keep reading this blog post.

Customizing firmware’s keyboard matrix

In the firmware folder on Mediafire, you will find two text files: ThinkClamp_v0.6.txt and ThinkClamp_v0.6_datapipe.txt. These two firmware will send keyboard and mouse reports to the computer and allow the module to function as a normal keyboard. However, beside sending keyboard and mouse to the computer, ThinkClamp_v0.6_datapipe will also send a string consisting of the row and column of the pressed key to the computer via a generic 64-byte report (more information on report format can be found in Texas Instruments’ USB HID Datapipe documentation).

Using ThinkClamp_v0.6_datapipe, matrix of any ThinkPad keyboard can be found, providing the keyboard’s plug fit into the receptacle provided. The steps to get the matrix are as follow:

  1. Flash the firmware onto the chip via USB BSL or SBW
  2. Download TI’s Java_HID_Demo. If the link is broken, find the zip from MSP430 USB Developers Package page.
  3. Extract and run HidDemo.jar
  4. Click OK as we will be entering a different PIDoops
  5. Enter 0x0967 into the PID input box and click “Set VID PID”. The window will become:
  6. Click on the button above “Not Initialized”. The cross icon will become a green tick. The log window will print “Connected to device VID: 8263 PID 2407”.
  7. Now, as you type, printable and non-printable keys, the row and column pair will be printed (as row,col) in which both row and column starts at 0

You may want to wait a bit between each key presses as there seems to be a small delay between when a key is pressed and when its row and column is displayed. This latency only appears when in used matrix is being found.

To create a new firmware with this newly found matrix, the keys found need to be converted to its corresponding hex value in the USB HID Usage Table’s keyboard values on page 53. For example, this is my ThinkPad US T60 keyboard matrix:

NADA correspond to a 0x00. This means there is no key at this matrix position. After matching the keys to its corresponding key codes, it is then organized into a 8×16 matrix and written into the firmware text file after address F000 as follows. FN3QIJ5HW4OJQFA