2

I have a folding PDA keyboard (model number iPAQ G750). It is using a proprietary serial protocol, I want to adapt it to Bluetooth using a micro controllers. The keyboard sends out a 2-byte keycode every time a key is pressed or released. Some effort of modding the keyboard is documented here: https://www.instructables.com/HP-Compaq-IPAQ-G750-Keyboard-to-USB/

I can't figure out too much pattern from the keycodes, except the most significant bit encodes pressed/released. Can anybody look at the keycodes and find some patterns from it? Is it a keyscan code denoting the rows and columns? Usually keycodes are 1-byte to allow more efficient processing. I can use the 2-byte keycodes with a hashmap but that is inefficient for micro controllers.

Here is the mapping from keycode to the actual keys.

void keySetup() {
  keyMapDown[0x16e9] = '1';
  keyMapUp[0x96e9] = '1';
  
  keyMapDown[0x1ee1] = '2';
  keyMapUp[0x9ee1] = '2';
  
  keyMapDown[0x26d9] = '3';
  keyMapUp[0xa6d9] = '3';
  
  keyMapDown[0x25da] = '4';
  keyMapUp[0xa5da] = '4';
  
  keyMapDown[0x2ed1] = '5';
  keyMapUp[0xaed1] = '5';
  
  keyMapDown[0x36c9] = '6';
  keyMapUp[0xb6c9] = '6';
  
  keyMapDown[0x3dc2] = '7';
  keyMapUp[0xbdc2] = '7';
  
  keyMapDown[0x3ec1] = '8';
  keyMapUp[0xbec1] = '8';
  
  keyMapDown[0x46b9] = '9';
  keyMapUp[0xc6b9] = '9';
  
  keyMapDown[0x45ba] = '0';
  keyMapUp[0xc5ba] = '0';

  
  //Letter keys
  keyMapDown[0x1ce3] = 'a';
  keyMapUp[0x9ce3] = 'a';
  
  keyMapDown[0x32cd] = 'b';
  keyMapUp[0xb2cd] = 'b';
  
  keyMapDown[0x21de] = 'c';
  keyMapUp[0xa1de] = 'c';
  
  keyMapDown[0x23dc] = 'd';
  keyMapUp[0xa3dc] = 'd';
  
  keyMapDown[0x24db] = 'e';
  keyMapUp[0xa4db] = 'e';
  
  keyMapDown[0x2bd4] = 'f';
  keyMapUp[0xabd4] = 'f';
  
  keyMapDown[0x34cb] = 'g';
  keyMapUp[0xb4cb] = 'g';
  
  keyMapDown[0x33cc] = 'h';
  keyMapUp[0xb3cc] = 'h';
  
  keyMapDown[0x43bc] = 'i';
  keyMapUp[0xc3bc] = 'i';
  
  keyMapDown[0x3bc4] = 'j';
  keyMapUp[0xbbc4] = 'j';
  
  keyMapDown[0x42bd] = 'k';
  keyMapUp[0xc2bd] = 'k';
  
  keyMapDown[0x4bb4] = 'l';
  keyMapUp[0xcbb4] = 'l';
  
  keyMapDown[0x3ac5] = 'm';
  keyMapUp[0xbac5] = 'm';
  
  keyMapDown[0x31ce] = 'n';
  keyMapUp[0xb1ce] = 'n';
  
  keyMapDown[0x44bb] = 'o';
  keyMapUp[0xc4bb] = 'o';
  
  keyMapDown[0x4db2] = 'p';
  keyMapUp[0xcdb2] = 'p';
  
  keyMapDown[0x15ea] = 'q';
  keyMapUp[0x95ea] = 'q';
  
  keyMapDown[0x2dd2] = 'r';
  keyMapUp[0xadd2] = 'r';
  
  keyMapDown[0x1be4] = 's';
  keyMapUp[0x9be4] = 's';
  
  keyMapDown[0x2cd3] = 't';
  keyMapUp[0xacd3] = 't';
  
  keyMapDown[0x3cc3] = 'u';
  keyMapUp[0xbcc3] = 'u';
  
  keyMapDown[0x2ad5] = 'v';
  keyMapUp[0xaad5] = 'v';
  
  keyMapDown[0x1de2] = 'w';
  keyMapUp[0x9de2] = 'w';
  
  keyMapDown[0x22dd] = 'x';
  keyMapUp[0xa2dd] = 'x';
  
  keyMapDown[0x35ca] = 'y';
  keyMapUp[0xb5ca] = 'y';
  
  keyMapDown[0x1ae5] = 'z';
  keyMapUp[0x9ae5] = 'z';


  //Symbol keys  
  keyMapDown[0xef1] = '`';
  keyMapUp[0x8ef1] = '`';
  
  keyMapDown[0x4eb1] = '-';
  keyMapUp[0xceb1] = '-';
  
  keyMapDown[0x55aa] = '=';
  keyMapUp[0xd5aa] = '=';
  
  keyMapDown[0x4cb3] = ';';
  keyMapUp[0xccb3] = ';';
  
  keyMapDown[0x5da2] = '\'';
  keyMapUp[0xdda2] = '\'';

  // # key but mapping is wrong so has to be changed
  keyMapDown[0x52ad] = 92;
  keyMapUp[0xd2ad] = 92;
  
  keyMapDown[0x41be] = ',';
  keyMapUp[0xc1be] = ',';
  
  keyMapDown[0x49b6] = '.';
  keyMapUp[0xc9b6] = '.';
  
  keyMapDown[0x4ab5] = '/';
  keyMapUp[0xcab5] = '/';

  // \ key but mapping is wrong so has to be changed
  keyMapDown[0x748b] = 49;
  keyMapUp[0xf48b] = 49;

  keyMapDown[0x54ab] = '[';
  keyMapUp[0xd4ab] = '[';

  keyMapDown[0x5ba4] = ']';
  keyMapUp[0xdba4] = ']';


  //Special keys
  keyMapDown[0x718e] = KEY_BACKSPACE;
  keyMapUp[0xf18e] = KEY_BACKSPACE;
  
  keyMapDown[0x5ca3] = ' ';
  keyMapUp[0xdca3] = ' '; 
  
  keyMapDown[0x58a7] = KEY_CAPS_LOCK;
  keyMapUp[0xd8a7] = KEY_CAPS_LOCK;
  
  keyMapDown[0x14eb] = KEY_LEFT_CTRL;
  keyMapUp[0x94eb] = KEY_LEFT_CTRL;
  
  keyMapDown[0x12ed] = KEY_LEFT_SHIFT;
  keyMapUp[0x92ed] = KEY_LEFT_SHIFT;
  
  keyMapDown[0x708f] = KEY_LEFT_ALT;
  keyMapUp[0xf08f] = KEY_LEFT_ALT;
  
  keyMapDown[0x7f8] = KEY_LEFT_GUI;
  keyMapUp[0x87f8] = KEY_LEFT_GUI;
  
  keyMapDown[0x738c] = KEY_RIGHT_CTRL;
  keyMapUp[0xf38c] = KEY_RIGHT_CTRL;
  
  keyMapDown[0x59a6] = KEY_RIGHT_SHIFT;
  keyMapUp[0xd9a6] = KEY_RIGHT_SHIFT;
  
  keyMapDown[0x11ee] = KEY_RIGHT_ALT;
  keyMapUp[0x91ee] = KEY_RIGHT_ALT;
  
  keyMapDown[0x6699] = KEY_DELETE;
  keyMapUp[0xe699] = KEY_DELETE;
  
  keyMapDown[0x5aa5] = KEY_RETURN;
  keyMapUp[0xdaa5] = KEY_RETURN;
  
  keyMapDown[0xdf2] = KEY_TAB;
  keyMapUp[0x8df2] = KEY_TAB;
  
  keyMapDown[0x28d7] = KEY_UP_ARROW;
  keyMapUp[0xa8d7] = KEY_UP_ARROW;
  
  keyMapDown[0x609f] = KEY_DOWN_ARROW;
  keyMapUp[0xe09f] = KEY_DOWN_ARROW;
  
  keyMapDown[0x5ea1] = KEY_LEFT_ARROW;
  keyMapUp[0xdea1] = KEY_LEFT_ARROW;
  
  keyMapDown[0x2fd0] = KEY_RIGHT_ARROW;
  keyMapUp[0xafd0] = KEY_RIGHT_ARROW;
};

1 Answer 1

0

I've figured it out:

  • the most significant bit: 0 is pressed, 1 is released
  • Mask the 16-bit with 0b0111111111111111 (ignoring the most significant bit), the first 8 bits and the second 8 bits are inversed, i.e. first_byte XOR second_byte = 0b11111111
  • So practically we just need to look at the first byte, the second byte is for error detection, I guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.