Add basic Bluetooth support
parent
4a700fac14
commit
5f6e4c1e35
|
|
@ -16,9 +16,15 @@
|
||||||
|
|
||||||
#include "anne_pro.h"
|
#include "anne_pro.h"
|
||||||
#include "anne_pro_lighting.h"
|
#include "anne_pro_lighting.h"
|
||||||
|
#include "anne_pro_bluetooth.h"
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
|
#ifdef NKRO_ENABLE
|
||||||
|
static bool nkro_enabled_last = false;
|
||||||
|
#endif
|
||||||
|
static host_driver_t *host_driver_last;
|
||||||
|
|
||||||
/* Process the Anne Pro custom keycodes */
|
/* Process the Anne Pro custom keycodes */
|
||||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||||
/* Update the key status for the reactive effects */
|
/* Update the key status for the reactive effects */
|
||||||
|
|
@ -49,6 +55,29 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||||
anne_pro_lighting_mode_next();
|
anne_pro_lighting_mode_next();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
case APB_TOG:
|
||||||
|
/* Toggle the output driver between USB and Bluetooth */
|
||||||
|
if (record->event.pressed) {
|
||||||
|
if (host_get_driver() != &anne_pro_bluetooth_driver) {
|
||||||
|
clear_keyboard();
|
||||||
|
host_driver_last = host_get_driver();
|
||||||
|
#ifdef NKRO_ENABLE
|
||||||
|
nkro_enabled_last = keymap_config.nkro;
|
||||||
|
keymap_config.nkro = false;
|
||||||
|
#endif
|
||||||
|
host_set_driver(&anne_pro_bluetooth_driver);
|
||||||
|
anne_pro_bluetooth_on();
|
||||||
|
anne_pro_bluetooth_broadcast();
|
||||||
|
} else {
|
||||||
|
clear_keyboard();
|
||||||
|
#ifdef NKRO_ENABLE
|
||||||
|
keymap_config.nkro = nkro_enabled_last;
|
||||||
|
#endif
|
||||||
|
host_set_driver(host_driver_last);
|
||||||
|
anne_pro_bluetooth_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
/* Handle other keycodes normally */
|
/* Handle other keycodes normally */
|
||||||
return process_record_user(keycode, record);
|
return process_record_user(keycode, record);
|
||||||
|
|
@ -59,6 +88,8 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||||
void keyboard_pre_init_kb(void) {
|
void keyboard_pre_init_kb(void) {
|
||||||
/* Initialize the ligthing controller */
|
/* Initialize the ligthing controller */
|
||||||
anne_pro_lighting_init();
|
anne_pro_lighting_init();
|
||||||
|
/* Initialize the bluetooth controller */
|
||||||
|
anne_pro_bluetooth_init();
|
||||||
|
|
||||||
keyboard_pre_init_user();
|
keyboard_pre_init_user();
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +110,8 @@ void keyboard_post_init_kb(void) {
|
||||||
void matrix_scan_kb(void) {
|
void matrix_scan_kb(void) {
|
||||||
/* Run some update code for the lighting */
|
/* Run some update code for the lighting */
|
||||||
anne_pro_lighting_update();
|
anne_pro_lighting_update();
|
||||||
|
/* Run some update code for the bluetooth */
|
||||||
|
anne_pro_bluetooth_update();
|
||||||
|
|
||||||
/* Run matrix_scan_user code */
|
/* Run matrix_scan_user code */
|
||||||
matrix_scan_user();
|
matrix_scan_user();
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ enum anne_pro_keycodes {
|
||||||
APL_RGB = SAFE_RANGE,
|
APL_RGB = SAFE_RANGE,
|
||||||
APL_RAT,
|
APL_RAT,
|
||||||
APL_BRT,
|
APL_BRT,
|
||||||
APL_MOD
|
APL_MOD,
|
||||||
|
APB_TOG,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The fully-featured LAYOUT() that has every single key available in the matrix. */
|
/* The fully-featured LAYOUT() that has every single key available in the matrix. */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,176 @@
|
||||||
|
/* Copyright 2019 Michiel Visser
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "anne_pro_bluetooth.h"
|
||||||
|
#include "uart_tx_ringbuf.h"
|
||||||
|
#include "host.h"
|
||||||
|
#include "host_driver.h"
|
||||||
|
|
||||||
|
#define BLUETOOTH_UART (&UARTD2)
|
||||||
|
/* UART transmission ringbuffer for the Bluetooth UART */
|
||||||
|
static uint8_t bluetooth_uart_tx_buffer[256] = {0};
|
||||||
|
static uart_tx_ringbuf_t bluetooth_uart_ringbuf = {
|
||||||
|
.buf = bluetooth_uart_tx_buffer,
|
||||||
|
.uart = BLUETOOTH_UART,
|
||||||
|
.size = sizeof(bluetooth_uart_tx_buffer),
|
||||||
|
.sending_elements = 0,
|
||||||
|
.head = 0,
|
||||||
|
.tail = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Handler for finsihed Bluetooth UART transmissions */
|
||||||
|
static void bluetooth_uart_txend(UARTDriver *uart) {
|
||||||
|
uart_tx_ringbuf_finish_transmission(&bluetooth_uart_ringbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wakeup bluetooth chip and wait for acknoledgement */
|
||||||
|
msg_t bluetooth_wakeup(void) {
|
||||||
|
char rx_buf[3];
|
||||||
|
size_t frames = 3;
|
||||||
|
palSetPad(GPIOA, 1);
|
||||||
|
msg_t result = uartReceiveTimeout(BLUETOOTH_UART, &frames, &rx_buf, 10);
|
||||||
|
palClearPad(GPIOA, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Bluetooth, should be called every matrix scan */
|
||||||
|
void anne_pro_bluetooth_update(void) {
|
||||||
|
if (!uart_tx_ringbuf_empty(&bluetooth_uart_ringbuf)) {
|
||||||
|
if (bluetooth_wakeup() == MSG_OK) {
|
||||||
|
uart_tx_ringbuf_start_transmission(&bluetooth_uart_ringbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bluetooth_rx_char(UARTDriver *driver, uint16_t c);
|
||||||
|
/* Bluetooth UART configuration */
|
||||||
|
static UARTConfig bluetooth_uart_cfg = {
|
||||||
|
.txend1_cb = bluetooth_uart_txend,
|
||||||
|
.txend2_cb = NULL,
|
||||||
|
.rxend_cb = NULL,
|
||||||
|
.rxchar_cb = bluetooth_rx_char,
|
||||||
|
.rxerr_cb = NULL,
|
||||||
|
.speed = 38400,
|
||||||
|
.cr1 = 0,
|
||||||
|
.cr2 = USART_CR2_LINEN,
|
||||||
|
.cr3 = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Receive buffer for the Bluetooth UART */
|
||||||
|
uint8_t bluetooth_rx_buffer[256] = {0};
|
||||||
|
size_t bluetooth_rx_index = 0;
|
||||||
|
|
||||||
|
/* Lookup table for translation to hex */
|
||||||
|
char hex_lookup[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
|
||||||
|
/* Handle packets from the bluetooth receive buffer */
|
||||||
|
void bluetooth_handle_packet(void) {
|
||||||
|
/* Packet type and length */
|
||||||
|
uint8_t packet_type = bluetooth_rx_buffer[0];
|
||||||
|
// uint8_t packet_len = bluetooth_rx_buffer[1];
|
||||||
|
|
||||||
|
/* Handle incomming packets over Bluetooth */
|
||||||
|
switch (packet_type) {
|
||||||
|
case 2: // System
|
||||||
|
switch (bluetooth_rx_buffer[2]) {
|
||||||
|
case 1: // GetId
|
||||||
|
// [2, 15, 129, 10, 2, 0, 1, 2, 50, 55, 71, 1, 50, 48]
|
||||||
|
// [2, 15, 129, 8, 2, 1, 54, 48, 52, 0, 54, 0, 50, 48]
|
||||||
|
uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 28, "\x02\x0f\x81\x0a\x02\x00\x01\x02\x32\x37\x47\x01\x32\x30"
|
||||||
|
"\x02\x0f\x81\x08\x02\x01\x36\x30\x34\x00\x36\x00\x32\x30");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive single character from the Bluetooth UART */
|
||||||
|
void bluetooth_rx_char(UARTDriver *driver, uint16_t c) {
|
||||||
|
bluetooth_rx_buffer[bluetooth_rx_index++] = c;
|
||||||
|
|
||||||
|
if (bluetooth_rx_index > 2) {
|
||||||
|
uint8_t packet_len = bluetooth_rx_buffer[1];
|
||||||
|
if (bluetooth_rx_index >= (2 + packet_len)) {
|
||||||
|
bluetooth_handle_packet();
|
||||||
|
bluetooth_rx_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the Anne Pro Bluetooth */
|
||||||
|
void anne_pro_bluetooth_init(void) {
|
||||||
|
/* Initialize the bleutooth UART */
|
||||||
|
uartStart(BLUETOOTH_UART, &bluetooth_uart_cfg);
|
||||||
|
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
|
||||||
|
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
|
||||||
|
palSetPadMode(GPIOA, 1, PAL_MODE_OUTPUT_PUSHPULL);
|
||||||
|
palClearPad(GPIOA, 1);
|
||||||
|
|
||||||
|
/* Disable bluetooth on startup */
|
||||||
|
anne_pro_bluetooth_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn on Bluetooth */
|
||||||
|
void anne_pro_bluetooth_on(void) {
|
||||||
|
uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x01");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn off Bluetooth */
|
||||||
|
void anne_pro_bluetooth_off(void) {
|
||||||
|
uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x02");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start broadcasting on Bluetooth */
|
||||||
|
void anne_pro_bluetooth_broadcast(void) {
|
||||||
|
uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x07");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status of keyboard leds for Bluetooth driver*/
|
||||||
|
static uint8_t keyboard_leds(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send keyboard HID report for Bluetooth driver */
|
||||||
|
static void send_keyboard(report_keyboard_t *report) {
|
||||||
|
uint8_t bluetooth_report[11] = {7, 9, 1, 0};
|
||||||
|
bluetooth_report[3] = report->mods;
|
||||||
|
bluetooth_report[4] = report->reserved;
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
bluetooth_report[5+i] = report->keys[i];
|
||||||
|
}
|
||||||
|
uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 11, bluetooth_report);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send mouse HID report for Bluetooth driver */
|
||||||
|
static void send_mouse(report_mouse_t *report) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send system report for Bluetooth driver */
|
||||||
|
static void send_system(uint16_t data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send consumer report for Bluetooth driver */
|
||||||
|
static void send_consumer(uint16_t data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth host driver, this allows us to switch from USB output to Bluetooth output */
|
||||||
|
host_driver_t anne_pro_bluetooth_driver = {
|
||||||
|
keyboard_leds,
|
||||||
|
send_keyboard,
|
||||||
|
send_mouse,
|
||||||
|
send_system,
|
||||||
|
send_consumer
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Copyright 2019 Michiel Visser
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "host_driver.h"
|
||||||
|
|
||||||
|
extern host_driver_t anne_pro_bluetooth_driver;
|
||||||
|
|
||||||
|
void anne_pro_bluetooth_init(void);
|
||||||
|
void anne_pro_bluetooth_update(void);
|
||||||
|
|
||||||
|
void anne_pro_bluetooth_on(void);
|
||||||
|
void anne_pro_bluetooth_off(void);
|
||||||
|
void anne_pro_bluetooth_broadcast(void);
|
||||||
|
|
@ -336,6 +336,26 @@
|
||||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* UART driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables synchronous APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
|
||||||
|
#define UART_USE_WAIT TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||||
|
#define UART_USE_MUTUAL_EXCLUSION FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* USB driver related settings. */
|
/* USB driver related settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
),
|
),
|
||||||
[2] = LAYOUT(
|
[2] = LAYOUT(
|
||||||
RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
APB_TOG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||||
_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
|
_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
|
||||||
_______, _______, _______, XXXXXXX, _______, _______, _______, _______
|
_______, _______, _______, XXXXXXX, _______, _______, _______, _______
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@
|
||||||
* UART driver system settings.
|
* UART driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_UART_USE_USART1 FALSE
|
#define STM32_UART_USE_USART1 FALSE
|
||||||
#define STM32_UART_USE_USART2 FALSE
|
#define STM32_UART_USE_USART2 TRUE
|
||||||
#define STM32_UART_USE_USART3 TRUE
|
#define STM32_UART_USE_USART3 TRUE
|
||||||
#define STM32_UART_USART1_IRQ_PRIORITY 12
|
#define STM32_UART_USART1_IRQ_PRIORITY 12
|
||||||
#define STM32_UART_USART2_IRQ_PRIORITY 12
|
#define STM32_UART_USART2_IRQ_PRIORITY 12
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ ARMV = 7
|
||||||
DFU_ARGS = -d 0483:df11 -a 0 -s 0x08004000
|
DFU_ARGS = -d 0483:df11 -a 0 -s 0x08004000
|
||||||
|
|
||||||
# Extra source files
|
# Extra source files
|
||||||
SRC += uart_tx_ringbuf.c anne_pro_lighting.c
|
SRC += uart_tx_ringbuf.c anne_pro_lighting.c anne_pro_bluetooth.c
|
||||||
|
|
||||||
# Build Options
|
# Build Options
|
||||||
# comment out to disable the options.
|
# comment out to disable the options.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue