diff --git a/drivers/chibios/spi_master.c b/drivers/chibios/spi_master.c index 552ac663c1e9..d7e3c4561d69 100644 --- a/drivers/chibios/spi_master.c +++ b/drivers/chibios/spi_master.c @@ -32,6 +32,10 @@ __attribute__((weak)) void spi_init(void) { palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); +#elif defined(HT32_SPI_USE_SPI1) || defined(HT32_SPI_USE_SPI2) + palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_HT32_MODE_AF(SPI_SCK_PAL_MODE) | PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_HT32_MODE_AF(SPI_MOSI_PAL_MODE) | PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_HT32_MODE_AF(SPI_MISO_PAL_MODE) | PAL_MODE_OUTPUT_PUSHPULL); #else palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); @@ -53,12 +57,36 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { return false; } +#if defined(HT32_SPI_USE_SPI1) || defined(HT32_SPI_USE_SPI2) + spiConfig.cr0 = SPI_CR0_SELOEN; + spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode + + if (lsbFirst) { + spiConfig.cr1 |= SPI_CR1_FIRSTBIT; + } + + switch (mode) { + case 0: + spiConfig.cr1 |= SPI_CR1_FORMAT_MODE0; + break; + case 1: + spiConfig.cr1 |= SPI_CR1_FORMAT_MODE1; + break; + case 2: + spiConfig.cr1 |= SPI_CR1_FORMAT_MODE2; + break; + case 3: + spiConfig.cr1 |= SPI_CR1_FORMAT_MODE3; + break; + } + + spiConfig.cpr = (roundedDivisor - 1) >> 1; +#else spiConfig.cr1 = 0; if (lsbFirst) { spiConfig.cr1 |= SPI_CR1_LSBFIRST; } - switch (mode) { case 0: break; @@ -98,6 +126,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0; break; } +#endif currentSlavePin = slavePin; spiConfig.ssport = PAL_PORT(slavePin); diff --git a/keyboards/annepro2/annepro2.c b/keyboards/annepro2/annepro2.c index fd180695916b..a6bcf423bf37 100644 --- a/keyboards/annepro2/annepro2.c +++ b/keyboards/annepro2/annepro2.c @@ -2,6 +2,7 @@ #include "hal.h" #include "annepro2.h" #include "annepro2_ble.h" +#include "spi_master.h" #include "qmk_ap2_led.h" static const SerialConfig ledUartConfig = { @@ -26,6 +27,9 @@ uint16_t annepro2LedMatrix[MATRIX_ROWS * MATRIX_COLS] = { }; void OVERRIDE keyboard_pre_init_kb(void) { +#if HAL_USE_SPI == TRUE + spi_init(); +#endif } void OVERRIDE keyboard_post_init_kb(void) { @@ -33,10 +37,21 @@ void OVERRIDE keyboard_post_init_kb(void) { sdStart(&SD0, &ledUartConfig); sdWrite(&SD0, ledMcuWakeup, 11); + // wait to receive response from wakeup + wait_ms(15); + + // loop to clear out receive buffer from shine wakeup + while(!sdGetWouldBlock(&SD0)) + sdGet(&SD0); + // 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(5); + keyboard_post_init_user(); } @@ -77,20 +92,21 @@ bool OVERRIDE process_record_kb(uint16_t keycode, keyrecord_t *record) { case KC_AP_LED_OFF: annepro2LedPrevProfile(); annepro2LedDisable(); - return false; + break; case KC_AP_LED_ON: annepro2LedNextProfile(); annepro2LedEnable(); - return false; + break; case KC_AP_LED_NEXT_PROFILE: annepro2LedNextProfile(); - return false; + break; case KC_AP_LED_PREV_PROFILE: annepro2LedPrevProfile(); - return false; + break; + default: break; diff --git a/keyboards/annepro2/c18/config.h b/keyboards/annepro2/c18/config.h index ad6333889220..96b8c1f3e085 100644 --- a/keyboards/annepro2/c18/config.h +++ b/keyboards/annepro2/c18/config.h @@ -60,6 +60,31 @@ /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 +#if defined(ANNEPRO2_EEPROM) +// SPI Config +#define SPI_DRIVER SPID1 +#define SPI_SCK_PIN A0 +#define SPI_SCK_PAL_MODE 5 +#define SPI_MOSI_PIN A1 +#define SPI_MOSI_PAL_MODE 5 +#define SPI_MISO_PIN A2 +#define SPI_MISO_PAL_MODE 5 +// EEPROM Config for W25X20CL +#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN A3 +#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 16 +#define EXTERNAL_EEPROM_BYTE_COUNT 1024 // 262144 +#define EXTERNAL_EEPROM_PAGE_SIZE 256 +#define EXTERNAL_EEPROM_ADDRESS_SIZE 3 +#define EXTERNAL_EEPROM_SPI_LSBFIRST false +#define EXTERNAL_EEPROM_SPI_MODE 3 +// HAL Config +#define HAL_USE_SPI TRUE +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +// MCU Config +#define HT32_SPI_USE_SPI1 TRUE +#define HT32_SPI1_IRQ_PRIORITY 9 +#endif + /* number of backlight levels */ // #define BACKLIGHT_LEVELS 10 diff --git a/keyboards/annepro2/c18/rules.mk b/keyboards/annepro2/c18/rules.mk index e042ff844a55..11efab064870 100644 --- a/keyboards/annepro2/c18/rules.mk +++ b/keyboards/annepro2/c18/rules.mk @@ -5,6 +5,11 @@ SRC = \ annepro2_ble.c \ qmk_ap2_led.c +ifeq ($(strip $(ANNEPRO2_EEPROM)), yes) + OPT_DEFS += -DANNEPRO2_EEPROM + SRC += spi_master.c eeprom_w25x20cl.c +endif + LAYOUTS += # MCU diff --git a/keyboards/annepro2/eeprom_w25x20cl.c b/keyboards/annepro2/eeprom_w25x20cl.c new file mode 100644 index 000000000000..6f96e650fcbd --- /dev/null +++ b/keyboards/annepro2/eeprom_w25x20cl.c @@ -0,0 +1,203 @@ +/* Copyright 2020 Nick Brassel (tzarc) and tech2077 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +/* + Note that the implementations of eeprom_XXXX_YYYY on AVR are normally + provided by avr-libc. The same functions are reimplemented below and are + rerouted to the external SPI equivalent. + + Seemingly, as this is compiled from within QMK, the object file generated + during the build overrides the avr-libc implementation during the linking + stage. + + On other platforms such as ARM, there are no provided implementations, so + there is nothing to override during linkage. +*/ + +#include "wait.h" +#include "spi_master.h" +#include "eeprom.h" +#include "eeprom_w25x20cl.h" + +#define CMD_WREN 0x06u +#define CMD_WRDI 0x04u +#define CMD_RDSR 0x05u +#define CMD_WRSR 0x01u +#define CMD_READ 0x03u +#define CMD_WRITE 0x02u +#define CMD_SECTOR_ERASE 0x20u + +#define SR_WIP 0x01u + +// #define DEBUG_EEPROM_OUTPUT + +#ifndef EXTERNAL_EEPROM_SPI_TIMEOUT +# define EXTERNAL_EEPROM_SPI_TIMEOUT 100 +#endif + +#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) +# include "timer.h" +# include "debug.h" +#endif // CONSOLE_ENABLE + +bool spi_eeprom_start(void) { + return spi_start(EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN, EXTERNAL_EEPROM_SPI_LSBFIRST, EXTERNAL_EEPROM_SPI_MODE, EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR); +} + +static spi_status_t spi_eeprom_wait_while_busy(int timeout) { + uint32_t deadline = timer_read32() + timeout; + spi_status_t response; + spi_write(CMD_RDSR); + do { + response = spi_read(); + if (timer_read32() >= deadline) { + return SPI_STATUS_TIMEOUT; + } + } while ((uint16_t)response & SR_WIP); + return SPI_STATUS_SUCCESS; +} +//---------------------------------------------------------------------------------------------------------------------- + +void eeprom_erase(uint32_t addr) { +#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) + uint32_t start = timer_read32(); +#endif + + spi_eeprom_start(); + spi_write(CMD_WREN); + spi_stop(); + + spi_eeprom_start(); + spi_write(CMD_SECTOR_ERASE); + spi_write((uint8_t)((addr & 0xFF0000u) >> 16u)); + spi_write((uint8_t)((addr & 0x00FF00u) >> 8u)); + spi_write((uint8_t)((addr & 0x0000FFu))); + spi_stop(); + + spi_eeprom_start(); + spi_status_t response = spi_eeprom_wait_while_busy(10000); + spi_stop(); + if (response == SPI_STATUS_TIMEOUT) { + dprint("SPI timeout for WIP check\n"); + return; + } + +#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) + dprintf("EEPROM erase took %ldms to complete\n", ((long)(timer_read32() - start))); +#endif +} + +void eeprom_read(void *buf, uint32_t addr, size_t len) { + //------------------------------------------------- + // Wait for the write-in-progress bit to be cleared + bool res = spi_eeprom_start(); + if (!res) { + dprint("failed to start SPI for WIP check\n"); + spi_stop(); + return; + } + + spi_status_t response = spi_eeprom_wait_while_busy(EXTERNAL_EEPROM_SPI_TIMEOUT); + spi_stop(); + if (response == SPI_STATUS_TIMEOUT) { + dprint("SPI timeout for WIP check\n"); + spi_stop(); + return; + } + + //------------------------------------------------- + // Perform read + res = spi_eeprom_start(); + if (!res) { + dprint("failed to start SPI for read\n"); + spi_stop(); + return; + } + + spi_write(CMD_READ); + spi_write((uint8_t)((addr & 0xFF0000u) >> 16u)); + spi_write((uint8_t)((addr & 0x00FF00u) >> 8u)); + spi_write((uint8_t)((addr & 0x0000FFu))); + spi_receive(buf, len); + spi_stop(); + +#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) + dprintf("[EEPROM R] 0x%08lX: ", (addr)); + for (size_t i = 0; i < len; ++i) { + dprintf(" %02X", (int)(((uint8_t *)buf)[i])); + } + dprintf("\n"); +#endif // DEBUG_EEPROM_OUTPUT + +} + +void eeprom_write(const void *buf, uint32_t addr, size_t len) { + eeprom_erase(addr); + + //------------------------------------------------- + // Enable writes + bool res = spi_eeprom_start(); + if (!res) { + dprint("failed to start SPI for write-enable\n"); + spi_stop(); + return; + } + + spi_write(CMD_WREN); + spi_stop(); + + wait_us(1); + + //------------------------------------------------- + // Perform the write + res = spi_eeprom_start(); + if (!res) { + dprint("failed to start SPI for write\n"); + spi_stop(); + return; + } + +#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) + dprintf("[EEPROM W] 0x%08lX: ", ((uint32_t)(uintptr_t)addr)); + for (size_t i = 0; i < len; i++) { + dprintf(" %02X", (int)(uint8_t)(buf[i])); + } + dprintf("\n"); +#endif // DEBUG_EEPROM_OUTPUT + + spi_write(CMD_WRITE); + spi_write((uint8_t)((addr & 0xFF0000u) >> 16u)); + spi_write((uint8_t)((addr & 0x00FF00u) >> 8u)); + spi_write((uint8_t)((addr & 0x0000FFu))); + spi_transmit(buf, len); + spi_stop(); + + res = spi_eeprom_start(); + if (!res) { + dprint("failed to start SPI for status\n"); + spi_stop(); + return; + } + spi_status_t response = spi_eeprom_wait_while_busy(EXTERNAL_EEPROM_SPI_TIMEOUT); + spi_stop(); + if (response == SPI_STATUS_TIMEOUT) { + dprint("SPI timeout for WIP check\n"); + return; + } +} diff --git a/keyboards/annepro2/eeprom_w25x20cl.h b/keyboards/annepro2/eeprom_w25x20cl.h new file mode 100644 index 000000000000..17021daded64 --- /dev/null +++ b/keyboards/annepro2/eeprom_w25x20cl.h @@ -0,0 +1,84 @@ +/* Copyright 2020 Nick Brassel (tzarc) and tech2077 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +void eeprom_erase(uint32_t addr); +void eeprom_read(void *buf, uint32_t addr, size_t len); +void eeprom_write(const void *buf, uint32_t addr, size_t len); + +/* + The slave select pin of the EEPROM. + This needs to be a normal GPIO pin_t value, such as A7. +*/ +#ifndef EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN +# error "No chip select pin defined -- missing EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN" +#endif + +/* + The clock divisor for SPI to ensure that the MCU is within the + specifications of the EEPROM chip. Generally this will be PCLK divided by + the intended divisor -- check your clock settings and the datasheet of + your EEPROM. +*/ +#ifndef EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR +# ifdef __AVR__ +# define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 8 +# else +# define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 64 +# endif +#endif + +/* + The SPI mode to communicate with the EEPROM. +*/ +#ifndef EXTERNAL_EEPROM_SPI_MODE +# define EXTERNAL_EEPROM_SPI_MODE 0 +#endif + +/* + Whether or not the SPI communication between the MCU and EEPROM should be + LSB-first. +*/ +#ifndef EXTERNAL_EEPROM_SPI_LSBFIRST +# define EXTERNAL_EEPROM_SPI_LSBFIRST false +#endif + +/* + The total size of the EEPROM, in bytes. The EEPROM datasheet will usually + specify this value in kbits, and will require conversion to bytes. +*/ +#ifndef EXTERNAL_EEPROM_BYTE_COUNT +# define EXTERNAL_EEPROM_BYTE_COUNT 8192 +#endif + +/* + The page size in bytes of the EEPROM, as specified in the datasheet. +*/ +#ifndef EXTERNAL_EEPROM_PAGE_SIZE +# define EXTERNAL_EEPROM_PAGE_SIZE 32 +#endif + +/* + The address size in bytes of the EEPROM. For EEPROMs with <=256 bytes, this + will likely be 1. For EEPROMs >256 and <=65536, this will be 2. For EEPROMs + >65536, this will likely need to be 4. + + As expected, consult the datasheet for specifics of your EEPROM. +*/ +#ifndef EXTERNAL_EEPROM_ADDRESS_SIZE +# define EXTERNAL_EEPROM_ADDRESS_SIZE 2 +#endif \ No newline at end of file diff --git a/keyboards/annepro2/keymaps/tech2077/keymap.c b/keyboards/annepro2/keymaps/tech2077/keymap.c new file mode 100644 index 000000000000..a3f238dbd01f --- /dev/null +++ b/keyboards/annepro2/keymaps/tech2077/keymap.c @@ -0,0 +1,206 @@ +#include "annepro2.h" +#include +#include +#include +#include "qmk_ap2_led.h" +#include "eeprom_w25x20cl.h" + +// layout using eeprom and bidir-comms to keep user led settings persistent + +// eeprom memory layout +typedef union { + uint32_t raw; + struct { + uint8_t magic : 8; + bool leds_on : 1; + uint8_t leds_profile : 8; + }; +} user_config_t; + +// define out default user_config +user_config_t user_config = {.magic = 0xDE, .leds_on = 0, .leds_profile = 0}; + +// keep the number of profiles so we can track along with the shine proc +uint8_t numProfiles = 0; + +static uint8_t usb_buf[256]; +static uint8_t buf_fil = 0; + +enum anne_pro_layers { + _BASE_LAYER, + _FN1_LAYER, + _FN2_LAYER, +}; + +/* +* 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 | GUI | Alt | space | GUI | ALT | FN1 | Ctrl | +* \-----------------------------------------------------------------------------------------/ +* Layer TAP in _BASE_LAYER +* ,-----------------------------------------------------------------------------------------. +* | | | | | | | | | | | | | | | +* |-----------------------------------------------------------------------------------------+ +* | | | | | | | | | | | | | | | +* |-----------------------------------------------------------------------------------------+ +* | | | | | | | | | | | | | | +* |-----------------------------------------------------------------------------------------+ +* | | | | | | | | | | | | UP | +* |-----------------------------------------------------------------------------------------+ +* | | | | | | LEFT | DOWN | RIGHT | +* \-----------------------------------------------------------------------------------------/ +*/ +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_BASE_LAYER] = KEYMAP(/* 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, + 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_LALT, KC_LGUI, KC_SPC, KC_RGUI, LT(KC_RALT, KC_LEFT), LT(_FN1_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 | FN2 | FN1 | Ctrl | + * \-----------------------------------------------------------------------------------------/ + * + */ + [_FN1_LAYER] = KEYMAP(/* 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, + MO(_FN2_LAYER), 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, MO(_FN2_LAYER), KC_TRNS, 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 | FN2 | FN1 | Ctrl | + * \-----------------------------------------------------------------------------------------/ + * + */ + [_FN2_LAYER] = KEYMAP(/* 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_PROFILE, KC_TRNS, 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(_FN2_LAYER), MO(_FN1_LAYER), KC_TRNS), +}; +const uint16_t keymaps_size = sizeof(keymaps); + +void matrix_init_user(void) +{ +} + +void matrix_scan_user(void) +{ +} + +layer_state_t layer_state_set_user(layer_state_t layer) +{ + return layer; +} + +void raw_hid_receive(uint8_t *data, uint8_t length) { + uprintf("raw_hid len: %u\n", length); + if (length == 1) + annepro2LedSetProfile(data[0]); + else { + for (uint8_t i = 0; i < length; i++){ + usb_buf[buf_fil + i] = data[i]; + } + buf_fil += length; + if (buf_fil >= 211) { + sdWrite(&SD0, usb_buf, 211); + buf_fil = 0; + } +// for (int i = 0; i < length; i++) { +// sdPut(&SD0, data[i]); +// sdGet(&SD0); +// } + } +} + +/*! + * @returns false processing for this keycode has been completed. + */ +bool process_record_user(uint16_t keycode, keyrecord_t* record) +{ + switch (keycode) { + case KC_AP_LED_OFF: + if (record->event.pressed) { + user_config.leds_on = false; + eeprom_write((void*)&user_config, 0, sizeof(user_config_t)); + } + return false; + case KC_AP_LED_ON: + if (record->event.pressed) { + user_config.leds_on = true; + eeprom_write((void*)&user_config, 0, sizeof(user_config_t)); + } + return false; + case KC_AP_LED_NEXT_PROFILE: + if (record->event.pressed) { + user_config.leds_profile = (user_config.leds_profile + 1) % numProfiles; + annepro2LedSetProfile(user_config.leds_profile); + eeprom_write((void*)&user_config, 0, sizeof(user_config_t)); + } + return false; + default: + break; + } + return true; +} + +void keyboard_post_init_user(void) +{ + // Customize these values to desired behavior + debug_enable = true; + //debug_matrix = true; + //debug_keyboard=true; + //debug_mouse=true; + + // Read the user config from EEPROM + eeprom_read((void*)&user_config, 0, sizeof(user_config_t)); + + // initialize a new eeprom + if (user_config.magic != 0xDE) + { + user_config.magic = 0xDE; + user_config.leds_on = false; + user_config.leds_profile = 0; + eeprom_write((void*)&user_config, 0, sizeof(user_config_t)); + } + + numProfiles = annepro2LedGetNumProfiles(); + + if (user_config.leds_on) { + // send profile before so that we don't get a flicker on startup + annepro2LedSetProfile(user_config.leds_profile); + annepro2LedEnable(); + } else { + annepro2LedDisable(); + } +} \ No newline at end of file diff --git a/keyboards/annepro2/keymaps/tech2077/rules.mk b/keyboards/annepro2/keymaps/tech2077/rules.mk new file mode 100644 index 000000000000..59a7f53b85cf --- /dev/null +++ b/keyboards/annepro2/keymaps/tech2077/rules.mk @@ -0,0 +1,47 @@ +# Anne Pro 2 +SRC = \ + matrix.c \ + hardfault_handler.c \ + annepro2_ble.c \ + qmk_ap2_led.c + +LAYOUTS += + +# MCU +MCU = cortex-m0plus +ARMV = 6 +USE_FPU = no +MCU_FAMILY = HT32 +MCU_SERIES = HT32F523x2 +MCU_LDSCRIPT = HT32F52342_ANNEPRO2 +MCU_STARTUP = ht32f523x2 + +BOARD = ANNEPRO2_C18 + +OPT_DEFS = -Wno-unused-function -fdump-rtl-dfinish -fstack-usage +#EXTRALDFLAGS = -Wl,--print-memory-usage + +# Options + +# Keys +CUSTOM_MATRIX = yes +NKRO_ENABLE = no +MOUSEKEY_ENABLE = no +EXTRAKEY_ENABLE = yes +KEY_LOCK_ENABLE = no + +# Other featues +BOOTMAGIC_ENABLE = no +CONSOLE_ENABLE = yes +COMMAND_ENABLE = yes +DEBUG_EEPROM = yes +RAW_ENABLE = no +MIDI_ENABLE = no +VIRTSER_ENABLE = no +COMBO_ENABLE = no +ANNEPRO2_EEPROM = yes + +ifeq ($(strip $(ANNEPRO2_EEPROM)), yes) + OPT_DEFS += -DANNEPRO2_EEPROM + SRC += spi_master.c eeprom_w25x20cl.c +endif \ No newline at end of file