summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwisn <56162793+bwisn@users.noreply.github.com>2022-03-08 02:12:53 +0100
committerGitHub <noreply@github.com>2022-03-08 12:12:53 +1100
commit893d86cb896d82eb8c9d16251062dd6afa802533 (patch)
treecfadc87d02f22b583542f0e6030ad4c8150e279a
parent2ff646c642152df064da8dcf62ef328585de0197 (diff)
Add Anne Pro 2 keyboard (#14385)
* [keyboard] Initial support for Anne Pro 2 * [keyboard][AnnePro2] Keymap:update to a reasonable keymap with caps+hjkl => arrow * :( * changed to use HSI * support for annepro2 c18 * keyboard/annepro2: Very stupid matrix scan bug fix. * typo * swap COL14/13 * keyboard/annepro2: startup secondary LED MCU * keyboard/annepro2: typo fix * Add IO Values * Disable Combo feature * Update default keymap to Anne Pro 2 Official Keymap * keyboard/annepro2: keymap layer name changes * keyboard/annepro2 BLE Support * Fix keymap comment FN1 ESC was listed as ~ instead of ` * keyboard/annepro2: Bluetooth path * Keyboard annepro2 bidir led comms (#5) * Added bidirectional shine comms and moved led functionality to new file * Added bidirectional shine comms and moved led functionality to new file * Restore original functionality to existing keymaps using new shine commands * Fix dangling bracketless if statements * PR cleanup * add custom keycodes to switch led profiles * Optimize code * switch to prev profile before turning leds off * Add persistent led support with eeprom (#9) * adding HT32 support to chibios SPI master driver * add support for W25X20CL SPI eeprom * add makefile flag for eeprom feature * add spi support to keyboard startup and config * example keymap using eeprom profile loading * Cleanup to fix C15 eeprom/spi build errors (#11) * Cleanup to fix C15 eeprom/spi build errors * add newline at eof * LED Masking support for Shine Introduce companion update to ledSetMask and ledClearMask. In keymap `codetector` there is example of how to map caps_lock to the caps_lock key light on the keyboard. * [AnnePro2]: update bluetooth connection * Merge the custom keys enums on annepro2.h (#13) * Keyboard annepro2 ble caps lock (#12) * Move matrix_scan_kb out of board.c to annepro2.c * add buffer clear after init and caplock polling * Add support for LED intensity (#15) * Improve logic for switching off and on of LEDs (#16) * Implement animation speed (#17) * Include logic to send solid colors as foreground to shine and add sample profiles (#14) Include the logic to send a solid color from qmk to shine. That solid color will act as a foreground (will override the current profile) until reset (witch will reactivate the current profile). This functionality depends on changes made for shine as well. Include 3 new profiles: default-full-caps -> same as default, but with the logic of using the red foreground color on caps lock. default-layer-indicators -> same as default, but with the logic of red foreground on caps lock, green foreground on FN1 and blue foreground on FN2. thomazmoura -> my own profile as a sample of an over-engineered advanced case scenario. * Implement reactive lighting effects (#18) * Added multiarrow keymap (#19) * Add LED documentation (#26) * add LED documentation * add LED documentation to other default profiles * Implement QMK's IAP default keybind (#29) * Add keymap for going into IAP * switch to default QMK keybind for IAP mode * implement bluetooth IAP mode * Make default config more like Obins stock default (#30) * Add new message type for resetting foreground color (#31) * annepro2(bluetooth): add media keys support (#41) * Asynchronous, robust serial protocol. (#39) * bla personal ap2-c18 keymap. * Bidirectional, asynchronous message-based communication with Shine. - Requires a matching Shine version. - Protocol is resiliant to loosing bytes during communication, chips won't lock waiting for bytes that aren't coming. - Chips resynchronize in event of loosing a byte using a AA0D header. Regressions: - Key masking/locking doesn't work right now. (did it work before?) - Not all user keymaps build against it. * Clang-format + code to ease reducing speed of LED UART. - Did clang-format --style=file -i on multiple files according to coding_conventions_c.md - Added separate serial speed for IAP boot and Led communication, it's possible that reducing this to 9600 helped someone with faulty HW. With this code they can do it with simple replacing of a value. * Main chip can set/clear foreground using a mask mechanism. - Some preparations for selective colouring. * Selective mask works - tested on capslock. - Migrated personal keymaps to new status API. * Clear the foreground colors to show profile when it's modified. - Show example of achieving selective caps-lock painting + foreground painting for layers. - annepro2LedMaskSetRow is implemented, but still requires testing. * Implement the QMK side of led blinking to indicate the command was received. - This stupidly blinks the key when user presses one of the bluetooth commands to let the user know that the command was received and forwarded to the BT chip. - TODO: Row/col key positions are hardcoded and not taken from the keymap. * Reduce memory footprint. Applying code review suggestions. Moved msgId to globals - preparing for transmission without copying payload when no retries are necessary. Added empty readme.md files - required by QMK lint. Co-authored-by: Tomasz bla Fortuna <bla@thera.be> * Let the LED chip settle a bit before waking it from the bootloader. (#42) At least for one person that helps to reliably get the LEDs working without disconnecting/reconnecting the power to the board multiple times. Co-authored-by: Tomasz bla Fortuna <bla@thera.be> * annepro2: rename KEYMAP to LAYOUT, as required by new version of QMK * annepro2: update ChibiOS configuration files * annepro2: fix undefined reference to dprint and timer_read32 * annepro2: update ChibiOS MCU name * update spi driver, fix bad merging with master * annepro2: add readme and info.json * annepro2: make code compatible with QMK coding conventions * tmk_core: temporary fix to allow HT32 based keyboards to work without patched ChibiOS-contrib (AnnePro2) * AnnePro2: removed core changes * AnnePro2: Leave only default keymaps Missing keymaps will be restored in another PR * annepro2: add licence information * annepro2: satisfy qmk lint * annepro2: fix drashna's suggestions * annepro2: fix matrix * annepro2: apply code review suggestions * annepro2: apply remaining code review suggestions * annepro2: update info.json * annepro2: remove include * annepro2: rename keymap to layout * annepro2: fix typing * annepro2: apply suggestions from tzarc's code review Co-authored-by: Nick Brassel <nick@tzarc.org> * annepro2: more fixes * annepro2: apply suggestions from code review Co-authored-by: Joel Challis <git@zvecr.com> * annepro2: rename file * more fixes * Apply suggestions from @tzarc code review Co-authored-by: Nick Brassel <nick@tzarc.org> * Update keyboards/annepro2/protocol.h Co-authored-by: Nick Brassel <nick@tzarc.org> * Update keyboards/annepro2/chconf.h Co-authored-by: Nick Brassel <nick@tzarc.org> * apply CR suggestions * upgrade readme * IAP * update IAP comments, defines * led fix * init fix * annepro2: GPIO cleanup * annepro2: ioline * change waiting time * Start develop for 2022q2 * [Core] Squeeze AVR some more with `-mrelax` and `-mcall-prologues` (#16269) * Rework generate-api CLI command to use .build directory (#16441) * Remove `send_unicode_hex_string()` (#16518) * Change data driven "str" type to represent a quoted string literal (#16516) * Change data driven "str" type to represent a quoted string literal * Update docs * Map data driven `DESCRIPTION` as string literal (#16523) * update bootloader * Revert "Merge pull request #2 from qmk/develop" This reverts commit 9c76065188c3adda98bdaa1f28dad85600e73ee9, reversing changes made to 240745dc05783c612e92bab153da5c46e037d675. * Revert "update bootloader" This reverts commit 240745dc05783c612e92bab153da5c46e037d675. * fix rules.mk * change PROGRAM_CMD Co-authored-by: codetector <codetector@codetector.cn> Co-authored-by: Fagl4 <18francisco18@gmail.com> Co-authored-by: Jakob Gillich <jakob@gillich.me> Co-authored-by: tech2077 <tech2077@gmail.com> Co-authored-by: jcdeA <31413538+JcdeA@users.noreply.github.com> Co-authored-by: Thomaz Moura <5599621+thomazmoura@users.noreply.github.com> Co-authored-by: Darkhan <darkhanu@gmail.com> Co-authored-by: Paco <70448173+packorf@users.noreply.github.com> Co-authored-by: jmarmstrong1207 <32995055+jmarmstrong1207@users.noreply.github.com> Co-authored-by: 1Conan <7620342+1Conan@users.noreply.github.com> Co-authored-by: Tomasz bla Fortuna <blagh@thera.be> Co-authored-by: Tomasz bla Fortuna <bla@thera.be> Co-authored-by: Nick Brassel <nick@tzarc.org> Co-authored-by: Joel Challis <git@zvecr.com> Co-authored-by: QMK Bot <hello@qmk.fm> Co-authored-by: Stefan Kerkmann <karlk90@pm.me> Co-authored-by: Ryan <fauxpark@gmail.com>
-rw-r--r--keyboards/annepro2/annepro2.c202
-rw-r--r--keyboards/annepro2/annepro2.h65
-rw-r--r--keyboards/annepro2/annepro2_ble.c170
-rw-r--r--keyboards/annepro2/annepro2_ble.h27
-rw-r--r--keyboards/annepro2/ap2_led.c134
-rw-r--r--keyboards/annepro2/ap2_led.h84
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C15/board.c103
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C15/board.h39
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C15/board.mk5
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C18/board.c103
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C18/board.h39
-rw-r--r--keyboards/annepro2/boards/ANNEPRO2_C18/board.mk5
-rw-r--r--keyboards/annepro2/c15/config.h47
-rw-r--r--keyboards/annepro2/c15/readme.md1
-rw-r--r--keyboards/annepro2/c15/rules.mk37
-rw-r--r--keyboards/annepro2/c18/config.h45
-rw-r--r--keyboards/annepro2/c18/readme.md1
-rw-r--r--keyboards/annepro2/c18/rules.mk37
-rw-r--r--keyboards/annepro2/chconf.h31
-rw-r--r--keyboards/annepro2/halconf.h28
-rw-r--r--keyboards/annepro2/info.json330
-rw-r--r--keyboards/annepro2/keymaps/default-full-caps/config.h20
-rw-r--r--keyboards/annepro2/keymaps/default-full-caps/keymap.c120
-rw-r--r--keyboards/annepro2/keymaps/default-layer-indicators/config.h20
-rw-r--r--keyboards/annepro2/keymaps/default-layer-indicators/keymap.c147
-rw-r--r--keyboards/annepro2/keymaps/default/config.h20
-rw-r--r--keyboards/annepro2/keymaps/default/keymap.c106
-rw-r--r--keyboards/annepro2/ld/HT32F52342_ANNEPRO2.ld91
-rw-r--r--keyboards/annepro2/matrix.c63
-rw-r--r--keyboards/annepro2/mcuconf.h62
-rw-r--r--keyboards/annepro2/protocol.c116
-rw-r--r--keyboards/annepro2/protocol.h111
-rw-r--r--keyboards/annepro2/readme.md50
33 files changed, 2459 insertions, 0 deletions
diff --git a/keyboards/annepro2/annepro2.c b/keyboards/annepro2/annepro2.c
new file mode 100644
index 0000000000..37489defff
--- /dev/null
+++ b/keyboards/annepro2/annepro2.c
@@ -0,0 +1,202 @@
+/* Copyright 2021 OpenAnnePro community
+ *
+ * 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 "hal.h"
+#include "annepro2.h"
+#include "annepro2_ble.h"
+#include "spi_master.h"
+#include "ap2_led.h"
+#include "protocol.h"
+
+#define RAM_MAGIC_LOCATION 0x20001ffc
+#define IAP_MAGIC_VALUE 0x0000fab2
+
+static const SerialConfig ledUartInitConfig = {
+ .speed = 115200,
+};
+
+#ifndef LED_UART_BAUD_RATE
+# define LED_UART_BAUD_RATE 115200
+#endif // LED_UART_BAUD_RATE
+
+static const SerialConfig ledUartRuntimeConfig = {
+ .speed = LED_UART_BAUD_RATE,
+};
+
+static const SerialConfig bleUartConfig = {
+ .speed = 115200,
+};
+
+static uint8_t ledMcuWakeup[11] = {0x7b, 0x10, 0x43, 0x10, 0x03, 0x00, 0x00, 0x7d, 0x02, 0x01, 0x02};
+
+ble_capslock_t BLECapsLock = {._dummy = {0}, .caps_lock = false};
+
+void bootloader_jump(void) {
+ // Send msg to shine to boot into IAP
+ annepro2SetIAP();
+
+ // wait for shine to boot into IAP
+ wait_ms(15);
+
+ // Load ble into IAP
+ annepro2_ble_bootload();
+ wait_ms(15);
+
+ // Magic key to set keyboard to IAP
+ // It’s from reversing original boot loader
+ // If value is that it stays in boot loader aka IAP
+ *((uint32_t *)RAM_MAGIC_LOCATION) = IAP_MAGIC_VALUE;
+
+ // Load the main MCU into IAP
+ __disable_irq();
+ NVIC_SystemReset();
+}
+
+void keyboard_pre_init_kb(void) {
+ // Start LED UART
+ sdStart(&SD0, &ledUartInitConfig);
+ /* Let the LED chip settle a bit before switching the mode.
+ * That helped at least one person. */
+ wait_ms(15);
+ sdWrite(&SD0, ledMcuWakeup, sizeof(ledMcuWakeup));
+
+ // wait to receive response from wakeup
+ wait_ms(15);
+
+ protoInit(&proto, ledCommandCallback);
+
+ // loop to clear out receive buffer from shine wakeup
+ while (!sdGetWouldBlock(&SD0)) sdGet(&SD0);
+
+ sdStart(&SD0, &ledUartRuntimeConfig);
+ keyboard_pre_init_user();
+}
+
+void keyboard_post_init_kb(void) {
+ // Start BLE UART
+ sdStart(&SD1, &bleUartConfig);
+ annepro2_ble_startup();
+
+ // Give the send uart thread some time to
+ // send out the queue before we read back
+ wait_ms(100);
+
+ // loop to clear out receive buffer from ble wakeup
+ while (!sdGetWouldBlock(&SD1)) sdGet(&SD1);
+
+ annepro2LedGetStatus();
+
+ keyboard_post_init_user();
+}
+
+void matrix_scan_kb() {
+ // if there's stuff on the ble serial buffer
+ // read it into the capslock struct
+ while (!sdGetWouldBlock(&SD1)) {
+ sdReadTimeout(&SD1, (uint8_t *)&BLECapsLock, sizeof(ble_capslock_t), 10);
+ }
+
+ /* While there's data from LED keyboard sent - read it. */
+ while (!sdGetWouldBlock(&SD0)) {
+ uint8_t byte = sdGet(&SD0);
+ protoConsume(&proto, byte);
+ }
+
+ matrix_scan_user();
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ if (record->event.pressed) {
+ if (annepro2LedStatus.matrixEnabled && annepro2LedStatus.isReactive) {
+ annepro2LedForwardKeypress(record->event.key.row, record->event.key.col);
+ }
+
+ const annepro2Led_t blue = {
+ .p.blue = 0xff,
+ .p.red = 0x00,
+ .p.green = 0x00,
+ .p.alpha = 0xff,
+ };
+
+ switch (keycode) {
+ case KC_AP2_BT1:
+ annepro2_ble_broadcast(0);
+ /* FIXME: This hardcodes col/row position */
+ annepro2LedBlink(0, 1, blue, 8, 50);
+ return false;
+
+ case KC_AP2_BT2:
+ annepro2_ble_broadcast(1);
+ annepro2LedBlink(0, 2, blue, 8, 50);
+ return false;
+
+ case KC_AP2_BT3:
+ annepro2_ble_broadcast(2);
+ annepro2LedBlink(0, 3, blue, 8, 50);
+ return false;
+
+ case KC_AP2_BT4:
+ annepro2_ble_broadcast(3);
+ annepro2LedBlink(0, 4, blue, 8, 50);
+ return false;
+
+ case KC_AP2_USB:
+ annepro2_ble_disconnect();
+ return false;
+
+ case KC_AP2_BT_UNPAIR:
+ annepro2_ble_unpair();
+ return false;
+
+ case KC_AP_LED_OFF:
+ annepro2LedDisable();
+ break;
+
+ case KC_AP_LED_ON:
+ if (annepro2LedStatus.matrixEnabled) {
+ annepro2LedNextProfile();
+ } else {
+ annepro2LedEnable();
+ }
+ annepro2LedResetForegroundColor();
+ break;
+
+ case KC_AP_LED_NEXT_PROFILE:
+ annepro2LedNextProfile();
+ annepro2LedResetForegroundColor();
+ break;
+
+ case KC_AP_LED_PREV_PROFILE:
+ annepro2LedPrevProfile();
+ annepro2LedResetForegroundColor();
+ break;
+
+ case KC_AP_LED_NEXT_INTENSITY:
+ annepro2LedNextIntensity();
+ annepro2LedResetForegroundColor();
+ return false;
+
+ case KC_AP_LED_SPEED:
+ annepro2LedNextAnimationSpeed();
+ annepro2LedResetForegroundColor();
+ return false;
+
+ default:
+ break;
+ }
+ }
+ return process_record_user(keycode, record);
+}
diff --git a/keyboards/annepro2/annepro2.h b/keyboards/annepro2/annepro2.h
new file mode 100644
index 0000000000..b08f8c5352
--- /dev/null
+++ b/keyboards/annepro2/annepro2.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 Yaotian Feng
+ *
+ * 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 "quantum.h"
+#include <stdint.h>
+#include "ap2_led.h"
+
+typedef struct __attribute__((__packed__)) {
+ uint8_t _dummy[10];
+ bool caps_lock;
+} ble_capslock_t;
+extern ble_capslock_t BLECapsLock;
+
+// Matrix keymap
+// clang-format off
+#define LAYOUT( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
+ K40, K42, K43, K46, K49, K4A, K4B, K4C \
+) { \
+ /* COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9 COL10 COL11 COL12 COL13 COL14*/ \
+ /* ROW1 */ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ /* ROW2 */ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ /* ROW3 */ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KC_NO}, \
+ /* ROW4 */ { K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KC_NO}, \
+ /* ROW5 */ { K40, KC_NO, K42, K43, KC_NO, KC_NO, K46, KC_NO, KC_NO, K49, K4A, K4B, K4C, KC_NO}, \
+}
+// clang-format on
+
+enum AP2KeyCodes {
+ KC_AP2_BT1 = SAFE_RANGE,
+ KC_AP2_BT2,
+ KC_AP2_BT3,
+ KC_AP2_BT4,
+ KC_AP2_BT_UNPAIR,
+ KC_AP2_USB,
+ KC_AP_LED_ON,
+ KC_AP_LED_OFF,
+ KC_AP_LED_NEXT_PROFILE,
+ KC_AP_LED_PREV_PROFILE,
+ KC_AP_LED_NEXT_INTENSITY,
+ KC_AP_LED_SPEED,
+ AP2_SAFE_RANGE,
+};
+
+#undef SAFE_RANGE
+#define SAFE_RANGE AP2_SAFE_RANGE
+
diff --git a/keyboards/annepro2/annepro2_ble.c b/keyboards/annepro2/annepro2_ble.c
new file mode 100644
index 0000000000..72cbb68016
--- /dev/null
+++ b/keyboards/annepro2/annepro2_ble.c
@@ -0,0 +1,170 @@
+/*
+ Copyright (C) 2020 Yaotian Feng, Codetector<codetector@codetector.cn>
+
+ 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.
+*/
+
+#include "annepro2_ble.h"
+#include "ch.h"
+#include "hal.h"
+#include "host.h"
+#include "host_driver.h"
+#include "report.h"
+
+/* -------------------- Static Function Prototypes -------------------------- */
+static uint8_t ap2_ble_leds(void);
+static void ap2_ble_mouse(report_mouse_t *report);
+static void ap2_ble_system(uint16_t data);
+static void ap2_ble_consumer(uint16_t data);
+static void ap2_ble_keyboard(report_keyboard_t *report);
+
+static void ap2_ble_swtich_ble_driver(void);
+
+/* -------------------- Static Local Variables ------------------------------ */
+static host_driver_t ap2_ble_driver = {
+ ap2_ble_leds, ap2_ble_keyboard, ap2_ble_mouse, ap2_ble_system, ap2_ble_consumer,
+};
+
+static uint8_t bleMcuWakeup[11] = {0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x01, 0x7d, 0x02, 0x01, 0x02};
+
+static uint8_t bleMcuStartBroadcast[11] = {
+ 0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x00, 0x7d, 0x40, 0x01, 0x00 // Broadcast ID[0-3]
+};
+
+static uint8_t bleMcuConnect[11] = {
+ 0x7b, 0x12, 0x53, 0x00, 0x03, 0x00, 0x00, 0x7d, 0x40, 0x04, 0x00 // Connect ID [0-3]
+};
+
+static uint8_t bleMcuSendReport[10] = {
+ 0x7b, 0x12, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x7d, 0x10, 0x04,
+};
+
+static uint8_t bleMcuSendConsumerReport[10] = {
+ 0x7b, 0x12, 0x53, 0x00, 0x06, 0x00, 0x00, 0x7d, 0x10, 0x08,
+};
+
+static uint8_t bleMcuUnpair[10] = {
+ 0x7b, 0x12, 0x53, 0x00, 0x02, 0x00, 0x00, 0x7d, 0x40, 0x05,
+};
+
+static uint8_t bleMcuBootload[11] = {0x7b, 0x10, 0x51, 0x10, 0x03, 0x00, 0x00, 0x7d, 0x02, 0x01, 0x01};
+
+static host_driver_t *lastHostDriver = NULL;
+#ifdef NKRO_ENABLE
+static bool lastNkroStatus = false;
+#endif // NKRO_ENABLE
+
+/* -------------------- Public Function Implementation ---------------------- */
+
+void annepro2_ble_bootload(void) { sdWrite(&SD1, bleMcuBootload, sizeof(bleMcuBootload)); }
+
+void annepro2_ble_startup(void) { sdWrite(&SD1, bleMcuWakeup, sizeof(bleMcuWakeup)); }
+
+void annepro2_ble_broadcast(uint8_t port) {
+ if (port > 3) {
+ port = 3;
+ }
+ // sdPut(&SD1, 0x00);
+ sdWrite(&SD1, bleMcuStartBroadcast, sizeof(bleMcuStartBroadcast));
+ sdPut(&SD1, port);
+ static int lastBroadcast = -1;
+ if (lastBroadcast == port) {
+ annepro2_ble_connect(port);
+ }
+ lastBroadcast = port;
+}
+
+void annepro2_ble_connect(uint8_t port) {
+ if (port > 3) {
+ port = 3;
+ }
+ sdWrite(&SD1, bleMcuConnect, sizeof(bleMcuConnect));
+ sdPut(&SD1, port);
+ ap2_ble_swtich_ble_driver();
+}
+
+void annepro2_ble_disconnect(void) {
+ /* Skip if the driver is already enabled */
+ if (host_get_driver() != &ap2_ble_driver) {
+ return;
+ }
+
+ clear_keyboard();
+#ifdef NKRO_ENABLE
+ keymap_config.nkro = lastNkroStatus;
+#endif
+ host_set_driver(lastHostDriver);
+}
+
+void annepro2_ble_unpair(void) {
+ // sdPut(&SD1, 0x0);
+ sdWrite(&SD1, bleMcuUnpair, sizeof(bleMcuUnpair));
+}
+
+/* ------------------- Static Function Implementation ----------------------- */
+static void ap2_ble_swtich_ble_driver(void) {
+ if (host_get_driver() == &ap2_ble_driver) {
+ return;
+ }
+ clear_keyboard();
+ lastHostDriver = host_get_driver();
+#ifdef NKRO_ENABLE
+ lastNkroStatus = keymap_config.nkro;
+#endif
+ keymap_config.nkro = false;
+ host_set_driver(&ap2_ble_driver);
+}
+
+static uint8_t ap2_ble_leds(void) {
+ return 0; // TODO: Figure out how to obtain LED status
+}
+
+static void ap2_ble_mouse(report_mouse_t *report) {}
+
+static void ap2_ble_system(uint16_t data) {}
+
+static inline uint16_t CONSUMER2AP2(uint16_t usage) {
+ switch (usage) {
+ case AUDIO_VOL_DOWN:
+ return 0x04;
+ case AUDIO_VOL_UP:
+ return 0x02;
+ case AUDIO_MUTE:
+ return 0x01;
+ case TRANSPORT_PLAY_PAUSE:
+ return 0x08;
+ case TRANSPORT_NEXT_TRACK:
+ return 0x10;
+ case TRANSPORT_PREV_TRACK:
+ return 0x20;
+ default:
+ return 0x00;
+ }
+}
+
+static void ap2_ble_consumer(uint16_t data) {
+ sdPut(&SD1, 0x0);
+ sdWrite(&SD1, bleMcuSendConsumerReport, sizeof(bleMcuSendConsumerReport));
+ sdPut(&SD1, CONSUMER2AP2(data));
+ static const uint8_t dummy[3] = {0};
+ sdWrite(&SD1, dummy, sizeof(dummy));
+}
+
+/*!
+ * @brief Send keyboard HID report for Bluetooth driver
+ */
+static void ap2_ble_keyboard(report_keyboard_t *report) {
+ sdPut(&SD1, 0x0);
+ sdWrite(&SD1, bleMcuSendReport, sizeof(bleMcuSendReport));
+ sdWrite(&SD1, &report->raw[0], KEYBOARD_REPORT_SIZE);
+}
diff --git a/keyboards/annepro2/annepro2_ble.h b/keyboards/annepro2/annepro2_ble.h
new file mode 100644
index 0000000000..0cfb68e071
--- /dev/null
+++ b/keyboards/annepro2/annepro2_ble.h
@@ -0,0 +1,27 @@
+/*
+ Copyright (C) 2020 Yaotian Feng, Codetector<codetector@codetector.cn>
+
+ 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
+
+#include "annepro2.h"
+#include "quantum.h"
+
+void annepro2_ble_bootload(void);
+void annepro2_ble_startup(void);
+void annepro2_ble_broadcast(uint8_t port);
+void annepro2_ble_connect(uint8_t port);
+void annepro2_ble_disconnect(void);
+void annepro2_ble_unpair(void);
diff --git a/keyboards/annepro2/ap2_led.c b/keyboards/annepro2/ap2_led.c
new file mode 100644
index 0000000000..9969fcd02a
--- /dev/null
+++ b/keyboards/annepro2/ap2_led.c
@@ -0,0 +1,134 @@
+/* Copyright 2021 OpenAnnePro community
+ *
+ * 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 <string.h>
+#include <stdio.h>
+#include "hal.h"
+#include "annepro2.h"
+#include "ap2_led.h"
+#include "protocol.h"
+
+annepro2Led_t ledMask[KEY_COUNT];
+annepro2LedStatus_t annepro2LedStatus;
+
+void ledCommandCallback(const message_t *msg) {
+ switch (msg->command) {
+ case CMD_LED_STATUS:
+ annepro2LedStatus.amountOfProfiles = msg->payload[0];
+ annepro2LedStatus.currentProfile = msg->payload[1];
+ annepro2LedStatus.matrixEnabled = msg->payload[2];
+ annepro2LedStatus.isReactive = msg->payload[3];
+ annepro2LedStatus.ledIntensity = msg->payload[4];
+ annepro2LedStatus.errors = msg->payload[5];
+ break;
+
+#ifdef CONSOLE_ENABLE
+ case CMD_LED_DEBUG:
+ /* TODO: Don't use printf. */
+ printf("LED:");
+ for (int i = 0; i < msg->payloadSize; i++) {
+ printf("%02x ", msg->payload[i]);
+ }
+ for (int i = 0; i < msg->payloadSize; i++) {
+ printf("%c", msg->payload[i]);
+ }
+ printf("\n");
+ break;
+#endif
+ }
+}
+
+void annepro2SetIAP(void) { protoTx(CMD_LED_IAP, NULL, 0, 3); }
+
+void annepro2LedDisable(void) { protoTx(CMD_LED_OFF, NULL, 0, 3); }
+
+void annepro2LedEnable(void) { protoTx(CMD_LED_ON, NULL, 0, 3); }
+
+void annepro2LedSetProfile(uint8_t prof) { protoTx(CMD_LED_SET_PROFILE, &prof, sizeof(prof), 3); }
+
+void annepro2LedGetStatus() { protoTx(CMD_LED_GET_STATUS, NULL, 0, 3); }
+
+void annepro2LedNextProfile() { protoTx(CMD_LED_NEXT_PROFILE, NULL, 0, 3); }
+
+void annepro2LedNextIntensity() { protoTx(CMD_LED_NEXT_INTENSITY, NULL, 0, 3); }
+
+void annepro2LedNextAnimationSpeed() { protoTx(CMD_LED_NEXT_ANIMATION_SPEED, NULL, 0, 3); }
+
+void annepro2LedPrevProfile() { protoTx(CMD_LED_PREV_PROFILE, NULL, 0, 3); }
+
+void annepro2LedMaskSetKey(uint8_t row, uint8_t col, annepro2Led_t color) {
+ uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha};
+ protoTx(CMD_LED_MASK_SET_KEY, payload, sizeof(payload), 1);
+}
+
+/* Push a whole local row to the shine */
+void annepro2LedMaskSetRow(uint8_t row) {
+ uint8_t payload[NUM_COLUMN * sizeof(annepro2Led_t) + 1];
+ payload[0] = row;
+ memcpy(payload + 1, &ledMask[ROWCOL2IDX(row, 0)], sizeof(*ledMask) * NUM_COLUMN);
+ protoTx(CMD_LED_MASK_SET_ROW, payload, sizeof(payload), 1);
+}
+
+/* Synchronize all rows */
+void annepro2LedMaskSetAll(void) {
+ for (int row = 0; row < 5; row++) annepro2LedMaskSetRow(row);
+}
+
+/* Set all keys to a given color */
+void annepro2LedMaskSetMono(const annepro2Led_t color) { protoTx(CMD_LED_MASK_SET_MONO, (uint8_t *)&color, sizeof(color), 1); }
+
+void annepro2LedBlink(uint8_t row, uint8_t col, annepro2Led_t color, uint8_t count, uint8_t hundredths) {
+ uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha, count, hundredths};
+ protoTx(CMD_LED_KEY_BLINK, payload, sizeof(payload), 1);
+}
+
+void annepro2LedSetForegroundColor(uint8_t red, uint8_t green, uint8_t blue) {
+ annepro2Led_t color = {.p.red = red, .p.green = green, .p.blue = blue, .p.alpha = 0xff};
+ annepro2LedMaskSetMono(color);
+}
+
+void annepro2LedResetForegroundColor() {
+ annepro2Led_t color = {
+ .p.red = 0,
+ .p.green = 0,
+ .p.blue = 0,
+ .p.alpha = 0,
+ };
+ annepro2LedMaskSetMono(color);
+}
+
+/*
+ * Currently keypresses are unified with other messages, still with single 1
+ * byte payload. Transfer is normally fast enough for that to not be a problem -
+ * especially with asynchronous message reading.
+ *
+ *
+ * Previous description:
+ * If enabled, this data is sent to LED MCU on every keypress.
+ * In order to improve performance, both row and column values
+ * are packed into a single byte.
+ * Row range is [0, 4] and requires only 3 bits.
+ * Column range is [0, 13] and requires 4 bits.
+ *
+ * In order to differentiate this command from regular commands,
+ * the leftmost bit is set to 1 (0b10000000).
+ * Following it are 3 bits of row and 4 bits of col.
+ * 1 + 3 + 4 = 8 bits - only a single byte is sent for every keypress.
+ */
+void annepro2LedForwardKeypress(uint8_t row, uint8_t col) {
+ const uint8_t payload = row << 4 | col;
+ protoTx(CMD_LED_KEY_DOWN, &payload, 1, 1);
+}
diff --git a/keyboards/annepro2/ap2_led.h b/keyboards/annepro2/ap2_led.h
new file mode 100644
index 0000000000..23712a2555
--- /dev/null
+++ b/keyboards/annepro2/ap2_led.h
@@ -0,0 +1,84 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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 "protocol.h"
+
+// Struct defining an LED and its RGB color components
+// Compatible with Shine firmware.
+typedef union {
+ struct {
+ /* Little endian ordering to match uint32_t */
+ uint8_t blue, green, red;
+ /* Used in mask; nonzero means - use color from mask. */
+ uint8_t alpha;
+ } p; /* parts */
+ /* Parts vector access: 0 - blue, 1 - green, 2 - red */
+ uint8_t pv[4];
+ /* 0xrgb in mem is b g r a */
+ uint32_t rgb;
+} annepro2Led_t;
+
+#define ROWCOL2IDX(row, col) (NUM_COLUMN * (row) + (col))
+#define NUM_COLUMN 14
+#define NUM_ROW 5
+#define KEY_COUNT 70
+
+/* Local copy of ledMask, used to override colors on the board */
+extern annepro2Led_t ledMask[KEY_COUNT];
+
+/* Handle incoming messages */
+extern void ledCommandCallback(const message_t *msg);
+
+void annepro2SetIAP(void);
+void annepro2LedDisable(void);
+void annepro2LedEnable(void);
+void annepro2LedSetProfile(uint8_t prof);
+void annepro2LedGetStatus(void);
+void annepro2LedNextProfile(void);
+void annepro2LedPrevProfile(void);
+void annepro2LedNextIntensity(void);
+void annepro2LedNextAnimationSpeed(void);
+void annepro2LedForwardKeypress(uint8_t row, uint8_t col);
+
+/* Set single key to a given color; alpha controls which is displayed */
+void annepro2LedMaskSetKey(uint8_t row, uint8_t col, annepro2Led_t color);
+/* Push a whole local row to the shine */
+void annepro2LedMaskSetRow(uint8_t row);
+/* Synchronize all rows */
+void annepro2LedMaskSetAll(void);
+
+/* Set all keys to a given color */
+void annepro2LedMaskSetMono(annepro2Led_t color);
+
+/* Blink given key `count` times by masking it with a `color`. Blink takes `hundredths` of a second */
+void annepro2LedBlink(uint8_t row, uint8_t col, annepro2Led_t color, uint8_t count, uint8_t hundredths);
+
+/* Kept for compatibility, but implemented using masks */
+void annepro2LedSetForegroundColor(uint8_t red, uint8_t green, uint8_t blue);
+void annepro2LedResetForegroundColor(void);
+
+typedef struct {
+ uint8_t amountOfProfiles;
+ uint8_t currentProfile;
+ uint8_t matrixEnabled;
+ uint8_t isReactive;
+ uint8_t ledIntensity;
+ uint8_t errors;
+} annepro2LedStatus_t;
+
+extern annepro2LedStatus_t annepro2LedStatus;
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C15/board.c b/keyboards/annepro2/boards/ANNEPRO2_C15/board.c
new file mode 100644
index 0000000000..60c1826155
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C15/board.c
@@ -0,0 +1,103 @@
+/*
+ Copyright (C) 2020 Yaotian Feng, Codetector<codetector@codetector.cn>
+
+ 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.
+*/
+
+#include "hal.h"
+
+/* ============ Private Defines ===================== */
+
+/* ============ Function Prototypes ================== */
+
+#define PBIT(PORT, LINE) ((PAL_PORT(LINE) == PORT) ? (1 << PAL_PAD(LINE)) : 0)
+#define PAFIO_L(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) < 8)) ? (AF << (PAL_PAD(LINE) << 2)) : 0)
+#define PAFIO_H(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) >= 8)) ? (AF << ((PAL_PAD(LINE) - 8) << 2)) : 0)
+#define PAFIO(PORT, N, LINE, AF) ((N) ? PAFIO_H(PORT, LINE, AF) : PAFIO_L(PORT, LINE, AF))
+
+#define OUT_BITS(PORT) (PBIT(PORT, C2) | PBIT(PORT, C1) | PBIT(PORT, B5) | PBIT(PORT, B4) | PBIT(PORT, C3) | 0)
+
+#define IN_BITS(PORT) (PBIT(PORT, C4) | PBIT(PORT, C5) | PBIT(PORT, B10) | PBIT(PORT, B11) | PBIT(PORT, C0) | PBIT(PORT, A15) | PBIT(PORT, A8) | PBIT(PORT, A10) | PBIT(PORT, A11) | PBIT(PORT, A12) | PBIT(PORT, A13) | PBIT(PORT, A14) | PBIT(PORT, B2) | PBIT(PORT, B3) | 0)
+
+// Alternate Functions
+#define AF_BITS(PORT, N) (PAFIO(PORT, N, LINE_UART_RX, AFIO_USART) | PAFIO(PORT, N, LINE_UART_TX, AFIO_USART) | PAFIO(PORT, N, LINE_BT_UART_TX, AFIO_USART) | PAFIO(PORT, N, LINE_BT_UART_RX, AFIO_USART) | PAFIO(PORT, N, C2, AFIO_GPIO) | PAFIO(PORT, N, C1, AFIO_GPIO) | PAFIO(PORT, N, B5, AFIO_GPIO) | PAFIO(PORT, N, B4, AFIO_GPIO) | PAFIO(PORT, N, C3, AFIO_GPIO) | PAFIO(PORT, N, C4, AFIO_GPIO) | PAFIO(PORT, N, C5, AFIO_GPIO) | PAFIO(PORT, N, B10, AFIO_GPIO) | PAFIO(PORT, N, B11, AFIO_GPIO) | PAFIO(PORT, N, C0, AFIO_GPIO) | PAFIO(PORT, N, A15, AFIO_GPIO) | PAFIO(PORT, N, A8, AFIO_GPIO) | PAFIO(PORT, N, A10, AFIO_GPIO) | PAFIO(PORT, N, A11, AFIO_GPIO) | PAFIO(PORT, N, A12, AFIO_GPIO) | PAFIO(PORT, N, A13, AFIO_GPIO) | PAFIO(PORT, N, A14, AFIO_GPIO) | PAFIO(PORT, N, B2, AFIO_GPIO) | PAFIO(PORT, N, B3, AFIO_GPIO) | 0)
+
+/**
+ * @brief PAL setup.
+ * @details Digital I/O ports static configuration as defined in @p board.h.
+ * This variable is used by the HAL when initializing the PAL driver.
+ */
+const PALConfig pal_default_config = {
+ // GPIO A
+ .setup[0] =
+ {
+ .DIR = OUT_BITS(IOPORTA),
+ .INE = IN_BITS(IOPORTA),
+ .PU = IN_BITS(IOPORTA),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTA, 0),
+ .CFG[1] = AF_BITS(IOPORTA, 1),
+ },
+ // GPIO B
+ .setup[1] =
+ {
+ .DIR = OUT_BITS(IOPORTB),
+ .INE = IN_BITS(IOPORTB),
+ .PU = IN_BITS(IOPORTB),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTB, 0),
+ .CFG[1] = AF_BITS(IOPORTB, 1),
+ },
+ // GPIO C
+ .setup[2] =
+ {
+ .DIR = OUT_BITS(IOPORTC),
+ .INE = IN_BITS(IOPORTC),
+ .PU = IN_BITS(IOPORTC),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTC, 0),
+ .CFG[1] = AF_BITS(IOPORTC, 1),
+ },
+ // GPIO D
+ .setup[3] =
+ {
+ .DIR = OUT_BITS(IOPORTD),
+ .INE = IN_BITS(IOPORTD),
+ .PU = IN_BITS(IOPORTD),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTD, 0),
+ .CFG[1] = AF_BITS(IOPORTD, 1),
+ },
+ .ESSR[0] = 0x00000000,
+ .ESSR[1] = 0x00000000,
+};
+
+void __early_init(void) { ht32_clock_init(); }
+
+void boardInit(void) {}
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C15/board.h b/keyboards/annepro2/boards/ANNEPRO2_C15/board.h
new file mode 100644
index 0000000000..0a044ea181
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C15/board.h
@@ -0,0 +1,39 @@
+/*
+ ChibiOS - Copyright (C) 2020 Codetector <codetector@codetector.cn>
+
+ 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
+/*
+ * Setup for Anne Pro 2 board.
+ */
+
+/*
+ * Board identifier.
+ */
+#define BOARD_NAME "Anne Pro 2"
+
+#define HT32F52342
+
+#define FLASH_SIZE (0x10000 - 0x4000) // 64kB - 16kB
+
+#if !defined(_FROM_ASM_)
+#ifdef __cplusplus
+extern "C" {
+#endif
+void boardInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _FROM_ASM_ */ \ No newline at end of file
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C15/board.mk b/keyboards/annepro2/boards/ANNEPRO2_C15/board.mk
new file mode 100644
index 0000000000..f308892e7c
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C15/board.mk
@@ -0,0 +1,5 @@
+# List of all the board related files.
+BOARDSRC = $(BOARD_PATH)/boards/ANNEPRO2_C15/board.c
+
+# Required include directories
+BOARDINC = $(BOARD_PATH)/boards/ANNEPRO2_C15
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C18/board.c b/keyboards/annepro2/boards/ANNEPRO2_C18/board.c
new file mode 100644
index 0000000000..42c03d3d00
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C18/board.c
@@ -0,0 +1,103 @@
+/*
+ Copyright (C) 2020 Yaotian Feng, Codetector<codetector@codetector.cn>
+
+ 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.
+*/
+
+#include "hal.h"
+
+/* ============ Private Defines ===================== */
+
+/* ============ Function Prototypes ================== */
+
+#define PBIT(PORT, LINE) ((PAL_PORT(LINE) == PORT) ? (1 << PAL_PAD(LINE)) : 0)
+#define PAFIO_L(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) < 8)) ? (AF << (PAL_PAD(LINE) << 2)) : 0)
+#define PAFIO_H(PORT, LINE, AF) (((PAL_PORT(LINE) == PORT) && (PAL_PAD(LINE) >= 8)) ? (AF << ((PAL_PAD(LINE) - 8) << 2)) : 0)
+#define PAFIO(PORT, N, LINE, AF) ((N) ? PAFIO_H(PORT, LINE, AF) : PAFIO_L(PORT, LINE, AF))
+
+#define OUT_BITS(PORT) (PBIT(PORT, B5) | PBIT(PORT, B4) | PBIT(PORT, B3) | PBIT(PORT, B2) | PBIT(PORT, D1) | 0)
+
+#define IN_BITS(PORT) (PBIT(PORT, C4) | PBIT(PORT, C5) | PBIT(PORT, D0) | PBIT(PORT, B15) | PBIT(PORT, C11) | PBIT(PORT, A15) | PBIT(PORT, C12) | PBIT(PORT, C13) | PBIT(PORT, A8) | PBIT(PORT, A10) | PBIT(PORT, A11) | PBIT(PORT, A14) | PBIT(PORT, D2) | PBIT(PORT, D3) | 0)
+
+// Alternate Functions
+#define AF_BITS(PORT, N) (PAFIO(PORT, N, LINE_UART_RX, AFIO_USART) | PAFIO(PORT, N, LINE_UART_TX, AFIO_USART) | PAFIO(PORT, N, LINE_BT_UART_TX, AFIO_USART) | PAFIO(PORT, N, LINE_BT_UART_RX, AFIO_USART) | PAFIO(PORT, N, B5, AFIO_GPIO) | PAFIO(PORT, N, B4, AFIO_GPIO) | PAFIO(PORT, N, B3, AFIO_GPIO) | PAFIO(PORT, N, B2, AFIO_GPIO) | PAFIO(PORT, N, D1, AFIO_GPIO) | PAFIO(PORT, N, C4, AFIO_GPIO) | PAFIO(PORT, N, C5, AFIO_GPIO) | PAFIO(PORT, N, D0, AFIO_GPIO) | PAFIO(PORT, N, B15, AFIO_GPIO) | PAFIO(PORT, N, C11, AFIO_GPIO) | PAFIO(PORT, N, A15, AFIO_GPIO) | PAFIO(PORT, N, C12, AFIO_GPIO) | PAFIO(PORT, N, C13, AFIO_GPIO) | PAFIO(PORT, N, A8, AFIO_GPIO) | PAFIO(PORT, N, A10, AFIO_GPIO) | PAFIO(PORT, N, A11, AFIO_GPIO) | PAFIO(PORT, N, A14, AFIO_GPIO) | PAFIO(PORT, N, D2, AFIO_GPIO) | PAFIO(PORT, N, D3, AFIO_GPIO) | 0)
+
+/**
+ * @brief PAL setup.
+ * @details Digital I/O ports static configuration as defined in @p board.h.
+ * This variable is used by the HAL when initializing the PAL driver.
+ */
+const PALConfig pal_default_config = {
+ // GPIO A
+ .setup[0] =
+ {
+ .DIR = OUT_BITS(IOPORTA),
+ .INE = IN_BITS(IOPORTA),
+ .PU = IN_BITS(IOPORTA),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTA, 0),
+ .CFG[1] = AF_BITS(IOPORTA, 1),
+ },
+ // GPIO B
+ .setup[1] =
+ {
+ .DIR = OUT_BITS(IOPORTB),
+ .INE = IN_BITS(IOPORTB),
+ .PU = IN_BITS(IOPORTB),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTB, 0),
+ .CFG[1] = AF_BITS(IOPORTB, 1),
+ },
+ // GPIO C
+ .setup[2] =
+ {
+ .DIR = OUT_BITS(IOPORTC),
+ .INE = IN_BITS(IOPORTC),
+ .PU = IN_BITS(IOPORTC),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTC, 0),
+ .CFG[1] = AF_BITS(IOPORTC, 1),
+ },
+ // GPIO D
+ .setup[3] =
+ {
+ .DIR = OUT_BITS(IOPORTD),
+ .INE = IN_BITS(IOPORTD),
+ .PU = IN_BITS(IOPORTD),
+ .PD = 0x0000,
+ .OD = 0x0000,
+ .DRV = 0x0000,
+ .LOCK = 0x0000,
+ .OUT = 0x0000,
+ .CFG[0] = AF_BITS(IOPORTD, 0),
+ .CFG[1] = AF_BITS(IOPORTD, 1),
+ },
+ .ESSR[0] = 0x00000000,
+ .ESSR[1] = 0x00000000,
+};
+
+void __early_init(void) { ht32_clock_init(); }
+
+void boardInit(void) {}
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C18/board.h b/keyboards/annepro2/boards/ANNEPRO2_C18/board.h
new file mode 100644
index 0000000000..7345b24231
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C18/board.h
@@ -0,0 +1,39 @@
+/*
+ ChibiOS - Copyright (C) 2020 Codetector <codetector@codetector.cn>
+
+ 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
+/*
+ * Setup for Anne Pro 2 board.
+ */
+
+/*
+ * Board identifier.
+ */
+#define BOARD_NAME "Anne Pro 2"
+
+#define HT32F52342
+
+#define FLASH_SIZE (0x10000 - 0x4000) // 64kB - 16kB
+
+#if !defined(_FROM_ASM_)
+#ifdef __cplusplus
+extern "C" {
+#endif
+void boardInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _FROM_ASM_ */
diff --git a/keyboards/annepro2/boards/ANNEPRO2_C18/board.mk b/keyboards/annepro2/boards/ANNEPRO2_C18/board.mk
new file mode 100644
index 0000000000..1b41dede85
--- /dev/null
+++ b/keyboards/annepro2/boards/ANNEPRO2_C18/board.mk
@@ -0,0 +1,5 @@
+# List of all the board related files.
+BOARDSRC = $(BOARD_PATH)/boards/ANNEPRO2_C18/board.c
+
+# Required include directories
+BOARDINC = $(BOARD_PATH)/boards/ANNEPRO2_C18
diff --git a/keyboards/annepro2/c15/config.h b/keyboards/annepro2/c15/config.h
new file mode 100644
index 0000000000..f28a6a1b53
--- /dev/null
+++ b/keyboards/annepro2/c15/config.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 Charlie Waters
+ *
+ * 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 "pin_defs.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xfeed
+#define PRODUCT_ID 0xac15
+#define DEVICE_VER 0x1337
+#define MANUFACTURER Obins
+#define PRODUCT Anne Pro 2 QMK
+// key matrix size
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+// layer size: MATRIX_ROWS * MATRIX_COLS * sizeof(uint16_t) = 140 bytes
+
+#define LINE_UART_TX B0 // Master TX, LED RX
+#define LINE_UART_RX B1 // Master RX, LED TX
+
+#define LINE_BT_UART_TX A4 // Master TX, BLE RX
+#define LINE_BT_UART_RX A5 // Master RX, BLE TX
+
+// outputs (rows are pulled low)
+#define MATRIX_ROW_PINS \
+ { C2, C1, B5, B4, C3 }
+
+// inputs (columns are sampled)
+// PORTA 12,13 conflict with SWD
+
+#define MATRIX_COL_PINS \
+ { C4, C5, B10, B11, C0, A15, A8, A10, A11, A12, A13, A14, B2, B3 }
diff --git a/keyboards/annepro2/c15/readme.md b/keyboards/annepro2/c15/readme.md
new file mode 100644
index 0000000000..5fadb73909
--- /dev/null
+++ b/keyboards/annepro2/c15/readme.md
@@ -0,0 +1 @@
+AnnePro2, ANSI C15 version.
diff --git a/keyboards/annepro2/c15/rules.mk b/keyboards/annepro2/c15/rules.mk
new file mode 100644
index 0000000000..554ddc28ce
--- /dev/null
+++ b/keyboards/annepro2/c15/rules.mk
@@ -0,0 +1,37 @@
+# Anne Pro 2
+SRC = \
+ matrix.c \
+ annepro2_ble.c \
+ ap2_led.c \
+ protocol.c
+
+# MCU
+MCU = cortex-m0plus
+ARMV = 6
+USE_FPU = no
+MCU_FAMILY = HT32
+MCU_SERIES = HT32F523xx
+MCU_LDSCRIPT = HT32F52342_ANNEPRO2
+MCU_STARTUP = ht32f523xx
+
+BOARD = ANNEPRO2_C15
+
+# Options
+
+# Keys
+CUSTOM_MATRIX = lite
+NKRO_ENABLE = no
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = yes
+KEY_LOCK_ENABLE = no
+
+# Other featues
+BOOTMAGIC_ENABLE = no
+CONSOLE_ENABLE = no
+COMMAND_ENABLE = no
+RAW_ENABLE = no
+MIDI_ENABLE = no
+VIRTSER_ENABLE = no
+COMBO_ENABLE = no
+BOOTLOADER = custom
+PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin
diff --git a/keyboards/annepro2/c18/config.h b/keyboards/annepro2/c18/config.h
new file mode 100644
index 0000000000..f610ef76e4
--- /dev/null
+++ b/keyboards/annepro2/c18/config.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 Charlie Waters
+ *
+ * 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 "pin_defs.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xfeed
+#define PRODUCT_ID 0xac18
+#define DEVICE_VER 0x1337
+#define MANUFACTURER Obins
+#define PRODUCT Anne Pro 2(c18)QMK
+// key matrix size
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+// layer size: MATRIX_ROWS * MATRIX_COLS * sizeof(uint16_t) = 140 bytes
+
+#define LINE_UART_TX B0
+#define LINE_UART_RX B1
+
+#define LINE_BT_UART_TX A4 // Master TX, BLE RX
+#define LINE_BT_UART_RX A5 // Master RX, BLE TX
+
+// outputs (rows are pulled low)
+#define MATRIX_ROW_PINS \
+ { B5, B4, B3, B2, D1 }
+
+// inputs (columns are sampled)
+#define MATRIX_COL_PINS \
+ { C4, C5, D0, B15, C11, A15, C12, C13, A8, A10, A11, A14, D2, D3 }
diff --git a/keyboards/annepro2/c18/readme.md b/keyboards/annepro2/c18/readme.md
new file mode 100644
index 0000000000..f2e2fc45b8
--- /dev/null
+++ b/keyboards/annepro2/c18/readme.md
@@ -0,0 +1 @@
+AnnePro2, ANSI C18 version.
diff --git a/keyboards/annepro2/c18/rules.mk b/keyboards/annepro2/c18/rules.mk
new file mode 100644
index 0000000000..b2e16cc35f
--- /dev/null
+++ b/keyboards/annepro2/c18/rules.mk
@@ -0,0 +1,37 @@
+# Anne Pro 2
+SRC = \
+ matrix.c \
+ annepro2_ble.c \
+ ap2_led.c \
+ protocol.c
+
+# MCU
+MCU = cortex-m0plus
+ARMV = 6
+USE_FPU = no
+MCU_FAMILY = HT32
+MCU_SERIES = HT32F523xx
+MCU_LDSCRIPT = HT32F52342_ANNEPRO2
+MCU_STARTUP = ht32f523xx
+
+BOARD = ANNEPRO2_C18
+
+# Options
+
+# Keys
+CUSTOM_MATRIX = lite
+NKRO_ENABLE = no
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = yes
+KEY_LOCK_ENABLE = no
+
+# Other featues
+BOOTMAGIC_ENABLE = yes
+CONSOLE_ENABLE = no
+COMMAND_ENABLE = no
+RAW_ENABLE = no
+MIDI_ENABLE = no
+VIRTSER_ENABLE = no
+COMBO_ENABLE = no
+BOOTLOADER = custom
+PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin
diff --git a/keyboards/annepro2/chconf.h b/keyboards/annepro2/chconf.h
new file mode 100644
index 0000000000..51fe38cf27
--- /dev/null
+++ b/keyboards/annepro2/chconf.h
@@ -0,0 +1,31 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/annepro2/chconf.h -r platforms/chibios/common/configs/chconf.h`
+ */
+
+#pragma once
+
+#define CH_CFG_ST_FREQUENCY 1000
+
+#define CH_CFG_ST_TIMEDELTA 0
+
+#define CH_CFG_TIME_QUANTUM 20
+
+
+#include_next <chconf.h> \ No newline at end of file
diff --git a/keyboards/annepro2/halconf.h b/keyboards/annepro2/halconf.h
new file mode 100644
index 0000000000..686b91a7fb
--- /dev/null
+++ b/keyboards/annepro2/halconf.h
@@ -0,0 +1,28 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/annepro2/halconf.h -r platforms/chibios/common/configs/halconf.h`
+ */
+
+#pragma once
+
+#define HAL_USE_SERIAL TRUE
+
+#define SERIAL_USB_BUFFERS_SIZE 256
+
+#include_next <halconf.h>
diff --git a/keyboards/annepro2/info.json b/keyboards/annepro2/info.json
new file mode 100644
index 0000000000..8fd515bd10
--- /dev/null
+++ b/keyboards/annepro2/info.json
@@ -0,0 +1,330 @@
+{
+ "keyboard_name": "Anne Pro 2",
+ "url": "https://openannepro.github.io/",
+ "maintainer": "community",
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {
+ "label": "~",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "label": "!",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "label": "@",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "label": "#",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "label": "$",
+ "x": 4,
+ "y": 0
+ },
+ {
+ "label": "%",
+ "x": 5,
+ "y": 0
+ },
+ {
+ "label": "^",
+ "x": 6,
+ "y": 0
+ },
+ {
+ "label": "&",
+ "x": 7,
+ "y": 0
+ },
+ {
+ "label": "*",
+ "x": 8,
+ "y": 0
+ },
+ {
+ "label": "(",
+ "x": 9,
+ "y": 0
+ },
+ {
+ "label": ")",
+ "x": 10,
+ "y": 0
+ },
+ {
+ "label": "_",
+ "x": 11,
+ "y": 0
+ },
+ {
+ "label": "+",
+ "x": 12,
+ "y": 0
+ },
+ {
+ "label": "Backspace",
+ "x": 13,
+ "y": 0,
+ "w": 2
+ },
+ {
+ "label": "Tab",
+ "x": 0,
+ "y": 1,
+ "w": 1.5
+ },
+ {
+ "label": "Q",
+ "x": 1.5,
+ "y": 1
+ },
+ {
+ "label": "W",
+ "x": 2.5,
+ "y": 1
+ },
+ {
+ "label": "E",
+ "x": 3.5,
+ "y": 1
+ },
+ {
+ "label": "R",
+ "x": 4.5,
+ "y": 1
+ },
+ {
+ "label": "T",
+ "x": 5.5,
+ "y": 1
+ },
+ {
+ "label": "Y",
+ "x": 6.5,
+ "y": 1
+ },
+ {
+ "label": "U",
+ "x": 7.5,
+ "y": 1
+ },
+ {
+ "label": "I",
+ "x": 8.5,
+ "y": 1
+ },
+ {
+ "label": "O",
+ "x": 9.5,
+ "y": 1
+ },
+ {
+ "label": "P",
+ "x": 10.5,
+ "y": 1
+ },
+ {
+ "label": "{",
+ "x": 11.5,
+ "y": 1
+ },
+ {
+ "label": "}",
+ "x": 12.5,
+ "y": 1
+ },
+ {
+ "label": "|",
+ "x": 13.5,
+ "y": 1,
+ "w": 1.5
+ },
+ {
+ "label": "Caps Lock",
+ "x": 0,
+ "y": 2,
+ "w": 1.75
+ },
+ {
+ "label": "A",
+ "x": 1.75,
+ "y": 2
+ },
+ {
+ "label": "S",
+ "x": 2.75,
+ "y": 2
+ },
+ {
+ "label": "D",
+ "x": 3.75,
+ "y": 2
+ },
+ {
+ "label": "F",
+ "x": 4.75,
+ "y": 2
+ },
+ {
+ "label": "G",
+ "x": 5.75,
+ "y": 2
+ },
+ {
+ "label": "H",
+ "x": 6.75,
+ "y": 2
+ },
+ {
+ "label": "J",
+ "x": 7.75,
+ "y": 2
+ },
+ {
+ "label": "K",
+ "x": 8.75,
+ "y": 2
+ },
+ {
+ "label": "L",
+ "x": 9.75,
+ "y": 2
+ },
+ {
+ "label": ":",
+ "x": 10.75,
+ "y": 2
+ },
+ {
+ "label": "\"",
+ "x": 11.75,
+ "y": 2
+ },
+ {
+ "label": "Enter",
+ "x": 12.75,
+ "y": 2,
+ "w": 2.25
+ },
+ {
+ "label": "Shift",
+ "x": 0,
+ "y": 3,
+ "w": 2.25
+ },
+ {
+ "label": "Z",
+ "x": 2.25,
+ "y": 3
+ },
+ {
+ "label": "X",
+ "x": 3.25,
+ "y": 3
+ },
+ {
+ "label": "C",
+ "x": 4.25,
+ "y": 3
+ },
+ {
+ "label": "V",
+ "x": 5.25,
+ "y": 3
+ },
+ {
+ "label": "B",
+ "x": 6.25,
+ "y": 3
+ },
+ {
+ "label": "N",
+ "x": 7.25,
+ "y": 3
+ },
+ {
+ "label": "M",
+ "x": 8.25,
+ "y": 3
+ },
+ {
+ "label": "<",
+ "x": 9.25,
+ "y": 3
+ },
+ {
+ "label": ">",
+ "x": 10.25,
+ "y": 3
+ },
+ {
+ "label": "?",
+ "x": 11.25,
+ "y": 3
+ },
+ {
+ "label": "Shift",
+ "x": 12.25,
+ "y": 3,
+ "w": 2.75
+ },
+ {
+ "label": "Ctrl",
+ "x": 0,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "label": "Win",
+ "x": 1.25,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "label": "Alt",
+ "x": 2.5,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "x": 3.75,
+ "y": 4,
+ "w": 6.25
+ },
+ {
+ "label": "Alt",
+ "x": 10,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "label": "Win",
+ "x": 11.25,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "label": "Menu",
+ "x": 12.5,
+ "y": 4,
+ "w": 1.25
+ },
+ {
+ "label": "Ctrl",
+ "x": 13.75,
+ "y": 4,
+ "w": 1.25
+ }
+ ]
+ }
+ }
+}
diff --git a/keyboards/annepro2/keymaps/default-full-caps/config.h b/keyboards/annepro2/keymaps/default-full-caps/config.h
new file mode 100644
index 0000000000..413c5d8dc5
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default-full-caps/config.h
@@ -0,0 +1,20 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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
+
+// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
+#define PERMISSIVE_HOLD
diff --git a/keyboards/annepro2/keymaps/default-full-caps/keymap.c b/keyboards/annepro2/keymaps/default-full-caps/keymap.c
new file mode 100644
index 0000000000..8ac9211ac4
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default-full-caps/keymap.c
@@ -0,0 +1,120 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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 QMK_KEYBOARD_H
+
+enum anne_pro_layers {
+ _BASE_LAYER,
+ _FN1_LAYER,
+ _FN2_LAYER,
+};
+
+// clang-format off
+
+// Key symbols are based on QMK. Use them to remap your keyboard
+/*
+* Layer _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Bksp |
+* |-----------------------------------------------------------------------------------------+
+* | Tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ |
+* |-----------------------------------------------------------------------------------------+
+* | Caps | a | s | d | f | g | h | j | k | l | ; | ' | Enter |
+* |-----------------------------------------------------------------------------------------+
+* | Shift | z | x | c | v | b | n | m | , | . | / | Shift |
+* |-----------------------------------------------------------------------------------------+
+* | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+* \-----------------------------------------------------------------------------------------/
+* Layer TAP in _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | UP |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | LEFT | DOWN | RIGHT |
+* \-----------------------------------------------------------------------------------------/
+*/
+ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE_LAYER] = LAYOUT( /* Base */
+ 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,
+ LT(_FN1_LAYER,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, RSFT_T(KC_UP),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, LT(_FN1_LAYER,KC_LEFT), LT(_FN2_LAYER,KC_DOWN), RCTL_T(KC_RGHT)
+),
+ /*
+ * Layer _FN1_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ` | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | DELETE |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift |V-UP |V-DWN|MUTE | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN1_LAYER] = LAYOUT( /* Base */
+ 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, KC_DEL,
+ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN2_LAYER), KC_TRNS
+),
+ /*
+ * Layer _FN2_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ~ | BT1 | BT2 | BT3 | BT4 | F5 | F6 | F7 |LEDOF|LEDON| F10 | F11 | F12 | Bksp |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift | z | x | c | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN2_LAYER] = LAYOUT( /* Base */
+ KC_TRNS, KC_AP2_BT1, KC_AP2_BT2, KC_AP2_BT3, KC_AP2_BT4, KC_TRNS, KC_TRNS, KC_TRNS, KC_AP_LED_OFF, KC_AP_LED_ON, KC_AP_LED_NEXT_INTENSITY, KC_AP_LED_SPEED, KC_TRNS, KC_TRNS,
+ MO(_FN2_LAYER), KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN1_LAYER), MO(_FN2_LAYER), KC_TRNS
+ ),
+};
+
+// clang-format on
+
+// The function to handle the caps lock logic
+bool led_update_user(led_t leds) {
+ if (leds.caps_lock) {
+ // Set the leds to red
+ annepro2LedSetForegroundColor(0xFF, 0x00, 0x00);
+ } else {
+ annepro2LedResetForegroundColor();
+ }
+
+ return true;
+}
diff --git a/keyboards/annepro2/keymaps/default-layer-indicators/config.h b/keyboards/annepro2/keymaps/default-layer-indicators/config.h
new file mode 100644
index 0000000000..413c5d8dc5
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default-layer-indicators/config.h
@@ -0,0 +1,20 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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
+
+// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
+#define PERMISSIVE_HOLD
diff --git a/keyboards/annepro2/keymaps/default-layer-indicators/keymap.c b/keyboards/annepro2/keymaps/default-layer-indicators/keymap.c
new file mode 100644
index 0000000000..ac2b421d06
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default-layer-indicators/keymap.c
@@ -0,0 +1,147 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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 QMK_KEYBOARD_H
+
+enum anne_pro_layers {
+ _BASE_LAYER,
+ _FN1_LAYER,
+ _FN2_LAYER,
+};
+
+// clang-format off
+
+// Key symbols are based on QMK. Use them to remap your keyboard
+/*
+* Layer _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Bksp |
+* |-----------------------------------------------------------------------------------------+
+* | Tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ |
+* |-----------------------------------------------------------------------------------------+
+* | Caps | a | s | d | f | g | h | j | k | l | ; | ' | Enter |
+* |-----------------------------------------------------------------------------------------+
+* | Shift | z | x | c | v | b | n | m | , | . | / | Shift |
+* |-----------------------------------------------------------------------------------------+
+* | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+* \-----------------------------------------------------------------------------------------/
+* Layer TAP in _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | UP |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | LEFT | DOWN | RIGHT |
+* \-----------------------------------------------------------------------------------------/
+*/
+ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE_LAYER] = LAYOUT( /* Base */
+ 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,
+ LT(_FN1_LAYER,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, RSFT_T(KC_UP),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, LT(_FN1_LAYER,KC_LEFT), LT(_FN2_LAYER,KC_DOWN), RCTL_T(KC_RGHT)
+),
+ /*
+ * Layer _FN1_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ` | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | DELETE |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift |V-UP |V-DWN|MUTE | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN1_LAYER] = LAYOUT( /* Base */
+ 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, KC_DEL,
+ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN2_LAYER), KC_TRNS
+),
+ /*
+ * Layer _FN2_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ~ | BT1 | BT2 | BT3 | BT4 | F5 | F6 | F7 |LEDOF|LEDON| F10 | F11 | F12 | Bksp |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift | z | x | c | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN2_LAYER] = LAYOUT( /* Base */
+ KC_TRNS, KC_AP2_BT1, KC_AP2_BT2, KC_AP2_BT3, KC_AP2_BT4, KC_TRNS, KC_TRNS, KC_TRNS, KC_AP_LED_OFF, KC_AP_LED_ON, KC_AP_LED_NEXT_INTENSITY, KC_AP_LED_SPEED, KC_TRNS, KC_TRNS,
+ MO(_FN2_LAYER), KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN1_LAYER), MO(_FN2_LAYER), KC_TRNS
+ ),
+};
+
+// clang-format on
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ switch (get_highest_layer(state)) {
+ case _FN1_LAYER:
+ // Set the leds to green
+ annepro2LedSetForegroundColor(0x00, 0xFF, 0x00);
+ break;
+ case _FN2_LAYER:
+ // Set the leds to blue
+ annepro2LedSetForegroundColor(0x00, 0x00, 0xFF);
+ break;
+ default:
+ // Reset back to the current profile
+ annepro2LedResetForegroundColor();
+ break;
+ }
+ return state;
+}
+
+// The function to handle the caps lock logic
+// It's called after the capslock changes state or after entering layers 1 and 2.
+bool led_update_user(led_t leds) {
+ if (leds.caps_lock) {
+ // Set the caps-lock to red
+ const annepro2Led_t color = {.p.red = 0xff, .p.green = 0x00, .p.blue = 0x00, .p.alpha = 0xff};
+
+ annepro2LedMaskSetKey(2, 0, color);
+ /* NOTE: Instead of colouring the capslock only, you can change the whole
+ keyboard with annepro2LedSetForegroundColor */
+ } else {
+ // Reset the capslock if there is no layer active
+ if (!layer_state_is(_FN1_LAYER) && !layer_state_is(_FN2_LAYER)) {
+ const annepro2Led_t color = {.p.red = 0xff, .p.green = 0x00, .p.blue = 0x00, .p.alpha = 0x00};
+ annepro2LedMaskSetKey(2, 0, color);
+ }
+ }
+
+ return true;
+}
diff --git a/keyboards/annepro2/keymaps/default/config.h b/keyboards/annepro2/keymaps/default/config.h
new file mode 100644
index 0000000000..413c5d8dc5
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default/config.h
@@ -0,0 +1,20 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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
+
+// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
+#define PERMISSIVE_HOLD
diff --git a/keyboards/annepro2/keymaps/default/keymap.c b/keyboards/annepro2/keymaps/default/keymap.c
new file mode 100644
index 0000000000..a984b05830
--- /dev/null
+++ b/keyboards/annepro2/keymaps/default/keymap.c
@@ -0,0 +1,106 @@
+ /* Copyright 2021 OpenAnnePro community
+ *
+ * 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 QMK_KEYBOARD_H
+
+enum anne_pro_layers {
+ _BASE_LAYER,
+ _FN1_LAYER,
+ _FN2_LAYER,
+};
+
+// clang-format off
+// Key symbols are based on QMK. Use them to remap your keyboard
+/*
+* Layer _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Bksp |
+* |-----------------------------------------------------------------------------------------+
+* | Tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ |
+* |-----------------------------------------------------------------------------------------+
+* | Caps | a | s | d | f | g | h | j | k | l | ; | ' | Enter |
+* |-----------------------------------------------------------------------------------------+
+* | Shift | z | x | c | v | b | n | m | , | . | / | Shift |
+* |-----------------------------------------------------------------------------------------+
+* | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+* \-----------------------------------------------------------------------------------------/
+* Layer TAP in _BASE_LAYER
+* ,-----------------------------------------------------------------------------------------.
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | | |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | | | | | | | UP |
+* |-----------------------------------------------------------------------------------------+
+* | | | | | | LEFT | DOWN | RIGHT |
+* \-----------------------------------------------------------------------------------------/
+*/
+ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE_LAYER] = LAYOUT( /* Base */
+ 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,
+ LT(_FN1_LAYER,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, RSFT_T(KC_UP),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, LT(_FN1_LAYER,KC_LEFT), LT(_FN2_LAYER,KC_DOWN), RCTL_T(KC_RGHT)
+),
+ /*
+ * Layer _FN1_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ` | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | DELETE |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift |V-UP |V-DWN|MUTE | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN1_LAYER] = LAYOUT( /* Base */
+ 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, KC_DEL,
+ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN2_LAYER), KC_TRNS
+),
+ /*
+ * Layer _FN2_LAYER
+ * ,-----------------------------------------------------------------------------------------.
+ * | ~ | BT1 | BT2 | BT3 | BT4 | F5 | F6 | F7 |LEDOF|LEDON| F10 | F11 | F12 | Bksp |
+ * |-----------------------------------------------------------------------------------------+
+ * | Tab | q | UP | e | r | t | y | u | i | o | PS | HOME | END | \ |
+ * |-----------------------------------------------------------------------------------------+
+ * | Esc |LEFT |DOWN |RIGHT| f | g | h | j | k | l | PGUP|PGDN | Enter |
+ * |-----------------------------------------------------------------------------------------+
+ * | Shift | z | x | c | v | b | n | m | , |INSRT| DEL | Shift |
+ * |-----------------------------------------------------------------------------------------+
+ * | Ctrl | L1 | Alt | space | Alt | FN1 | FN2 | Ctrl |
+ * \-----------------------------------------------------------------------------------------/
+ *
+ */
+ [_FN2_LAYER] = LAYOUT( /* Base */
+ KC_TRNS, KC_AP2_BT1, KC_AP2_BT2, KC_AP2_BT3, KC_AP2_BT4, KC_TRNS, KC_TRNS, KC_TRNS, KC_AP_LED_OFF, KC_AP_LED_ON, KC_AP_LED_NEXT_INTENSITY, KC_AP_LED_SPEED, KC_TRNS, KC_TRNS,
+ MO(_FN2_LAYER), KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_HOME, KC_END, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FN1_LAYER), MO(_FN2_LAYER), KC_TRNS
+ ),
+};
+// clang-format on
diff --git a/keyboards/annepro2/ld/HT32F52342_ANNEPRO2.ld b/keyboards/annepro2/ld/HT32F52342_ANNEPRO2.ld
new file mode 100644
index 0000000000..544400b948
--- /dev/null
+++ b/keyboards/annepro2/ld/HT32F52342_ANNEPRO2.ld
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013-2016 Fabio UJonathan A. Kollaschtzig, http://fabioutzig.com
+ * (c) 2020 Yaotian Feng (Codetector) <codetector@codetector.cn>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * HT32F52342 w/ Anne Pro 2 bootloader memory setup.
+ */
+MEMORY {
+ flash0 : org = 0x00004000, len = 64k - 16k /* firmware */
+ 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 = 8k - 4 /* RAM */
+ 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/annepro2/matrix.c b/keyboards/annepro2/matrix.c
new file mode 100644
index 0000000000..a1585e4ddf
--- /dev/null
+++ b/keyboards/annepro2/matrix.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Charlie Waters
+ *
+ * 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 <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <hal.h>
+#include "timer.h"
+#include "wait.h"
+#include "print.h"
+#include "matrix.h"
+#include "annepro2.h"
+
+pin_t row_list[MATRIX_ROWS] = MATRIX_ROW_PINS;
+pin_t col_list[MATRIX_COLS] = MATRIX_COL_PINS;
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ bool matrix_has_changed = false;
+ // cache of input ports for columns
+ static uint16_t port_cache[4];
+ // scan each row
+ for (int row = 0; row < MATRIX_ROWS; row++) {
+ palClearLine(row_list[row]);
+ __NOP();
+ __NOP();
+ __NOP();
+ __NOP();
+ // read i/o ports
+ port_cache[0] = palReadPort(IOPORTA);
+ port_cache[1] = palReadPort(IOPORTB);
+ port_cache[2] = palReadPort(IOPORTC);
+ port_cache[3] = palReadPort(IOPORTD);
+ palSetLine(row_list[row]);
+
+ // get columns from ports
+ matrix_row_t data = 0;
+ for (int col = 0; col < MATRIX_COLS; ++col) {
+ pin_t line = col_list[col];
+ uint16_t port = port_cache[HT32_PAL_IDX(PAL_PORT(line))];
+ data |= (((port & (1 << PAL_PAD(line))) ? 0 : 1) << col);
+ }
+
+ if (current_matrix[row] != data) {
+ current_matrix[row] = data;
+ matrix_has_changed = true;
+ }
+ }
+ return matrix_has_changed;
+} \ No newline at end of file
diff --git a/keyboards/annepro2/mcuconf.h b/keyboards/annepro2/mcuconf.h
new file mode 100644
index 0000000000..8265fe6eb9
--- /dev/null
+++ b/keyboards/annepro2/mcuconf.h
@@ -0,0 +1,62 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 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
+
+#include "nvic.h"
+
+#define HT32F52342_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+
+/*
+ * Clock configuration.
+ */
+
+// This configuration:
+// 8 MHz HSE crystal
+// PLL multiplies HSE to 48 MHz core and peripheral clock
+// 48 MHz to UART
+// 48 MHz to USB
+
+#define HT32_CK_HSE_FREQUENCY 8000000UL // 8 MHz
+#define HT32_CKCU_SW CKCU_GCCR_SW_PLL
+#define HT32_PLL_USE_HSE TRUE
+#define HT32_PLL_FBDIV 6 // 8 MHz -> 48 MHz
+#define HT32_PLL_OTDIV 0
+#define HT32_AHB_PRESCALER 1 // 48 MHz -> 48 MHz
+#define HT32_USART_PRESCALER 1 // 48 MHz
+#define HT32_USB_PRESCALER 1 // 48 MHz -> 48 MHz
+// SysTick uses processor clock at 48MHz
+#define HT32_ST_USE_HCLK TRUE
+
+/*
+ * Peripheral driver settings
+ */
+
+#define HT32_SERIAL_USE_USART0 TRUE
+#define HT32_USART0_IRQ_PRIORITY 6
+
+#define HT32_SERIAL_USE_USART1 TRUE
+#define HT32_USART1_IRQ_PRIORITY 7
+
+/*
+ * USB driver settings
+ */
+
+#define HT32_USB_USE_USB0 TRUE
+#define HT32_USB_USB0_IRQ_PRIORITY 5
diff --git a/keyboards/annepro2/protocol.c b/keyboards/annepro2/protocol.c
new file mode 100644
index 0000000000..171ac5c239
--- /dev/null
+++ b/keyboards/annepro2/protocol.c
@@ -0,0 +1,116 @@
+/*
+ * (c) 2021 by Tomasz bla Fortuna
+ * License: GPLv2
+ *
+ * This file is shared with the Shine firmware. Keep it in sync (and in the
+ * shine's clang formatting).
+ *
+ * Implementation of a robust serial protocol which can handle single dropped
+ * characters during transit without locking.
+ *
+ * At 115200, transmitting the shortest message takes 0.043ms, at 9600 - 0.52ms.
+ *
+ */
+
+#include "protocol.h"
+#include "board.h"
+#include "ch.h"
+#include "hal.h"
+
+/* UART communication protocol state */
+protocol_t proto;
+
+void protoInit(protocol_t *proto, void (*callback)(const message_t *)) {
+ proto->previousId = 0;
+ proto->callback = callback;
+ proto->state = STATE_SYNC_1;
+ proto->errors = 0;
+}
+
+static uint8_t msgId = 0;
+void protoTx(uint8_t cmd, const unsigned char *buf, int payloadSize, int retries) {
+ chDbgCheck(payloadSize <= MAX_PAYLOAD_SIZE);
+
+ const uint8_t header[5] = {
+ 0x7A, 0x1D, cmd, ++msgId, payloadSize,
+ };
+
+ /* We don't implement ACKs, yet some messages should not be lost. */
+ for (int i = 0; i < retries; i++) {
+ sdWrite(&PROTOCOL_SD, header, sizeof(header));
+ if (payloadSize) sdWrite(&PROTOCOL_SD, buf, payloadSize);
+ }
+}
+
+static inline void messageReceived(protocol_t *proto) {
+ if (proto->buffer.msgId != proto->previousId) {
+ /* It's not a resend / duplicate */
+ proto->callback(&proto->buffer);
+ proto->previousId = proto->buffer.msgId;
+ }
+ proto->state = STATE_SYNC_1;
+}
+
+void protoConsume(protocol_t *proto, uint8_t byte) {
+ switch (proto->state) {
+ case STATE_SYNC_1:
+ if (byte == 0x7A) {
+ proto->state = STATE_SYNC_2;
+ } else {
+ proto->errors++;
+ }
+ return;
+
+ case STATE_SYNC_2:
+ if (byte == 0x1D) {
+ proto->state = STATE_CMD;
+ } else {
+ proto->state = STATE_SYNC_1;
+ proto->errors++;
+ }
+ return;
+
+ case STATE_CMD:
+ proto->buffer.command = byte;
+ proto->state = STATE_ID;
+ return;
+
+ case STATE_ID:
+ proto->buffer.msgId = byte;
+ proto->state = STATE_PAYLOAD_SIZE;
+ return;
+
+ case STATE_PAYLOAD_SIZE:
+ proto->buffer.payloadSize = byte;
+ if (proto->buffer.payloadSize > MAX_PAYLOAD_SIZE) {
+ proto->buffer.payloadSize = MAX_PAYLOAD_SIZE;
+ proto->errors++;
+ }
+ proto->payloadPosition = 0;
+ if (proto->buffer.payloadSize == 0) {
+ /* No payload - whole message received */
+ messageReceived(proto);
+ } else {
+ proto->state = STATE_PAYLOAD;
+ }
+ return;
+
+ case STATE_PAYLOAD:
+ /* NOTE: This could be read with sdReadTimeout probably, but that breaks
+ * abstraction */
+ proto->buffer.payload[proto->payloadPosition] = byte;
+ proto->payloadPosition++;
+ if (proto->payloadPosition == proto->buffer.payloadSize) {
+ /* Payload read - message received */
+ messageReceived(proto);
+ }
+ return;
+ }
+}
+
+void protoSilence(protocol_t *proto) {
+ if (proto->state != STATE_SYNC_1) {
+ proto->state = STATE_SYNC_1;
+ proto->errors++;
+ }
+}
diff --git a/keyboards/annepro2/protocol.h b/keyboards/annepro2/protocol.h
new file mode 100644
index 0000000000..d1a05683c8
--- /dev/null
+++ b/keyboards/annepro2/protocol.h
@@ -0,0 +1,111 @@
+/*
+ * (c) 2021 by Tomasz bla Fortuna
+ * License: GPLv2
+ *
+ * This file is shared with the Shine firmware. Keep it in sync (and in the
+ * shine's clang formatting).
+ */
+
+#pragma once
+#include <stdint.h>
+
+#define PROTOCOL_SD SD0
+
+enum {
+ /*
+ * Main -> LED
+ */
+ /* Basic config */
+ CMD_LED_ON = 0x01,
+ CMD_LED_OFF = 0x02,
+
+ CMD_LED_SET_PROFILE = 0x03,
+ CMD_LED_NEXT_PROFILE = 0x04,
+ CMD_LED_PREV_PROFILE = 0x05,
+
+ CMD_LED_NEXT_INTENSITY = 0x06,
+ CMD_LED_NEXT_ANIMATION_SPEED = 0x07,
+
+ /* Masks */
+ /* Override a key color, eg. capslock */
+ CMD_LED_MASK_SET_KEY = 0x10,
+ /* Override all keys in a row with configurable colors */
+ CMD_LED_MASK_SET_ROW = 0x11,
+
+ /* Override all keys with single color (eg. foreground color) */
+ CMD_LED_MASK_SET_MONO = 0x12,
+
+ /* Reactive / status */
+ CMD_LED_GET_STATUS = 0x20,
+ CMD_LED_KEY_BLINK = 0x21,
+ CMD_LED_KEY_DOWN = 0x22,
+ CMD_LED_KEY_UP = 0x23, /* TODO */
+ CMD_LED_IAP = 0x24,
+
+ /* LED -> Main */
+ /* Payload with data to send over HID */
+ CMD_LED_DEBUG = 0x40,
+
+ /* Number of profiles, current profile, on/off state,
+ reactive flag, brightness, errors */
+ CMD_LED_STATUS = 0x41,
+};
+
+/* 1 ROW * 14 COLS * 4B (RGBX) = 56 + header prefix. */
+#define MAX_PAYLOAD_SIZE 64
+
+/** Enum of the states used for the serial protocol finite-state automaton */
+enum protoState {
+ /* 2-byte initial start-of-message sync */
+ STATE_SYNC_1,
+ STATE_SYNC_2,
+ /* Waiting for command byte */
+ STATE_CMD,
+ /* Waiting for ID byte */
+ STATE_ID,
+ /* Waiting for payload size */
+ STATE_PAYLOAD_SIZE,
+ /* Reading payload until payloadPosition == payloadSize */
+ STATE_PAYLOAD,
+};
+
+/* Buffer holding a single message */
+typedef struct {
+ uint8_t command;
+ uint8_t msgId;
+ uint8_t payloadSize;
+ uint8_t payload[MAX_PAYLOAD_SIZE];
+} message_t;
+
+/* Internal protocol state */
+typedef struct {
+ /* Callback to call upon receiving a valid message */
+ void (*callback)(const message_t *);
+
+ /* Number of read payload bytes */
+ uint8_t payloadPosition;
+
+ /* Current finite-state-automata state */
+ enum protoState state;
+
+ uint8_t previousId;
+ uint8_t errors;
+
+ /* Currently received message */
+ message_t buffer;
+} protocol_t;
+
+/* NOTE: This didn't work when defined on stack */
+extern protocol_t proto;
+
+/* Init state */
+extern void protoInit(protocol_t *proto, void (*callback)(const message_t *));
+
+/* Consume one byte and push state forward - might call the callback */
+extern void protoConsume(protocol_t *proto, uint8_t byte);
+
+/* Prolonged silence - reset state */
+extern void protoSilence(protocol_t *proto);
+
+/* Transmit message */
+extern void protoTx(uint8_t cmd, const unsigned char *buf, int payloadSize, int retries);
diff --git a/keyboards/annepro2/readme.md b/keyboards/annepro2/readme.md
new file mode 100644
index 0000000000..e3e0b95be4
--- /dev/null
+++ b/keyboards/annepro2/readme.md
@@ -0,0 +1,50 @@
+# Anne Pro 2 rev. C15 and C18 QMK firmware
+
+## Introduction
+
+This is the QMK firmware repository for the Anne Pro 2 rev. C15 and C18 keyboard.
+
+## Layouts
+
+Keyboard has 60% ANSI standard layout.
+
+## How to compile
+
+After setting up your build environment, you can compile the Anne Pro 2 C18 default keymap by using:
+
+ make annepro2/c18:default
+
+If you want to compile the Anne Pro 2 C15 default keymap use:
+
+ make annepro2/c15:default
+
+## Installing
+
+### Get AnnePro2 Tools
+
+If you want the executable instead of compiling it yourself, [download it here](https://ci.codetector.org/job/OpenAnnePro/job/AnnePro2-Tools/job/master/).
+Windows and Linux versions are available. Otherwise, follow the steps below:
+
+0. Install the latest stable `rust` toolchain using [rustup](https://rustup.rs/)
+0. Also install [Visual Studio Community edition](https://visualstudio.microsoft.com/downloads/)
+including the C/C++ module to prevent errors while compiling
+0. Download or Clone the [AnnePro2-Tools](https://github.com/OpenAnnePro/AnnePro2-Tools) project.
+0. Compile the tool using
+```bash
+cargo build --release
+```
+0. The compiled tool should be in `./target/release/annepro2_tools` (In later I will refer to this as `annepro2_tools`)
+
+### Flashing the firmware
+0. Put the keyboard into DFU/IAP mode by unplugging the keyboard, then holding ESC while plugging it back in.
+0. Run annepro2_tools with the firmware you just built.
+
+**Please substitute with the correct paths and correct bin file if you chose another keymap profile**
+```bash
+annepro2_tools annepro2_c15_default.bin
+```
+
+If the tool can't find the keyboard please double check you have the keyboard in IAP mode.
+
+
+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). \ No newline at end of file