/* * Copyright (C) 2014 BlueKitchen GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * 4. Any redistribution, use, or modification is done solely for * personal benefit and not for any commercial purpose or for * monetary gain. * * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Please inquire about commercial licensing options at * contact@bluekitchen-gmbh.com * */ // ***************************************************************************** // // keyboard_demo // // ***************************************************************************** #include #include #include #include "btstack_chipset_cc256x.h" #include "hal_adc.h" #include "hal_board.h" #include "hal_compat.h" #include "hal_lcd.h" #include "hal_usb.h" #include "UserExperienceGraphics.h" #include #include "btstack_run_loop.h" #include "hci_cmd.h" #include "btstack_memory.h" #include "hci.h" #include "l2cap.h" #define INQUIRY_INTERVAL 15 #define FONT_HEIGHT 12 // Each character has 13 lines #define FONT_WIDTH 8 static int row = 0; extern int dumpCmds; const char *hexMap = "0123456789ABCDEF"; static char lineBuffer[20]; static uint8_t num_chars = 0; static bd_addr_t keyboard; static int haveKeyboard = 0; typedef enum { boot = 1, inquiry, w4_inquiry_cmd_complete, w4_l2cap_hii_connect, connected } state_t; static state_t state = 0; #define KEYCODE_RETURN '\n' #define KEYCODE_ESCAPE 27 #define KEYCODE_TAB '\t' #define KEYCODE_BACKSPACE 0x7f #define KEYCODE_ILLEGAL 0xffff #define KEYCODE_CAPSLOCK KEYCODE_ILLEGAL #define MOD_SHIFT 0x22 /** * English (US) */ static uint16_t keytable_us_none [] = { KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 0-3 */ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', /* 4 - 13 */ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', /* 14 - 23 */ 'u', 'v', 'w', 'x', 'y', 'z', /* 24 - 29 */ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', /* 30 - 39 */ KEYCODE_RETURN, KEYCODE_ESCAPE, KEYCODE_BACKSPACE, KEYCODE_TAB, ' ', /* 40 - 44 */ '-', '=', '[', ']', '\\', KEYCODE_ILLEGAL, ';', '\'', 0x60, ',', /* 45 - 54 */ '.', '/', KEYCODE_CAPSLOCK, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 55 - 60 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 61-64 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 65-68 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 69-72 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 73-76 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 77-80 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 81-84 */ '*', '-', '+', '\n', '1', '2', '3', '4', '5', /* 85-97 */ '6', '7', '8', '9', '0', '.', 0xa7, /* 97-100 */ }; static uint16_t keytable_us_shift[] = { KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 0-3 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 4 - 13 */ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 14 - 23 */ 'U', 'V', 'W', 'X', 'Y', 'Z', /* 24 - 29 */ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', /* 30 - 39 */ KEYCODE_RETURN, KEYCODE_ESCAPE, KEYCODE_BACKSPACE, KEYCODE_TAB, ' ', /* 40 - 44 */ '_', '+', '{', '}', '|', KEYCODE_ILLEGAL, ':', '"', 0x7E, '<', /* 45 - 54 */ '>', '?', KEYCODE_CAPSLOCK, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 55 - 60 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 61-64 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 65-68 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 69-72 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 73-76 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 77-80 */ KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, KEYCODE_ILLEGAL, /* 81-84 */ '*', '-', '+', '\n', '1', '2', '3', '4', '5', /* 85-97 */ '6', '7', '8', '9', '0', '.', 0xb1, /* 97-100 */ }; // decode hid packet into buffer - return number of valid keys events #define NUM_KEYS 6 uint8_t last_keyboard_state[NUM_KEYS]; uint16_t input[NUM_KEYS]; static char last_state_init = 0; uint16_t last_key; uint16_t last_mod; uint16_t last_char; uint8_t last_key_new; void doLCD(void){ //Initialize LCD and backlight // 138 x 110, 4-level grayscale pixels. halLcdInit(); // halLcdBackLightInit(); // halLcdSetBackLight(0); // 8 for normal halLcdSetContrast(100); halLcdClearScreen(); halLcdImage(TI_TINY_BUG, 4, 32, 104, 12 ); halLcdPrintLine("BTstack on ", 0, 0); halLcdPrintLine("TI MSP430", 1, 0); halLcdPrintLine("Keyboard", 2, 0); halLcdPrintLine("Init...", 3, 0); row = 4; } void clearLine(int line){ halLcdClearImage(130, FONT_HEIGHT, 0, line*FONT_HEIGHT); } void printLine(char *text){ printf("LCD: %s\n\r", text); halLcdPrintLine(text, row++, 0); } // put 'lineBuffer' on screen void showLine(void){ clearLine(row); halLcdPrintLine(lineBuffer, row, 0); printf("LCD: %s\n\r", lineBuffer); } unsigned char hid_process_packet(unsigned char *hid_report, uint16_t *buffer, uint8_t max_keys){ // check for key report if (hid_report[0] != 0xa1 || hid_report[1] != 0x01) { return 0; } u_char modifier = hid_report[2]; u_char result = 0; u_char i; u_char j; if (!last_state_init) { for (i=0;i> 4 ]; lineBuffer[j++] = hexMap[ keyboard[i] & 0x0f ]; if (i<5) lineBuffer[j++] = ':'; } lineBuffer[j++] = 0; printLine(lineBuffer); haveKeyboard = 1; hci_send_cmd(&hci_inquiry_cancel); state = w4_inquiry_cmd_complete; break; case HCI_EVENT_INQUIRY_COMPLETE: printLine("No keyboard found :("); break; case HCI_EVENT_LINK_KEY_REQUEST: // deny link key request hci_send_cmd(&hci_link_key_request_negative_reply, &keyboard); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request printLine( "Enter 0000"); hci_send_cmd(&hci_pin_code_request_reply, &keyboard, 4, "0000"); break; case HCI_EVENT_COMMAND_COMPLETE: if (COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel) ) { // inq successfully cancelled // printLine("Connecting"); l2cap_create_channel(l2cap_packet_handler, keyboard, PSM_HID_INTERRUPT, 150); break; } } } } static hci_transport_config_uart_t config = { HCI_TRANSPORT_CONFIG_UART, 115200, 1000000, // main baudrate 1, // flow control NULL, }; int main(void){ // stop watchdog timer WDTCTL = WDTPW + WDTHOLD; //Initialize clock and peripherals halBoardInit(); halBoardStartXT1(); halBoardSetSystemClock(SYSCLK_16MHZ); // Debug UART halUsbInit(); // show off doLCD(); // init LEDs LED_PORT_OUT |= LED_1 | LED_2; LED_PORT_DIR |= LED_1 | LED_2; /// GET STARTED /// btstack_memory_init(); btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); // init HCI const hci_transport_t * transport = hci_transport_h4_instance(); remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; hci_init(transport, &config, remote_db); hci_set_chipset(btstack_chipset_cc256x_instance()); // use eHCILL btstack_chipset_cc256x_enable_ehcill(1); // init L2CAP l2cap_init(); l2cap_register_packet_handler(packet_handler); // ready - enable irq used in h4 task __enable_interrupt(); // turn on! hci_power_control(HCI_POWER_ON); return 0; }