diff --git a/keyboards/anne_pro/anne_pro.c b/keyboards/anne_pro/anne_pro.c new file mode 100644 index 00000000000..0e38231bc58 --- /dev/null +++ b/keyboards/anne_pro/anne_pro.c @@ -0,0 +1,202 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include "anne_pro.h" +#include "anne_pro_lighting.h" +#include "anne_pro_bluetooth.h" +#include "ch.h" +#include "hal.h" + +void early_hardware_init_pre(void) { + /* Disable all external interrupt vectors, they are left enabled by the bootloader */ + nvicDisableVector(EXTI0_IRQn); + nvicDisableVector(EXTI1_IRQn); + nvicDisableVector(EXTI2_IRQn); + nvicDisableVector(EXTI3_IRQn); + nvicDisableVector(EXTI4_IRQn); + nvicDisableVector(EXTI9_5_IRQn); + nvicDisableVector(EXTI15_10_IRQn); +} + +/* Process the Anne Pro custom keycodes */ +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + /* Update the key status for the reactive effects */ + anne_pro_lighting_update_dynamic(record); + anne_pro_lighting_update_timeout(record); + + switch (keycode) { + case APL_RGB: + /* Toggle the RGB enabled/disabled */ + if (record->event.pressed) { + anne_pro_lighting_toggle(); + } + return false; + case APL_RAT: + /* Change the animation rate */ + if (record->event.pressed) { + anne_pro_lighting_rate_next(); + } + return false; + case APL_BRT: + /* Change the brightness */ + if (record->event.pressed) { + anne_pro_lighting_brightness_next(); + } + return false; + case APL_MOD: + /* Change the lighting mode */ + if (record->event.pressed) { + anne_pro_lighting_mode_next(); + } + return false; + case APB_OFF: + /* Turn off Bluetooth */ + if (record->event.pressed) { + anne_pro_bluetooth_off(); + } + return false; + case APB_ON: + /* Turn on Bluetooth, if on start broadcasting */ + if (record->event.pressed) { + if (!anne_pro_bluetooth_enabled()) { + anne_pro_bluetooth_on(); + } else { + anne_pro_bluetooth_broadcast(); + } + } + return false; + case APB_LGC: + /* Toggle Bluetooth legacy mode */ + if (record->event.pressed) { + anne_pro_bluetooth_legacy_toggle(); + } + return false; + case APB_HLQ: + /* Query hostlist */ + if (record->event.pressed) { + anne_pro_bluetooth_hostlist_query(); + } + return false; + case APB_HC1: + /* Connect saved host 1 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_connect(1); + } + return false; + case APB_HC2: + /* Connect saved host 2 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_connect(2); + } + return false; + case APB_HC3: + /* Connect saved host 3 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_connect(3); + } + return false; + case APB_HC4: + /* Connect saved host 4 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_connect(4); + } + return false; + case APB_HS1: + /* Save connected host 1 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_save(1); + } + return false; + case APB_HS2: + /* Save connected host 2 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_save(2); + } + return false; + case APB_HS3: + /* Save connected host 3 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_save(3); + } + return false; + case APB_HS4: + /* Save connected host 4 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_save(4); + } + return false; + case APB_HD1: + /* Delete saved host 1 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_delete(1); + } + return false; + case APB_HD2: + /* Delete saved host 2 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_delete(2); + } + return false; + case APB_HD3: + /* Delete saved host 3 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_delete(3); + } + return false; + case APB_HD4: + /* Delete saved host 4 */ + if (record->event.pressed) { + anne_pro_bluetooth_host_delete(4); + } + return false; + default: + /* Handle other keycodes normally */ + return process_record_user(keycode, record); + } +} + +/* Initialize custom keyboard features */ +void keyboard_pre_init_kb(void) { + /* Initialize the ligthing controller */ + anne_pro_lighting_init(); + /* Initialize the bluetooth controller */ + anne_pro_bluetooth_init(); + + keyboard_pre_init_user(); +} + +/* Turn on the lighting when init is finished */ +void keyboard_post_init_kb(void) { + /* Turn on the lighting */ + anne_pro_lighting_on(); + /* Set the theme to rainbow */ + anne_pro_lighting_mode(APL_MODE_RAINBOW); + /* Set the effect rate to average and the brightness to average */ + anne_pro_lighting_rate_brightness(128, 5); + + keyboard_post_init_user(); +} + +/* Start transmissions when the flag is set */ +void matrix_scan_kb(void) { + /* Run some update code for the lighting */ + anne_pro_lighting_update(); + /* Run some update code for the bluetooth */ + anne_pro_bluetooth_update(); + + /* Run matrix_scan_user code */ + matrix_scan_user(); +} diff --git a/keyboards/anne_pro/anne_pro.h b/keyboards/anne_pro/anne_pro.h new file mode 100644 index 00000000000..f6380369b01 --- /dev/null +++ b/keyboards/anne_pro/anne_pro.h @@ -0,0 +1,42 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#pragma once +#include "quantum.h" + +/* Custom keycodes for Lighting and Bluetooth control */ +enum anne_pro_keycodes { + APL_RGB = QK_KB, + APL_RAT, + APL_BRT, + APL_MOD, + APB_OFF, + APB_ON, + APB_LGC, + APB_HLQ, + APB_HC1, + APB_HC2, + APB_HC3, + APB_HC4, + APB_HS1, + APB_HS2, + APB_HS3, + APB_HS4, + APB_HD1, + APB_HD2, + APB_HD3, + APB_HD4, +}; diff --git a/keyboards/anne_pro/anne_pro_bluetooth.c b/keyboards/anne_pro/anne_pro_bluetooth.c new file mode 100644 index 00000000000..59a96673067 --- /dev/null +++ b/keyboards/anne_pro/anne_pro_bluetooth.c @@ -0,0 +1,375 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include "anne_pro_bluetooth.h" +#include "anne_pro_lighting.h" +#include "uart_tx_ringbuf.h" +#include "host.h" +#include "host_driver.h" + +#define BLUETOOTH_LAYER 3 +#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 +}; + +/* Bluetooth processor state */ +static bool bluetooth_enabled = false; +static volatile bool bluetooth_legacy = false; +static volatile uint8_t bluetooth_saved_hosts = 0; +static volatile uint8_t bluetooth_connected_host = 0; + +/* State for lighting effect when opening the bluetooth layer */ +static bool bluetooth_layer_enabled = false; +static bool lighting_before_bluetooth_layer = false; +/* Handle when layers are switched */ +layer_state_t layer_state_set_kb(layer_state_t state) { + if (!bluetooth_layer_enabled && (state & (1 << BLUETOOTH_LAYER)) != 0) { + /* Bluetooth layer turned on */ + lighting_before_bluetooth_layer = anne_pro_lighting_enabled(); + bluetooth_layer_enabled = true; + if (!lighting_before_bluetooth_layer) { + anne_pro_lighting_on(); + } + anne_pro_bluetooth_lighting_update(); + } else if (bluetooth_layer_enabled && (state & (1 << BLUETOOTH_LAYER)) == 0) { + /* Bluetooth layer turned off */ + bluetooth_layer_enabled = false; + if (!lighting_before_bluetooth_layer) { + anne_pro_lighting_off(); + } else { + anne_pro_lighting_mode_last(); + } + } + + return layer_state_set_user(state); +} + +/* Save state for QMK HID driver */ +#ifdef NKRO_ENABLE +static bool nkro_enabled_last = false; +#endif +static host_driver_t *host_driver_last; + +/* Enable the Bluetooth HID driver */ +static void driver_enable_bluetooth(void) { + /* Skip if the driver is already enabled */ + if (host_get_driver() == &anne_pro_bluetooth_driver) return; + + 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); +} + +/* Enable the last HID driver */ +static void driver_enable_last(void) { + /* Skip if the driver is already enabled */ + if (host_get_driver() != &anne_pro_bluetooth_driver) return; + + clear_keyboard(); +#ifdef NKRO_ENABLE + keymap_config.nkro = nkro_enabled_last; +#endif + host_set_driver(host_driver_last); +} + +/* Receive buffer for the Bluetooth UART */ +uint8_t bluetooth_rx_buffer[256] = {0}; +size_t bluetooth_rx_index = 0; + +/* 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]; + uint8_t message_type = bluetooth_rx_buffer[2]; + uint8_t data_len = packet_len - 1; + uint8_t *packet_data = &bluetooth_rx_buffer[3]; + + /* Handle incomming packets over Bluetooth */ + switch (packet_type) { + case 2: /* System packet */ + switch (message_type) { + case 1: /* GetId */ + /* These two buffers of data were extracted from the original Anne Pro firmware + however the exact meaning of all fields is unknown. + [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; + case 6: /* Bluetooth packet */ + switch (message_type) { + case 13: /* Pair request */ + if (bluetooth_connected_host == 0) { + /* Connected, turn to bluetooth */ + bluetooth_connected_host = 12; + driver_enable_bluetooth(); + layer_off(BLUETOOTH_LAYER); + } + break; + case 133: /* AckDeleteHost */ + /* Update the hostlist information when a saved host is deleted */ + anne_pro_bluetooth_hostlist_query(); + break; + case 134: /* AckHostListQuery */ + if (data_len == 3) { + if (bluetooth_connected_host == 0 && packet_data[1] != 0) { + /* Connected, turn to bluetooth */ + driver_enable_bluetooth(); + } else if (bluetooth_connected_host != 0 && packet_data[1] == 0) { + /* Disconnected, turn off bluetooth */ + driver_enable_last(); + } + + /* Save the hostlist query information */ + bluetooth_saved_hosts = packet_data[0]; + bluetooth_connected_host = packet_data[1]; + bluetooth_legacy = (packet_data[2] != 0); + + /* Update lighting if the bluetooth layer is active */ + if (bluetooth_layer_enabled) { + anne_pro_bluetooth_lighting_update(); + } + } + 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"); + bluetooth_enabled = true; +} + +/* Turn off Bluetooth */ +void anne_pro_bluetooth_off(void) { + /* When there is a connection disable it first, otherwise switching drivers + will reactivate the Bluetooth controller */ + if (bluetooth_connected_host != 0) { + /* Disconnected, turn off bluetooth */ + bluetooth_connected_host = 0; + driver_enable_last(); + + if (bluetooth_layer_enabled) { + anne_pro_bluetooth_lighting_update(); + } + } + + /* Disable the Bluetooth controller */ + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x02"); + bluetooth_enabled = false; +} + +/* Query if Bluetooth is enabled */ +bool anne_pro_bluetooth_enabled(void) { + return bluetooth_enabled; +} + +/* Start broadcasting on Bluetooth */ +void anne_pro_bluetooth_broadcast(void) { + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x07"); +} + +/* Turn Bluetooth legacy mode on or off */ +void anne_pro_bluetooth_legacy(bool enable) { + uint8_t buf[] = {6, 2, 12, enable ? 1 : 0}; + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 4, buf); + bluetooth_legacy = enable; +} + +/* Toggle Bluetooth legacy mode */ +void anne_pro_bluetooth_legacy_toggle(void) { + anne_pro_bluetooth_legacy(!bluetooth_legacy); +} + +/* Connect to a saved host */ +void anne_pro_bluetooth_host_connect(uint8_t host) { + uint8_t buf[] = {6, 2, 4, host}; + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 4, buf); +} + +/* Save the current host into a slot */ +void anne_pro_bluetooth_host_save(uint8_t host) { + uint8_t buf[] = {6, 2, 3, host}; + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 4, buf); +} + +/* Delete the host from a slot */ +void anne_pro_bluetooth_host_delete(uint8_t host) { + uint8_t buf[] = {6, 2, 5, host}; + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 4, buf); +} + +/* Query the hostlist of the Bluetooth controller */ +void anne_pro_bluetooth_hostlist_query(void) { + uart_tx_ringbuf_write(&bluetooth_uart_ringbuf, 3, "\x06\x01\x06"); +} + +/* Update the lighting effect for the Bluetooth layer */ +void anne_pro_bluetooth_lighting_update(void) { + /* Status of host 1 */ + uint8_t r1 = (bluetooth_connected_host != 1) ? 255 : 0; + uint8_t g1 = (bluetooth_connected_host == 1 || bluetooth_saved_hosts & (1 << 0)) ? 255 : 0; + /* Status of host 2 */ + uint8_t r2 = (bluetooth_connected_host != 2) ? 255 : 0; + uint8_t g2 = (bluetooth_connected_host == 2 || bluetooth_saved_hosts & (1 << 1)) ? 255 : 0; + /* Status of host 3 */ + uint8_t r3 = (bluetooth_connected_host != 3) ? 255 : 0; + uint8_t g3 = (bluetooth_connected_host == 3 || bluetooth_saved_hosts & (1 << 2)) ? 255 : 0; + /* Status of host 4 */ + uint8_t r4 = (bluetooth_connected_host != 4) ? 255 : 0; + uint8_t g4 = (bluetooth_connected_host == 4 || bluetooth_saved_hosts & (1 << 3)) ? 255 : 0; + /* Legacy mode? */ + uint8_t leg = (bluetooth_legacy) ? 255 : 0; + /* Bluetooth driver selected? */ + bool connected = (bluetooth_connected_host != 0); + bool drvr = (host_get_driver() == &anne_pro_bluetooth_driver); + + /* Payload for the lighting effect */ + uint8_t keybuf[] = { + 0, drvr ? 0 : 255, connected ? 255 : 0, drvr ? 255 : 0, 1, /* ESC-key */ + 1, r1, g1, 0, 1, /* 1-key */ + 2, r2, g2, 0, 1, /* 2-key */ + 3, r3, g3, 0, 1, /* 3-key */ + 4, r4, g4, 0, 1, /* 4-key */ + 10, leg, 255, 0, 1, /* 0-key (legacy) */ + 11, 255, 0, 0, 1, /* '-'-key (off) */ + 12, 0, 255, 0, 2, /* '='-key (on) */ + }; + + anne_pro_lighting_set_keys(8, keybuf); +} + +/* + Anne Pro Bluetooth HID driver for QMK + */ + +/* 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_nkro_t *report) { +} + +/* Send system report for Bluetooth driver */ +static void send_system(report_mouse_t *data) { +} + +/* Send consumer report for Bluetooth driver */ +static void send_consumer(report_extra_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 +}; diff --git a/keyboards/anne_pro/anne_pro_bluetooth.h b/keyboards/anne_pro/anne_pro_bluetooth.h new file mode 100644 index 00000000000..499331d4d29 --- /dev/null +++ b/keyboards/anne_pro/anne_pro_bluetooth.h @@ -0,0 +1,35 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#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); +bool anne_pro_bluetooth_enabled(void); +void anne_pro_bluetooth_broadcast(void); +void anne_pro_bluetooth_legacy(bool enable); +void anne_pro_bluetooth_legacy_toggle(void); +void anne_pro_bluetooth_host_connect(uint8_t host); +void anne_pro_bluetooth_host_save(uint8_t host); +void anne_pro_bluetooth_host_delete(uint8_t host); +void anne_pro_bluetooth_hostlist_query(void); +void anne_pro_bluetooth_lighting_update(void); diff --git a/keyboards/anne_pro/anne_pro_lighting.c b/keyboards/anne_pro/anne_pro_lighting.c new file mode 100644 index 00000000000..00a091732da --- /dev/null +++ b/keyboards/anne_pro/anne_pro_lighting.c @@ -0,0 +1,243 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include "anne_pro_lighting.h" +#include "uart_tx_ringbuf.h" +#include "quantum.h" +#include "ch.h" +#include "hal.h" + +#define LED_UART (&UARTD3) +/* UART transmission ringbuffer for the LED UART */ +static uint8_t led_uart_tx_buffer[256] = {0}; +static uart_tx_ringbuf_t led_uart_ringbuf = { + .buf = led_uart_tx_buffer, + .uart = LED_UART, + .size = sizeof(led_uart_tx_buffer), + .sending_elements = 0, + .head = 0, + .tail = 0, +}; + +/* Handler for finsihed LED UART transmissions */ +static void led_uart_txend(UARTDriver *uart) { + uart_tx_ringbuf_finish_transmission(&led_uart_ringbuf); +} + +/* LED UART configuration */ +static UARTConfig led_uart_cfg = { + .txend1_cb = led_uart_txend, + .txend2_cb = NULL, + .rxend_cb = NULL, + .rxchar_cb = NULL, + .rxerr_cb = NULL, + .speed = 38400, + .cr1 = 0, + .cr2 = USART_CR2_LINEN, + .cr3 = 0 +}; + +/* Timer to keep track of seconds, this allows the backlight timeout */ +static virtual_timer_t seconds_timer; +static volatile uint32_t seconds_timer_counter = 0; + +/* Timer callback to update the seconds timer */ +static void update_seconds_timer(virtual_timer_t *vtp, void *p) { + chSysLockFromISR(); + chVTSetI(&seconds_timer, TIME_MS2I(1000), update_seconds_timer, p); + chSysUnlockFromISR(); + + seconds_timer_counter++; +} + +/* State of the leds on the keyboard */ +static volatile bool leds_enabled = false; + +void anne_pro_lighting_init(void) { + /* Turn on lighting controller */ + writePinLow(C15); + setPinOutput(C15); + + /* Initialize the lighting UART */ + uartStart(LED_UART, &led_uart_cfg); + palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7)); + palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7)); + + /* Enable the seconds timer for backlight timeout */ + chVTSet(&seconds_timer, TIME_MS2I(1000), update_seconds_timer, NULL); +} + +/* Buffer for the keystate packet */ +static uint8_t keystate[12] = {9, 10, 7, 0}; + +/* Update the dynamic lighting packet based on a keypress */ +void anne_pro_lighting_update_dynamic(keyrecord_t *record) { + /* Make sure this is actually a keypress event */ + if (IS_NOEVENT(record->event)) return; + /* Only update dynamic lighting modes when leds are enabled */ + if (leds_enabled) { + /* Calculate the position of the key that was pressed */ + uint8_t row = record->event.key.row; + uint8_t col = record->event.key.col; + int position = row * MATRIX_COLS + col; + int index = position / 8; + int bit = position % 8; + + /* Update the keystate based on the location */ + if (record->event.pressed) { + keystate[3 + index] |= (1 << bit); + } else { + keystate[3 + index] &= ~(1 << bit); + } + + /* Send the keystate to the LED controller */ + uart_tx_ringbuf_write(&led_uart_ringbuf, 12, keystate); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + } +} + + +/* Timer keeping track of the last keypress */ +static uint32_t last_keypress_timer = 0; +/* Was the lighting turned off by the timeout */ +static bool turned_off_by_timeout = false; + +/* Update the last keypress timer when a key is pressed */ +void anne_pro_lighting_update_timeout(keyrecord_t *record) { + /* Make sure this is actually a keypress event */ + if (IS_NOEVENT(record->event)) return; + + if (record->event.pressed) { + /* Update the last keypress timer */ + last_keypress_timer = seconds_timer_counter; + + /* If the lighting was turned off by a timeout, turn it back on */ + if (turned_off_by_timeout) { + anne_pro_lighting_on(); + turned_off_by_timeout = false; + } + } +} + +/* Update lighting, should be called every matrix scan */ +void anne_pro_lighting_update(void) { + /* If the backlight in on, and the last keypress timeout is hit */ + if (leds_enabled && (seconds_timer_counter - last_keypress_timer) >= BACKLIGHT_TIMEOUT) { + /* Turn off the backlight */ + anne_pro_lighting_off(); + turned_off_by_timeout = true; + } + + if (!uart_tx_ringbuf_empty(&led_uart_ringbuf)) { + /* we need to slightly delay transmission in order for it to register + * on the receiving end */ + chThdSleepMilliseconds(1); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + } +} + +/* Toggle the lighting on/off */ +void anne_pro_lighting_toggle(void) { + if (!leds_enabled) { + anne_pro_lighting_on(); + } else { + anne_pro_lighting_off(); + } +} + +/* Turn the lighting on */ +void anne_pro_lighting_on(void) { + /* Wake up the LED controller */ + writePinHigh(C15); + chThdSleepMilliseconds(50); + /* Send turn light on command */ + uart_tx_ringbuf_write(&led_uart_ringbuf, 3, "\x09\x01\x01"); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + leds_enabled = true; + /* Wait for the message to be sent */ + chThdSleepMilliseconds(10); +} + +/* Turn the lighting off */ +void anne_pro_lighting_off(void) { + /* Send turn light off command */ + uart_tx_ringbuf_write(&led_uart_ringbuf, 4, "\x09\x02\x01\x00"); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + leds_enabled = false; + /* Sleep the LED controller */ + writePinLow(C15); +} + +/* Is the lighting enabled? */ +bool anne_pro_lighting_enabled(void) { + return leds_enabled; +} + +/* Select the next effect rate */ +void anne_pro_lighting_rate_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x01\x00"); + } +} + +/* Select the next brightness */ +void anne_pro_lighting_brightness_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x00\x01"); + } +} + +/* Select the next lighting mode */ +void anne_pro_lighting_mode_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x01\x00\x00"); + } +} + +/* Set the lighting mode */ +void anne_pro_lighting_mode(uint8_t mode) { + if (leds_enabled) { + uint8_t buf[] = {9, 2, 1, mode}; + uart_tx_ringbuf_write(&led_uart_ringbuf, 4, buf); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + } +} + +/* Set the lighting mode to the last lighting mode */ +void anne_pro_lighting_mode_last(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 3, "\x09\x01\x01"); + } +} + +/* Set the rate and brightness */ +void anne_pro_lighting_rate_brightness(uint8_t rate, uint8_t brightness) { + if (leds_enabled) { + if (brightness > 10) brightness = 10; + + uint8_t buf[] = {9, 4, 2, rate, brightness, 0}; + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, buf); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + } +} + +/* Set lighting for individual keys, this takes number of keys and a payload + that describes which keys and the colors of those keys */ +void anne_pro_lighting_set_keys(uint8_t keys, uint8_t *payload) { + uint8_t buf[] = {9, 3 + 5 * keys, 11, 202, keys}; + uart_tx_ringbuf_write(&led_uart_ringbuf, 5, buf); + uart_tx_ringbuf_write(&led_uart_ringbuf, 5 * keys, payload); +} diff --git a/keyboards/anne_pro/anne_pro_lighting.h b/keyboards/anne_pro/anne_pro_lighting.h new file mode 100644 index 00000000000..e8dd418487d --- /dev/null +++ b/keyboards/anne_pro/anne_pro_lighting.h @@ -0,0 +1,55 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#pragma once +#include "quantum.h" + +#define APL_MODE_OFF 0 +#define APL_MODE_RED 1 +#define APL_MODE_YELLOW 2 +#define APL_MODE_GREEN 3 +#define APL_MODE_CYAN 4 +#define APL_MODE_BLUE 5 +#define APL_MODE_PURPLE 6 +#define APL_MODE_PINK 7 +#define APL_MODE_ORANGE 8 +#define APL_MODE_WHITE 9 +#define APL_MODE_FLAG_FANCE 10 +#define APL_MODE_FLAG_ITALY 11 +#define APL_MODE_FLAG_ARGENTINA 12 +#define APL_MODE_BREATHING 13 +#define APL_MODE_RAINBOW 14 +#define APL_MODE_REACTIVE_FADE 15 +#define APL_MODE_REACTIVE_HOLD 16 +#define APL_MODE_REACTIVE_LINE 17 +#define APL_MODE_RANDOM 18 +#define APL_MODE_CUSTOM 128 + +void anne_pro_lighting_init(void); +void anne_pro_lighting_update(void); +void anne_pro_lighting_update_dynamic(keyrecord_t *record); +void anne_pro_lighting_update_timeout(keyrecord_t *record); +void anne_pro_lighting_toggle(void); +void anne_pro_lighting_on(void); +void anne_pro_lighting_off(void); +bool anne_pro_lighting_enabled(void); +void anne_pro_lighting_rate_next(void); +void anne_pro_lighting_brightness_next(void); +void anne_pro_lighting_mode_next(void); +void anne_pro_lighting_mode(uint8_t mode); +void anne_pro_lighting_mode_last(void); +void anne_pro_lighting_rate_brightness(uint8_t speed, uint8_t brightness); +void anne_pro_lighting_set_keys(uint8_t keys, uint8_t *payload); diff --git a/keyboards/anne_pro/boards/STM32L151_ANNE_PRO/board.mk b/keyboards/anne_pro/boards/STM32L151_ANNE_PRO/board.mk new file mode 100644 index 00000000000..11ddc8e83fd --- /dev/null +++ b/keyboards/anne_pro/boards/STM32L151_ANNE_PRO/board.mk @@ -0,0 +1,5 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_L152RE/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_L152RE diff --git a/keyboards/anne_pro/chconf.h b/keyboards/anne_pro/chconf.h new file mode 100644 index 00000000000..84fe151c34e --- /dev/null +++ b/keyboards/anne_pro/chconf.h @@ -0,0 +1,48 @@ +/* Copyright 2020 QMK + * + * 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 . + */ + +/* + * This file was auto-generated by: + * `qmk chibios-confmigrate -i keyboards/anne_pro/chconf.h -r lib/chibios/os/rt/templates/chconf.h` + */ + +#pragma once + +#define CH_CFG_ST_RESOLUTION 16 + +#define CH_CFG_ST_FREQUENCY 1000 + +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +#define CH_DBG_ENABLE_CHECKS FALSE + +#define CH_DBG_ENABLE_ASSERTS FALSE + +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +#define CH_DBG_ENABLE_STACK_CHECK FALSE + +#define CH_DBG_FILL_THREADS FALSE + +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add threads initialization code here.*/ \ +} + +#include_next + diff --git a/keyboards/anne_pro/config.h b/keyboards/anne_pro/config.h new file mode 100644 index 00000000000..24e4daea570 --- /dev/null +++ b/keyboards/anne_pro/config.h @@ -0,0 +1,27 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#pragma once + +#define STM32_HSECLK 16000000U +#define STM32_BOOTLOADER_ADDRESS 0x08000000 +#define STM32L152xB + +/* + * Timeout after which the backlight of the keyboard is disabled if no keypresses are received. + * If this feature is not needed you can set the timeout to UINT32_MAX, this is more than 100 years. + */ +#define BACKLIGHT_TIMEOUT 60 diff --git a/keyboards/anne_pro/halconf.h b/keyboards/anne_pro/halconf.h new file mode 100644 index 00000000000..b32462bf32d --- /dev/null +++ b/keyboards/anne_pro/halconf.h @@ -0,0 +1,55 @@ +/* Copyright 2020 QMK + * + * 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 . + */ + +/* + * This file was auto-generated by: + * `qmk chibios-confmigrate -i keyboards/anne_pro/halconf.h -r platforms/chibios/boards/common/configs/halconf.h` + */ + +#pragma once + +#define HAL_USE_SERIAL_USB TRUE + +#define HAL_USE_UART TRUE + +#define PAL_USE_WAIT TRUE + +#define ADC_USE_WAIT FALSE + +#define ADC_USE_MUTUAL_EXCLUSION FALSE + +#define DAC_USE_WAIT FALSE + +#define DAC_USE_MUTUAL_EXCLUSION FALSE + +#define MAC_USE_EVENTS FALSE + +#define SERIAL_BUFFERS_SIZE 16 + +#define SERIAL_USB_BUFFERS_SIZE 256 + +#define SPI_USE_WAIT FALSE + +#define SPI_USE_MUTUAL_EXCLUSION FALSE + +#define UART_USE_WAIT TRUE + +#define WSPI_USE_WAIT FALSE + +#define WSPI_USE_MUTUAL_EXCLUSION FALSE + +#include_next + diff --git a/keyboards/anne_pro/keyboard.json b/keyboards/anne_pro/keyboard.json new file mode 100644 index 00000000000..1ab3abb759a --- /dev/null +++ b/keyboards/anne_pro/keyboard.json @@ -0,0 +1,92 @@ +{ + "manufacturer": "Obins", + "keyboard_name": "Anne Pro", + "maintainer": "msvisser / TinfoilSubmarine", + "bootloader": "stm32-dfu", + "diode_direction": "COL2ROW", + "features": { + "bootmagic": false, + "command": false, + "console": false, + "extrakey": true, + "mousekey": false, + "nkro": true + }, + "matrix_pins": { + "cols": ["A5", "A6", "A7", "B0", "B1", "B12", "B13", "B14", "A8", "A9", "A15", "B3", "B4", "B5"], + "rows": ["B9", "B8", "B7", "B6", "A0"] + }, + "url": "https://www.hexcore.xyz/annepro", + "usb": { + "device_version": "1.0.0", + "pid": "0xFBF1", + "vid": "0xAC20" + }, + "layouts": { + "LAYOUT": { + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0}, + {"matrix": [0, 1], "x": 1, "y": 0}, + {"matrix": [0, 2], "x": 2, "y": 0}, + {"matrix": [0, 3], "x": 3, "y": 0}, + {"matrix": [0, 4], "x": 4, "y": 0}, + {"matrix": [0, 5], "x": 5, "y": 0}, + {"matrix": [0, 6], "x": 6, "y": 0}, + {"matrix": [0, 7], "x": 7, "y": 0}, + {"matrix": [0, 8], "x": 8, "y": 0}, + {"matrix": [0, 9], "x": 9, "y": 0}, + {"matrix": [0, 10], "x": 10, "y": 0}, + {"matrix": [0, 11], "x": 11, "y": 0}, + {"matrix": [0, 12], "x": 12, "y": 0}, + {"matrix": [0, 13], "x": 13, "y": 0, "w": 2}, + {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5}, + {"matrix": [1, 1], "x": 1.5, "y": 1}, + {"matrix": [1, 2], "x": 2.5, "y": 1}, + {"matrix": [1, 3], "x": 3.5, "y": 1}, + {"matrix": [1, 4], "x": 4.5, "y": 1}, + {"matrix": [1, 5], "x": 5.5, "y": 1}, + {"matrix": [1, 6], "x": 6.5, "y": 1}, + {"matrix": [1, 7], "x": 7.5, "y": 1}, + {"matrix": [1, 8], "x": 8.5, "y": 1}, + {"matrix": [1, 9], "x": 9.5, "y": 1}, + {"matrix": [1, 10], "x": 10.5, "y": 1}, + {"matrix": [1, 11], "x": 11.5, "y": 1}, + {"matrix": [1, 12], "x": 12.5, "y": 1}, + {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5}, + {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75}, + {"matrix": [2, 1], "x": 1.75, "y": 2}, + {"matrix": [2, 2], "x": 2.75, "y": 2}, + {"matrix": [2, 3], "x": 3.75, "y": 2}, + {"matrix": [2, 4], "x": 4.75, "y": 2}, + {"matrix": [2, 5], "x": 5.75, "y": 2}, + {"matrix": [2, 6], "x": 6.75, "y": 2}, + {"matrix": [2, 7], "x": 7.75, "y": 2}, + {"matrix": [2, 8], "x": 8.75, "y": 2}, + {"matrix": [2, 9], "x": 9.75, "y": 2}, + {"matrix": [2, 10], "x": 10.75, "y": 2}, + {"matrix": [2, 11], "x": 11.75, "y": 2}, + {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25}, + {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25}, + {"matrix": [3, 1], "x": 2.25, "y": 3}, + {"matrix": [3, 2], "x": 3.25, "y": 3}, + {"matrix": [3, 3], "x": 4.25, "y": 3}, + {"matrix": [3, 4], "x": 5.25, "y": 3}, + {"matrix": [3, 5], "x": 6.25, "y": 3}, + {"matrix": [3, 6], "x": 7.25, "y": 3}, + {"matrix": [3, 7], "x": 8.25, "y": 3}, + {"matrix": [3, 8], "x": 9.25, "y": 3}, + {"matrix": [3, 9], "x": 10.25, "y": 3}, + {"matrix": [3, 10], "x": 11.25, "y": 3}, + {"matrix": [3, 13], "x": 12.25, "y": 3, "w": 2.75}, + {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25}, + {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25}, + {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25}, + {"matrix": [4, 5], "x": 3.75, "y": 4, "w": 6.25}, + {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25}, + {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25}, + {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25}, + {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25} + ] + } + } +} diff --git a/keyboards/anne_pro/keymaps/anne-pro-2-mac/keymap.c b/keyboards/anne_pro/keymaps/anne-pro-2-mac/keymap.c new file mode 100644 index 00000000000..67d62538675 --- /dev/null +++ b/keyboards/anne_pro/keymaps/anne-pro-2-mac/keymap.c @@ -0,0 +1,51 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Anne Pro 2 MacOS layout +Includes Media Keys and TAP features, see readme.md */ + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MT(MOD_RSFT, KC_UP), + KC_LCTL, KC_LALT, KC_LGUI, KC_SPACE, KC_LALT, LT(1,KC_LEFT), LT(2,KC_DOWN), MT(MOD_RCTL, KC_RGHT) + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, + XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_UP, KC_SLCT, KC_PAUS, KC_HOME, KC_END, KC_PSCR, + XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGUP, KC_PGDN, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TG(3), XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_DEL, _______, + _______, _______, _______, XXXXXXX, _______, _______, _______, _______ + ), + [2] = LAYOUT( + QK_RBT, KC_MSTP, KC_VOLD, KC_VOLU, KC_MRWD, KC_MPLY, KC_MFFD, KC_MUTE, XXXXXXX, APL_MOD, APL_RGB, APL_RAT, APL_BRT, 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, _______, _______, _______, _______ + ), + [3] = LAYOUT( + TG(3), APB_HC1, APB_HC2, APB_HC3, APB_HC4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, APB_LGC, APB_OFF, APB_ON, XXXXXXX, + XXXXXXX, APB_HS1, APB_HS2, APB_HS3, APB_HS4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, APB_HD1, APB_HD2, APB_HD3, APB_HD4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + APB_HLQ, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + ), +}; diff --git a/keyboards/anne_pro/keymaps/anne-pro-2-mac/readme.md b/keyboards/anne_pro/keymaps/anne-pro-2-mac/readme.md new file mode 100644 index 00000000000..9c96f871415 --- /dev/null +++ b/keyboards/anne_pro/keymaps/anne-pro-2-mac/readme.md @@ -0,0 +1,45 @@ +# Anne Pro 2 MAC keymap + +### This keymap adds TAP, Media Keys features and AP2-like backlight control. +### Maintainer: [angelokofficial](https://github.com/angelokofficial) + + +__Keys:__ + +ANNE+0 - off/on the backlight +ANNE+9 - switch the backlight profile +ANNE + =/+ - increases brightness +ANNE + - -/_ - changes backlight speed +ANNE+ESC - reset the keyboard (instead of button on the back side) +ANNE+ESC+hold ESC - enter to the bootloader (DFU) mode + +__TAP:__ + +Right Shift - up arrow +ANNE - down arrow +FN - left arrow +Right CTRL - right arrow + + +__Bluetooth:__ + +Fn+B - enter BT mode +=/+ - turn ON BT +-/_ - turn OFF BT +0 - enter legacy BT mode +1,2,3,4 - should work as bt profiles for switch among connected devices + + +**Media keys:** + +ANNE+1 - stop +ANNE+2 - volume down +ANNE+3 - volume up +ANNE+4 - previous track +ANNE+5 - pause/play +ANNE+6 - next track +ANNE+7 - mute/unmute volume + + +All other keys remain on their own places. +To compile: `make anne_pro:` diff --git a/keyboards/anne_pro/keymaps/anne-pro-2-win/keymap.c b/keyboards/anne_pro/keymaps/anne-pro-2-win/keymap.c new file mode 100644 index 00000000000..bea0e3f9c27 --- /dev/null +++ b/keyboards/anne_pro/keymaps/anne-pro-2-win/keymap.c @@ -0,0 +1,51 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Anne Pro 2 default layout +Includes Media Keys and TAP features, see readme.md */ + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MT(MOD_RSFT, KC_UP), + KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_RALT, LT(1,KC_LEFT), LT(2,KC_DOWN), MT(MOD_RCTL, KC_RGHT) + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, + XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_UP, KC_SLCT, KC_PAUS, KC_HOME, KC_END, KC_PSCR, + XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGUP, KC_PGDN, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TG(3), XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_DEL, _______, + _______, _______, _______, XXXXXXX, _______, _______, _______, _______ + ), + [2] = LAYOUT( + QK_RBT, KC_MSTP, KC_VOLD, KC_VOLU, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, XXXXXXX, APL_MOD, APL_RGB, APL_RAT, APL_BRT, 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, _______, _______, _______, _______ + ), + [3] = LAYOUT( + TG(3), APB_HC1, APB_HC2, APB_HC3, APB_HC4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, APB_LGC, APB_OFF, APB_ON, XXXXXXX, + XXXXXXX, APB_HS1, APB_HS2, APB_HS3, APB_HS4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, APB_HD1, APB_HD2, APB_HD3, APB_HD4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + APB_HLQ, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + ), +}; diff --git a/keyboards/anne_pro/keymaps/anne-pro-2-win/readme.md b/keyboards/anne_pro/keymaps/anne-pro-2-win/readme.md new file mode 100644 index 00000000000..b471d6d019d --- /dev/null +++ b/keyboards/anne_pro/keymaps/anne-pro-2-win/readme.md @@ -0,0 +1,45 @@ +# Anne Pro 2 Windows keymap + +### This keymap adds TAP, Media Keys features and AP2-like backlight control. +### Maintainer: [angelokofficial](https://github.com/angelokofficial) + + +__Keys:__ + +ANNE+0 - off/on the backlight +ANNE+9 - switch the backlight profile +ANNE + =/+ - increases brightness +ANNE + - -/_ - changes backlight speed +ANNE+ESC - reset the keyboard (instead of button on the back side) +ANNE+ESC+hold ESC - enter to the bootloader (DFU) mode + +__TAP:__ + +Right Shift - up arrow +ANNE - down arrow +FN - left arrow +Right CTRL - right arrow + + +__Bluetooth:__ + +Fn+B - enter BT mode +=/+ - turn ON BT +-/_ - turn OFF BT +0 - enter legacy BT mode +1,2,3,4 - should work as bt profiles for switch among connected devices + + +**Media keys:** + +ANNE+1 - stop +ANNE+2 - volume down +ANNE+3 - volume up +ANNE+4 - previous track +ANNE+5 - pause/play +ANNE+6 - next track +ANNE+7 - mute/unmute volume + + +All other keys remain on their own places. +To compile: `make anne_pro:` diff --git a/keyboards/anne_pro/keymaps/arrow/keymap.c b/keyboards/anne_pro/keymaps/arrow/keymap.c new file mode 100644 index 00000000000..dca5c6ce156 --- /dev/null +++ b/keyboards/anne_pro/keymaps/arrow/keymap.c @@ -0,0 +1,49 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Default Anne Pro layout, arrows style */ +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_UP, KC_RSFT, + KC_LCTL, MO(2), KC_LALT, KC_SPACE, KC_LEFT, KC_DOWN, KC_RGHT, MO(1) + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, + XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, APL_RGB, APL_RAT, APL_BRT, APL_MOD, KC_UP, KC_SLCT, KC_PAUS, KC_HOME, KC_END, KC_PSCR, + XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGUP, KC_PGDN, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TG(3), XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_SLSH, _______, + _______, _______, _______, XXXXXXX, _______, _______, _______, _______ + ), + [2] = LAYOUT( + QK_RBT, 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, _______, _______, _______, _______ + ), + [3] = LAYOUT( + TG(3), APB_HC1, APB_HC2, APB_HC3, APB_HC4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, APB_LGC, APB_OFF, APB_ON, XXXXXXX, + XXXXXXX, APB_HS1, APB_HS2, APB_HS3, APB_HS4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, APB_HD1, APB_HD2, APB_HD3, APB_HD4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + APB_HLQ, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + ), +}; diff --git a/keyboards/anne_pro/keymaps/arrow/readme.md b/keyboards/anne_pro/keymaps/arrow/readme.md new file mode 100644 index 00000000000..87ff650b8dc --- /dev/null +++ b/keyboards/anne_pro/keymaps/arrow/readme.md @@ -0,0 +1,22 @@ +# Anne Pro Arrow keymap + +### Maintainer: [msvisser](https://github.com/msvisser) + +This keymap is the arrows keymap supplied on the original Anne Pro firmware. +However the interface for Bluetooth is changed slightly. + +### Bluetooth +To enable the Bluetooht layer press `FN+B`. + +While in the Bluetooth layer: +- `ESC` - Exit Bluetooth layer +- `1, 2, 3, 4` - Connect to saved profile +- `Q, W, E, R` - Save connection to profile +- `A, S, D, F` - Delete saved connection +- `0` - Toggle legacy Bluetooth mode +- `-` - Disable Bluetooth +- `+` - Enable Bluetooth + +Finally the lighting on the `ESC` key tries to indicate the connection status +of the Bluetooth. However this might sometimes go out of sync. To update the +connection status press the left `CTRL` key. diff --git a/keyboards/anne_pro/keymaps/default/keymap.c b/keyboards/anne_pro/keymaps/default/keymap.c new file mode 100644 index 00000000000..1dbfbdf85b1 --- /dev/null +++ b/keyboards/anne_pro/keymaps/default/keymap.c @@ -0,0 +1,49 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Default Anne Pro layout, windows style */ +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LCTL, KC_LWIN, KC_LALT, KC_SPACE, KC_RALT, MO(1), MO(2), KC_RCTL + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, + XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, APL_RGB, APL_RAT, APL_BRT, APL_MOD, KC_UP, KC_SLCT, KC_PAUS, KC_HOME, KC_END, KC_PSCR, + XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGUP, KC_PGDN, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TG(3), XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_DEL, _______, + _______, _______, _______, XXXXXXX, _______, _______, _______, _______ + ), + [2] = LAYOUT( + QK_RBT, 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, _______, _______, _______, _______ + ), + [3] = LAYOUT( + TG(3), APB_HC1, APB_HC2, APB_HC3, APB_HC4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, APB_LGC, APB_OFF, APB_ON, XXXXXXX, + XXXXXXX, APB_HS1, APB_HS2, APB_HS3, APB_HS4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, APB_HD1, APB_HD2, APB_HD3, APB_HD4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + APB_HLQ, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + ), +}; diff --git a/keyboards/anne_pro/keymaps/default/readme.md b/keyboards/anne_pro/keymaps/default/readme.md new file mode 100644 index 00000000000..1d2aa725b92 --- /dev/null +++ b/keyboards/anne_pro/keymaps/default/readme.md @@ -0,0 +1,22 @@ +# Anne Pro Default (Windows) keymap + +### Maintainer: [msvisser](https://github.com/msvisser) + +This keymap is the default Windows keymap supplied on the original Anne Pro +firmware. However the interface for Bluetooth is changed slightly. + +### Bluetooth +To enable the Bluetooht layer press `FN+B`. + +While in the Bluetooth layer: +- `ESC` - Exit Bluetooth layer +- `1, 2, 3, 4` - Connect to saved profile +- `Q, W, E, R` - Save connection to profile +- `A, S, D, F` - Delete saved connection +- `0` - Toggle legacy Bluetooth mode +- `-` - Disable Bluetooth +- `+` - Enable Bluetooth + +Finally the lighting on the `ESC` key tries to indicate the connection status +of the Bluetooth. However this might sometimes go out of sync. To update the +connection status press the left `CTRL` key. diff --git a/keyboards/anne_pro/keymaps/macos/keymap.c b/keyboards/anne_pro/keymaps/macos/keymap.c new file mode 100644 index 00000000000..fb25de17c59 --- /dev/null +++ b/keyboards/anne_pro/keymaps/macos/keymap.c @@ -0,0 +1,49 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Default Anne Pro layout, macOS style with LALT and LWIN switched */ +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LCTL, KC_LALT, KC_LWIN, KC_SPACE, KC_RALT, MO(1), MO(2), KC_RCTL + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, + XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, APL_RGB, APL_RAT, APL_BRT, APL_MOD, KC_UP, KC_SLCT, KC_PAUS, KC_HOME, KC_END, KC_PSCR, + XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGUP, KC_PGDN, XXXXXXX, + _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TG(3), XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_DEL, _______, + _______, _______, _______, XXXXXXX, _______, _______, _______, _______ + ), + [2] = LAYOUT( + QK_RBT, 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, _______, _______, _______, _______ + ), + [3] = LAYOUT( + TG(3), APB_HC1, APB_HC2, APB_HC3, APB_HC4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, APB_LGC, APB_OFF, APB_ON, XXXXXXX, + XXXXXXX, APB_HS1, APB_HS2, APB_HS3, APB_HS4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, APB_HD1, APB_HD2, APB_HD3, APB_HD4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + APB_HLQ, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + ), +}; diff --git a/keyboards/anne_pro/keymaps/macos/readme.md b/keyboards/anne_pro/keymaps/macos/readme.md new file mode 100644 index 00000000000..1fca1acad85 --- /dev/null +++ b/keyboards/anne_pro/keymaps/macos/readme.md @@ -0,0 +1,22 @@ +# Anne Pro macOS keymap + +### Maintainer: [msvisser](https://github.com/msvisser) + +This keymap is the macOS keymap supplied on the original Anne Pro firmware. +However the interface for Bluetooth is changed slightly. + +### Bluetooth +To enable the Bluetooht layer press `FN+B`. + +While in the Bluetooth layer: +- `ESC` - Exit Bluetooth layer +- `1, 2, 3, 4` - Connect to saved profile +- `Q, W, E, R` - Save connection to profile +- `A, S, D, F` - Delete saved connection +- `0` - Toggle legacy Bluetooth mode +- `-` - Disable Bluetooth +- `+` - Enable Bluetooth + +Finally the lighting on the `ESC` key tries to indicate the connection status +of the Bluetooth. However this might sometimes go out of sync. To update the +connection status press the left `CTRL` key. diff --git a/keyboards/anne_pro/ld/STM32L151.ld b/keyboards/anne_pro/ld/STM32L151.ld new file mode 100644 index 00000000000..f8019baa471 --- /dev/null +++ b/keyboards/anne_pro/ld/STM32L151.ld @@ -0,0 +1,85 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * ST32L151 memory map. + */ +MEMORY +{ + flash0 : org = 0x08004000, len = 48k + flash1 : org = 0x00000000, len = 0 + flash2 : org = 0x00000000, len = 0 + flash3 : org = 0x00000000, len = 0 + flash4 : org = 0x00000000, len = 0 + flash5 : org = 0x00000000, len = 0 + flash6 : org = 0x00000000, len = 0 + flash7 : org = 0x00000000, len = 0 + ram0 : org = 0x20000000, len = 10k + ram1 : org = 0x00000000, len = 0 + ram2 : org = 0x00000000, len = 0 + ram3 : org = 0x00000000, len = 0 + ram4 : org = 0x00000000, len = 0 + ram5 : org = 0x00000000, len = 0 + ram6 : org = 0x00000000, len = 0 + ram7 : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/keyboards/anne_pro/mcuconf.h b/keyboards/anne_pro/mcuconf.h new file mode 100644 index 00000000000..03c75f2c32e --- /dev/null +++ b/keyboards/anne_pro/mcuconf.h @@ -0,0 +1,201 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +/* + * STM32L1xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define STM32L1xx_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED FALSE +#define STM32_ADC_CLOCK_ENABLED FALSE +#define STM32_USB_CLOCK_ENABLED TRUE +#define STM32_MSIRANGE STM32_MSIRANGE_2M +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_PLLMUL_VALUE 6 +#define STM32_PLLDIV_VALUE 3 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#define STM32_RTCSEL STM32_RTCSEL_LSI +#define STM32_RTCPRE STM32_RTCPRE_DIV2 +#define STM32_VOS STM32_VOS_1P8 +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI16_PRIORITY 6 +#define STM32_IRQ_EXTI17_PRIORITY 6 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_22_PRIORITY 6 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_IRQ_PRIORITY 6 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM9 FALSE +#define STM32_GPT_USE_TIM11 FALSE +#define STM32_GPT_TIM2_IRQ_PRIORITY 7 +#define STM32_GPT_TIM3_IRQ_PRIORITY 7 +#define STM32_GPT_TIM4_IRQ_PRIORITY 7 +#define STM32_GPT_TIM6_IRQ_PRIORITY 7 +#define STM32_GPT_TIM7_IRQ_PRIORITY 7 +#define STM32_GPT_TIM9_IRQ_PRIORITY 7 +#define STM32_GPT_TIM11_IRQ_PRIORITY 7 + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C2_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C2_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM9 FALSE +#define STM32_ICU_TIM2_IRQ_PRIORITY 7 +#define STM32_ICU_TIM3_IRQ_PRIORITY 7 +#define STM32_ICU_TIM4_IRQ_PRIORITY 7 +#define STM32_ICU_TIM9_IRQ_PRIORITY 7 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM9 FALSE +#define STM32_PWM_TIM2_IRQ_PRIORITY 7 +#define STM32_PWM_TIM3_IRQ_PRIORITY 7 +#define STM32_PWM_TIM4_IRQ_PRIORITY 7 +#define STM32_PWM_TIM9_IRQ_PRIORITY 7 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_USART3_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 TRUE +#define STM32_UART_USE_USART3 TRUE +#define STM32_UART_USART1_IRQ_PRIORITY 12 +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_USB1 TRUE +#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE +#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 +#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + diff --git a/keyboards/anne_pro/readme.md b/keyboards/anne_pro/readme.md new file mode 100644 index 00000000000..72a2a3ba4ea --- /dev/null +++ b/keyboards/anne_pro/readme.md @@ -0,0 +1,36 @@ +# Anne Pro + +![Anne Pro](https://i.imgur.com/wF7mz7u.jpg) + +*QMK firmware port for the Anne Pro 60% keyboard produced by [Obins](http://en.obins.net)* + +* Keyboard Maintainers: [Michiel Visser](https://github.com/msvisser), [Joel Beckmeyer](https://github.com/TinfoilSubmarine/) +* Hardware Supported: Anne Pro (the original, not the _Anne Pro 2_) +* Hardware Availability: Discontinued + +Make example for this keyboard (after setting up your build environment): + + make anne_pro:default + +Flashing the firmware can easily be done when the keyboard is in DFU mode: + + make anne_pro:default:flash + +The default Arrows and macOS keyboard layouts are also included and can be used with `arrow` or `macos` instead of `default`. + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Bootloader +If your keyboard has stock firmware, the only way to enter the bootloader is by first unplugging the keyboard. Hold down the Esc key and while holding it down, briefly press the button on the bottom of the keyboard using a paperclip or some other small object. You can then release the Esc key, at which point it will enter the bootloader. You can now plug the keyboard back in. + +If you have previously flashed QMK firmware, you can enter the bootloader with a long press of the QK_REBOOT keycode (mapped to ANNE+Esc in the included keymaps). + +## Firmware requirements for LED backlight +To get functioning backlighting for the Anne Pro the original LED firmware is required. This should be the version v1.40, which is available on the [Hexcore website](https://service.hexcore.xyz/manual/annepro/#42-anne-pro-firmware). __The backlight will not work with the newer ObinsKit firmware!__ This firmware can be installed by following the update guide on the same Hexcore website, or using `dfu-util` if you know what you are doing. + +## Bluetooth pairing +The Bluetooth setup is similar to the original Anne Pro firmware. After pressing `Fn + B` the Bluetooth layer shows up. By pressing the `+` key Bluetooth is enabled. You can now pair your computer. Once the computer asks for the pairing code the lights on the keyboard should turn off. You can now simply enter the pairing code and hit connect on the computer, this should pair the device. + +## Known problems +- Capslock indicator light is not working. This is the results of buggy lighting firmware by Obins, which means that the complete backlight would turn on if the capslock was toggled. +- Sending macros over Bluetooth is limited to about 20 keypresses, this is because the transmit buffer is limited and only starts sending after all keypresses are put in the buffer. diff --git a/keyboards/anne_pro/rules.mk b/keyboards/anne_pro/rules.mk new file mode 100644 index 00000000000..4f91cb804c8 --- /dev/null +++ b/keyboards/anne_pro/rules.mk @@ -0,0 +1,33 @@ +## chip/board settings +# the next two should match the directories in +# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +MCU_FAMILY = STM32 +MCU_SERIES = STM32L1xx +# linker script to use +# it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +MCU_LDSCRIPT = STM32L151 +# startup code to use +# is should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +MCU_STARTUP = stm32l1xx +# board to use +# it should exist either in /os/hal/boards/ +# or /boards +BOARD = STM32L151_ANNE_PRO +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m3 +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +ARMV = 7 + +# Extra arguments for dfu-util to flash to the correct location +DFU_ARGS = -d 0483:df11 -a 0 -s 0x08004000:leave + +# Extra source files +SRC += uart_tx_ringbuf.c anne_pro_lighting.c anne_pro_bluetooth.c + +# Required for functionality with Bluetooth +NO_USB_STARTUP_CHECK = yes + +# Enter lower-power sleep mode when on the ChibiOS idle thread +OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE diff --git a/keyboards/anne_pro/uart_tx_ringbuf.c b/keyboards/anne_pro/uart_tx_ringbuf.c new file mode 100644 index 00000000000..3ff1a82478d --- /dev/null +++ b/keyboards/anne_pro/uart_tx_ringbuf.c @@ -0,0 +1,89 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#include "uart_tx_ringbuf.h" +#include "hal.h" + +int uart_tx_ringbuf_elements(uart_tx_ringbuf_t *ringbuf) { + return ringbuf->head - ringbuf->tail; +} + +int uart_tx_ringbuf_space(uart_tx_ringbuf_t *ringbuf) { + return ringbuf->size - uart_tx_ringbuf_elements(ringbuf); +} + +bool uart_tx_ringbuf_empty(uart_tx_ringbuf_t *ringbuf) { + return uart_tx_ringbuf_elements(ringbuf) == 0; +} + +bool uart_tx_ringbuf_full(uart_tx_ringbuf_t *ringbuf) { + return uart_tx_ringbuf_elements(ringbuf) == ringbuf->size; +} + +void uart_tx_ringbuf_start_transmission(uart_tx_ringbuf_t *ringbuf) { + /* Do not start transmission when one is already in progress */ + if (ringbuf->sending_elements != 0) return; + + size_t elements = uart_tx_ringbuf_elements(ringbuf); + /* Do not start transmission when ringbuffer is empty */ + if (elements == 0) return; + + /* Get the offset of the first and last item */ + size_t first_offset = (ringbuf->tail & (ringbuf->size - 1)); + + /* Determine if this wraps around the end of the buffer */ + if (first_offset + elements >= ringbuf->size) { + /* If so only send until the end of the buffer */ + elements = ringbuf->size - first_offset; + } + + /* Send the selected elements */ + ringbuf->sending_elements = elements; + uartStartSend(ringbuf->uart, elements, ringbuf->buf + first_offset); +} + +void uart_tx_ringbuf_finish_transmission(uart_tx_ringbuf_t *ringbuf) { + /* Update the tail of the ringbuffer */ + ringbuf->tail += ringbuf->sending_elements; + /* Clear the sending elements */ + ringbuf->sending_elements = 0; +} + +bool uart_tx_ringbuf_put(uart_tx_ringbuf_t *ringbuf, uint8_t c) { + /* If the ringbuffer is full, ignore the request */ + if (uart_tx_ringbuf_full(ringbuf)) return false; + + /* Put the character into the ringbuffer */ + size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); + ringbuf->buf[head_offset] = c; + ringbuf->head++; + + return true; +} + +bool uart_tx_ringbuf_write(uart_tx_ringbuf_t *ringbuf, size_t count, void *data) { + /* If there is not enough space, ignore the request */ + if (uart_tx_ringbuf_space(ringbuf) < count) return false; + + for (int i = 0; i < count; i++) { + /* Put the character into the ringbuffer */ + size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); + ringbuf->buf[head_offset] = ((uint8_t *) data)[i]; + ringbuf->head++; + } + + return true; +} diff --git a/keyboards/anne_pro/uart_tx_ringbuf.h b/keyboards/anne_pro/uart_tx_ringbuf.h new file mode 100644 index 00000000000..c476dc17d60 --- /dev/null +++ b/keyboards/anne_pro/uart_tx_ringbuf.h @@ -0,0 +1,36 @@ +/* Copyright 2019 Michiel Visser (@msvisser) + * + * 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 . + */ + +#pragma once +#include "hal.h" + +typedef struct { + uint8_t *buf; + UARTDriver *uart; + size_t size; + volatile size_t sending_elements; + volatile size_t head; + volatile size_t tail; +} uart_tx_ringbuf_t; + +int uart_tx_ringbuf_elements(uart_tx_ringbuf_t *ringbuf); +int uart_tx_ringbuf_space(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_empty(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_full(uart_tx_ringbuf_t *ringbuf); +void uart_tx_ringbuf_start_transmission(uart_tx_ringbuf_t *ringbuf); +void uart_tx_ringbuf_finish_transmission(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_put(uart_tx_ringbuf_t *ringbuf, uint8_t c); +bool uart_tx_ringbuf_write(uart_tx_ringbuf_t *ringbuf, size_t count, void *data);