[Keyboard] MechWild Puckbuddy (#17161)

* Initial commit

* testing modes

* working on puckbuddy firmware. This is all working for now but need to clean it up and personalize it.

* needs to be updated from vial build

* prepping for PR

* added rgb mode cycling to fn1 since it isn't on the encoder for these maps

* readme written in preparation for pr

* reverting driver print line

* Removed old reference to OBE in the readme from copypaste error

* applying changes based on review

* applying changes from review

* Update keyboards/mechwild/puckbuddy/puckbuddy.c

* trailing whitespaces removed

* added clear screen condition for switching back to name rendering

* Added uf2 keymap and fixed display glitch for the logo render art.

* Removed extra definition of FEE_PAGE_BASE_ADDRESS

* Removed the uf2 keymap and made it automatic when selecting bootloader instead

* Fixed the bad bootloader check

* moved the uf2 check from rules.mk to post_rules.mk to satisfy lint

* changing it back to stm32-dfu bootloader default

* Fixed RGBLIGHT enable oversight.

* Added persistent dynamic tapping configuration for the cirque touchpad tap term

* new lines at end of files for formatting and diff sanity

* changing default bootloader back to stm32-dfu

* Had to completely redefine the tap keycodes instead of using the DT_UP and DT_DOWN keycodes because I was not able to specify them easily in the via/vial configs and this allows me to keep the original functionality instead of tying it to eeprom like these are.

* Added tap toggling keycodes to quick enable and disable the tapping term

* working out an issue where the tap status keeps turning to off on power cycle

* correcting submodule garbo

* Fixed display issue and rewrote TAP config approach to make it a little easier to control

* removing backup puckbuddy.c code

* Added some comment, removed some commented out old code, removed trailing whitespace

* Changed to handle tinyuf2 by expecting emulated eeprom so that adding other forms of eeprom can be handled for the memory offset separately, and added user oled conditional inside the keyboard oled code block

* Updated default keymaps to have the tap and dpi keys on by default

* Apply suggestions from code review

* Apply suggestions from code review
This commit is contained in:
Kyle McCreery 2022-08-09 20:23:44 -04:00 committed by GitHub
parent 94b3efe92e
commit 7019d0bce8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 1081 additions and 0 deletions

View file

@ -0,0 +1,159 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0x6D77 // mw = "MechWild"
#define PRODUCT_ID 0x170F
#define DEVICE_VER 0x0100
#define MANUFACTURER MechWild
#define PRODUCT PuckBuddy
/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 4
#ifdef UF2_BUILD
#define EXTERNAL_EEPROM_BYTE_COUNT 2048
#define EXTERNAL_EEPROM_PAGE_SIZE 128
#define EXTERNAL_EEPROM_ADDRESS_SIZE 1
#define EXTERNAL_EEPROM_WRITE_TIME 0
#define FEE_PAGE_BASE_ADDRESS 0x08008000
#endif
/* Define custom font */
#define OLED_FONT_H "keyboards/mechwild/puckbuddy/glcdfont.c"
/* allows the "key" button on the blackpill to toggle caps lock for user testing before soldering */
#define DIP_SWITCH_PINS { A0 }
/* status light pins using the on board LED for the blackpill */
#define LED_CAPS_LOCK_PIN C13
#define LED_PIN_ON_STATE 0
/* set the tapping term for glidepoint pad to register a tap click */
//#define CIRQUE_PINNACLE_TAPPING_TERM 0 // This is set to 0 to disable it
/* TAPPING_TERM value is used for the CIRQUE_PINNACLE_TAPPING_TERM as well by default
* defining it this way allows us to easily modify it with DYNAMIC_TAPPING_TERM_ENABLE
*/
#define TAPPING_TERM 0
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { B12, B13, B14, B15 }
#define MATRIX_COL_PINS { B10, A8, B4, B5 }
#define UNUSED_PINS
/* spi config */
#define SPI_DRIVER SPID1
#define SPI_SCK_PIN A5
#define SPI_SCK_PAL_MODE 5
#define SPI_MOSI_PIN A7
#define SPI_MOSI_PAL_MODE 5
#define SPI_MISO_PIN A6
#define SPI_MISO_PAL_MODE 5
#define CIRQUE_PINNACLE_SPI_DIVISOR 8
#define CIRQUE_PINNACLE_SPI_CS_PIN A4
/* encoder pins */
#define ENCODERS_PAD_A { B1, B3 }
#define ENCODERS_PAD_B { B0, A15 }
/* encoder resolution */
#define ENCODER_RESOLUTION 4
#define TAP_CODE_DELAY 10
/* COL2ROW, ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* RGB settings, uncomment this define to enable RGB */
#define RGB_DI_PIN A3
#ifdef RGB_DI_PIN
# define RGBLED_NUM 3
# define RGBLIGHT_HUE_STEP 8
# define RGBLIGHT_SAT_STEP 8
# define RGBLIGHT_VAL_STEP 8
# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
# define RGBLIGHT_EFFECT_BREATHING
# define RGBLIGHT_EFFECT_RAINBOW_MOOD
# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
# define RGBLIGHT_EFFECT_SNAKE
# define RGBLIGHT_EFFECT_KNIGHT
# define RGBLIGHT_EFFECT_CHRISTMAS
# define RGBLIGHT_EFFECT_STATIC_GRADIENT
# define RGBLIGHT_EFFECT_RGB_TEST
# define RGBLIGHT_EFFECT_ALTERNATING
/*== customize breathing effect ==*/
/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
/*==== use exp() and sin() ====*/
//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
#endif
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
* This is useful for the Windows task manager shortcut (ctrl+shift+esc).
*/
//#define GRAVE_ESC_CTRL_OVERRIDE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
/* Bootmagic Lite key configuration */
//#define BOOTMAGIC_LITE_ROW 0
//#define BOOTMAGIC_LITE_COLUMN 0

View file

@ -0,0 +1,231 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "progmem.h"
const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0,
0x78, 0x1C, 0x0E, 0x06, 0x06, 0x06,
0x06, 0x06, 0x0E, 0x0C, 0x0C, 0x18,
0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x0E, 0x1C,
0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x78, 0x1E, 0x00,
0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0xE0, 0xFE, 0xFF,
0xFE, 0xF8, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xFC, 0xFF, 0xFE,
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x3E,
0xE0, 0x80, 0x70, 0x0E, 0x01, 0x00,
0x00, 0x00, 0x00, 0x07, 0x3C, 0xE0,
0x80, 0x78, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x70, 0x30, 0x30, 0x30, 0xB0, 0xF0,
0xF0, 0x00, 0xFE, 0xFF, 0x33, 0x31,
0x31, 0x31, 0x31, 0x31, 0x31, 0x33,
0x3F, 0x1C, 0x00, 0x00, 0x00, 0x00,
0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x08, 0x0C, 0x0E, 0x07,
0x03, 0x03, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0xF8, 0xFE, 0x0F,
0x07, 0x03, 0x03, 0x03, 0x03, 0x02,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xE0, 0xF0, 0x38, 0x1F, 0x0F, 0x00,
0x00, 0x00, 0x80, 0xE0, 0x70, 0x38,
0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0xC0, 0xF0, 0xFC, 0x7E, 0x4E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x1F,
0x07, 0x1F, 0xFF, 0xFE, 0xF0, 0xC0,
0xF8, 0xFF, 0x7F, 0x0F, 0x07, 0x7F,
0xFF, 0xFE, 0xFC, 0x04, 0x04, 0x78,
0x80, 0x00, 0x00, 0x00, 0xC0, 0x38,
0x0C, 0x1C, 0x60, 0x80, 0x00, 0x00,
0x00, 0xF0, 0x0C, 0x04, 0xF4, 0x1C,
0x80, 0xC0, 0xFC, 0xE6, 0xC3, 0xC1,
0xC1, 0xC3, 0xE6, 0xFC, 0xC0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x06, 0x0E, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0E, 0x07, 0x03,
0x00, 0x00, 0x01, 0x03, 0x07, 0x06,
0x0E, 0x0C, 0x0C, 0x0C, 0x06, 0x06,
0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1F, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x07, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x06, 0x07, 0x03, 0x1F, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x03, 0x06,
0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x06,
0x06, 0x00, 0x00, 0x00, 0x1F, 0x1F,
0x00, 0x01, 0x07, 0x0E, 0x18, 0x10,
0x00, 0x00, 0x07, 0x1F, 0x18, 0x30,
0x30, 0x30, 0x30, 0x1F, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x3C, 0x1C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1F, 0x1F, 0x1F, 0x07, 0x00,
0x00, 0x00, 0x00, 0x03, 0x1F, 0x1F,
0x0F, 0x01, 0x00, 0x00, 0x00, 0x00,
0x07, 0x1F, 0x1F, 0x1E, 0xF8, 0x00,
0x0F, 0x70, 0x30, 0x0E, 0xC1, 0x38,
0x07, 0x0E, 0x70, 0x83, 0x1C, 0x60,
0x1E, 0x03, 0xC0, 0x3E, 0x01, 0x00,
0x3F, 0x7F, 0xFF, 0xFF, 0xF9, 0xC0,
0xC0, 0xF9, 0xFF, 0xFF, 0x7F, 0x3F,
};

View file

@ -0,0 +1,13 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define HAL_USE_I2C TRUE
#define HAL_USE_SPI TRUE
#define SPI_USE_WAIT TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#include_next <halconf.h>

View file

@ -0,0 +1,25 @@
{
"keyboard_name": "MechWild PuckBuddy",
"url": "mechwild.com",
"maintainer": "kylemccreery",
"layouts": {
"LAYOUT": {
"layout": [
{"label":"k00", "x":0, "y":0},
{"label":"k01", "x":1.5, "y":0},
{"label":"k02", "x":2.5, "y":0},
{"label":"k03", "x":3.5, "y":0},
{"label":"k05", "x":5, "y":0},
{"label":"k10", "x":0, "y":1.25},
{"label":"k15", "x":5, "y":1.25},
{"label":"k20", "x":0, "y":2.25},
{"label":"k25", "x":5, "y":2.25},
{"label":"k30", "x":0, "y":3.25},
{"label":"k35", "x":5, "y":3.25},
{"label":"k31", "x":1, "y":4.5},
{"label":"k32", "x":2, "y":4.5},
{"label":"k33", "x":3, "y":4.5},
{"label":"k34", "x":4, "y":4.5}]
}
}
}

View file

@ -0,0 +1,64 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap
enum layer_names {
_BASE,
_FN1,
_FN2,
_FN3
};
/* Physical Layout:
* /-------------------\
* |ENC| 1 | 2 | 3 |ENC|
* |---+---'---'---+---|
* | 4 | | 5 |
* |---| |---|
* | 6 | | 7 |
* |---| |---|
* | 8 | | 9 |
* \-----,---,---,-----/
* | A | B | C | D |
* \---'---'---'---/
*
* Keymap Layout:
* ENC, 1, 2, 3, ENC,
* 4, 5,
* 6, 7,
* 8, A, B, C, D, 9,
*
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_MUTE, MO(_FN3), MO(_FN2), MO(_FN1), LGUI(KC_D),
MO(_FN2), KC_HOME,
MO(_FN3), KC_END,
KC_BTN3, DPI_FINE,
KC_BTN1, KC_BTN2, KC_BTN2, KC_BTN1
),
[_FN1] = LAYOUT(
RGB_TOG, KC_TRNS, KC_TRNS, KC_TRNS, TAP_TOG,
DPI_UP, TAP_UP,
DPI_DN, TAP_DN,
KC_TRNS, KC_TRNS,
KC_HOME, KC_PGUP, KC_PGDN, KC_END
),
[_FN2] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG,
KC_TRNS, RGB_MOD,
KC_TRNS, RGB_RMOD,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
),
[_FN3] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
)
};

View file

@ -0,0 +1,64 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap
enum layer_names {
_BASE,
_FN1,
_FN2,
_FN3
};
/* Physical Layout:
* /-------------------\
* |ENC| 1 | 2 | 3 |ENC|
* |---+---'---'---+---|
* | 4 | | 5 |
* |---| |---|
* | 6 | | 7 |
* |---| |---|
* | 8 | | 9 |
* \-----,---,---,-----/
* | A | B | C | D |
* \---'---'---'---/
*
* Keymap Layout:
* ENC, 1, 2, 3, ENC,
* 4, 5,
* 6, 7,
* 8, A, B, C, D, 9,
*
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_MUTE, MO(_FN3), MO(_FN2), MO(_FN1), LGUI(KC_D),
MO(_FN2), KC_HOME,
MO(_FN3), KC_END,
KC_BTN3, DPI_FINE,
KC_BTN1, KC_BTN2, KC_BTN2, KC_BTN1
),
[_FN1] = LAYOUT(
RGB_TOG, KC_TRNS, KC_TRNS, KC_TRNS, TAP_TOG,
DPI_UP, TAP_UP,
DPI_DN, TAP_DN,
KC_TRNS, KC_TRNS,
KC_HOME, KC_PGUP, KC_PGDN, KC_END
),
[_FN2] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG,
KC_TRNS, RGB_MOD,
KC_TRNS, RGB_RMOD,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
),
[_FN3] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
)
};

View file

@ -0,0 +1 @@
VIA_ENABLE = yes

View file

@ -0,0 +1,88 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* STM32F401xE memory setup.
*/
MEMORY
{
flash0 (rx) : org = 0x08000000, len = 16k /* tinyuf2 bootloader requires app to be located at 64k offset for this MCU */
flash1 (rx) : org = 0x08004000, len = 16k
flash2 (rx) : org = 0x08008000, len = 16k /* emulated eeprom */
flash3 (rx) : org = 0x0800C000, len = 16k
flash4 (rx) : org = 0x08010000, len = 512k - 64k
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 96k
ram1 (wx) : org = 0x00000000, len = 0
ram2 (wx) : org = 0x00000000, len = 0
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x00000000, len = 0
ram5 (wx) : org = 0x00000000, len = 0
ram6 (wx) : org = 0x00000000, len = 0
ram7 (wx) : 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", flash4);
REGION_ALIAS("VECTORS_FLASH_LMA", flash4);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash4);
REGION_ALIAS("XTORS_FLASH_LMA", flash4);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash4);
REGION_ALIAS("TEXT_FLASH_LMA", flash4);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash4);
REGION_ALIAS("RODATA_FLASH_LMA", flash4);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash4);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash4);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash4);
/* 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", flash4);
/* 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
/* TinyUF2 bootloader reset support */
_board_dfu_dbl_tap = ORIGIN(ram0) + 64k - 4; /* this is based off the linker file for tinyuf2 */

View file

@ -0,0 +1,12 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include_next <mcuconf.h>
#undef STM32_I2C_USE_I2C1
#define STM32_I2C_USE_I2C1 TRUE
#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE

View file

@ -0,0 +1,7 @@
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
ifndef EEPROM_DRIVER
MCU_LDSCRIPT = STM32F401xE
EEPROM_DRIVER = vendor
UF2_BUILD = yes
endif
endif

View file

@ -0,0 +1,307 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "puckbuddy.h"
#ifndef GLIDEPOINT_DPI_OPTIONS
# define GLIDEPOINT_DPI_OPTIONS \
{ 400, 800, 1200, 1600, 2000, 2400, 2800, 3200, 3600, 4000 }
# ifndef GLIDEPOINT_DPI_DEFAULT
# define GLIDEPOINT_DPI_DEFAULT 1
# endif
#endif
#ifndef GLIDEPOINT_DPI_DEFAULT
# define GLIDEPOINT_DPI_DEFAULT 1
#endif
keyboard_config_t keyboard_config;
uint16_t dpi_array[] = GLIDEPOINT_DPI_OPTIONS;
#define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t))
void board_init(void) {
// B9 is configured as I2C1_SDA in the board file; that function must be
// disabled before using B7 as I2C1_SDA.
setPinInputHigh(B9);
}
#ifdef DYNAMIC_TAPPING_TERM_ENABLE
void tap_modify(int change_value, bool tap_status) {
if (keyboard_config.dt_term_config < 0) {
keyboard_config.dt_term_config *= -1;
}
keyboard_config.dt_term_config += change_value;
if (tap_status == false ) {
keyboard_config.dt_term_config *= -1;
g_tapping_term = 0;
} else {
g_tapping_term = keyboard_config.dt_term_config;
}
eeconfig_update_kb(keyboard_config.raw);
}
void tap_toggle(void) {
keyboard_config.dt_term_config *= -1;
if (keyboard_config.dt_term_config > 0) {
g_tapping_term = keyboard_config.dt_term_config;
} else {
g_tapping_term = 0;
}
eeconfig_update_kb(keyboard_config.raw);
}
#endif
#ifdef DIP_SWITCH_ENABLE
bool dip_switch_update_kb(uint8_t index, bool active) {
if (!dip_switch_update_user(index, active)) { return false; }
switch (index) {
case 0:
if(active) { tap_code(KC_CLCK); }
break;
break;
}
return true;
}
#endif
#ifdef ENCODER_ENABLE
bool encoder_update_kb(uint8_t index, bool clockwise) {
if (!encoder_update_user(index, clockwise)) { return false; }
switch (index) {
case 0:
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
break;
case 1:
if (clockwise) {
tap_code(KC_PGUP);
} else {
tap_code(KC_PGDN);
}
break;
}
return true;
}
#endif
#ifdef OLED_ENABLE // OLED Functionality
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
return OLED_ROTATION_180; // flips the display 180 degrees
}
bool clear_screen = true; // used to manage singular screen clears to prevent display glitch
bool clear_screen_art = true; // used to manage singular screen clears to prevent display glitch
static void render_name(void) { // Render Puckbuddy "Get Puck'd" text
static const char PROGMEM name_1[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0xB6, 0xB6, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x00};
static const char PROGMEM name_2[] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xB6, 0xB6, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0x00};
static const char PROGMEM name_3[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xB6, 0xB6, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0x00};
oled_set_cursor(0,0);
oled_write_P(name_1, false);
oled_set_cursor(0,1);
oled_write_P(name_2, false);
oled_set_cursor(0,2);
oled_write_P(name_3, false);
}
static void render_logo(void) { // Render MechWild "MW" Logo
static const char PROGMEM logo_1[] = {0x97, 0x98, 0x99, 0x9A,0x00};
static const char PROGMEM logo_2[] = {0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0x00};
static const char PROGMEM logo_3[] = {0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xB6, 0x00};
static const char PROGMEM logo_4[] = {0xB6, 0xB6, 0xB6, 0x9B, 0x9C, 0x9D, 0x9E, 0x00};
oled_set_cursor(0,0);
oled_write_P(logo_1, false);
oled_set_cursor(0,1);
oled_write_P(logo_2, false);
oled_set_cursor(0,2);
oled_write_P(logo_3, false);
oled_set_cursor(0,3);
oled_write_P(logo_4, false);
}
bool oled_task_kb(void) {
if(!oled_task_user()) {
return false;
}
if ( IS_HOST_LED_OFF(USB_LED_NUM_LOCK) && IS_HOST_LED_OFF(USB_LED_CAPS_LOCK) && IS_HOST_LED_OFF(USB_LED_SCROLL_LOCK) && get_highest_layer(layer_state) == 0 ) {
if (clear_screen_art == true) {
oled_clear();
oled_render();
clear_screen_art = false;
}
render_name();
oled_set_cursor(0,3);
#ifdef POINTING_DEVICE_ENABLE
oled_write_P(PSTR(" DPI:"), false);
oled_write(get_u16_str(dpi_array[keyboard_config.dpi_config], ' '), false);
#endif
#ifdef DYNAMIC_TAPPING_TERM_ENABLE // only display tap info if it is being configured dynamically
oled_write_P(PSTR(" TAP:"), false);
if (keyboard_config.dt_term_config < 0) {
oled_write_P(PSTR("Off "), false);
} else {
oled_write(get_u16_str(g_tapping_term, ' '), false);
}
#endif
clear_screen = true;
} else {
if (clear_screen == true) {
oled_clear();
oled_render();
clear_screen = false;
}
render_logo();
oled_set_cursor(8,1);
switch (get_highest_layer(layer_state)) {
case 0:
oled_write_P(PSTR("Layer 0"), false);
break;
case 1:
oled_write_P(PSTR("Layer 1"), false);
break;
case 2:
oled_write_P(PSTR("Layer 2"), false);
break;
case 3:
oled_write_P(PSTR("Layer 3"), false);
break;
default:
oled_write_P(PSTR("Layer ?"), false); // Should never display, here as a catchall
}
led_t led_state = host_keyboard_led_state();
oled_set_cursor(8,0);
oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
oled_write_P(led_state.scroll_lock ? PSTR("SCR") : PSTR(" "), false);
#ifdef POINTING_DEVICE_ENABLE
oled_set_cursor(8,2);
oled_write_P(PSTR("DPI:"), false);
oled_write(get_u16_str(dpi_array[keyboard_config.dpi_config], ' '), false);
#endif
#ifdef DYNAMIC_TAPPING_TERM_ENABLE // only display tap info if it is being configured dynamically
oled_set_cursor(8,3);
oled_write_P(PSTR("TAP:"), false);
if (keyboard_config.dt_term_config < 0) {
oled_write_P(PSTR("Off "), false);
} else {
oled_write(get_u16_str(g_tapping_term, ' '), false);
}
#endif
clear_screen_art = true;
}
return true;
}
#endif
bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
switch(keycode) {
#ifdef POINTING_DEVICE_ENABLE
case DPI_UP:
if (record->event.pressed) {
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE;
eeconfig_update_kb(keyboard_config.raw);
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
}
return false;
case DPI_DN:
if (record->event.pressed) {
if (keyboard_config.dpi_config > 0) {
keyboard_config.dpi_config = (keyboard_config.dpi_config - 1) % DPI_OPTION_SIZE;
} else {
keyboard_config.dpi_config = DPI_OPTION_SIZE - 1;
}
eeconfig_update_kb(keyboard_config.raw);
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
}
return false;
case DPI_FINE:
if (record->event.pressed) {
pointing_device_set_cpi(dpi_array[0]);
} else {
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
}
return false;
#endif
#ifdef DYNAMIC_TAPPING_TERM_ENABLE // only include tap info keycodes if it is being configured dynamically
case TAP_UP:
if (record->event.pressed) {
tap_modify(DYNAMIC_TAPPING_TERM_INCREMENT, true);
}
return false;
case TAP_DN:
if (record->event.pressed) {
if (keyboard_config.dt_term_config > 0) {
tap_modify(-1 * DYNAMIC_TAPPING_TERM_INCREMENT, true);
}
}
return false;
case TAP_ON:
if (record->event.pressed) {
tap_modify(0, true);
}
return false;
case TAP_OFF:
if (record->event.pressed) {
tap_modify(0, false);
}
return false;
case TAP_TOG:
if (record->event.pressed) {
tap_toggle();
}
return false;
#endif
}
return process_record_user(keycode, record);
}
void pointing_device_init_kb(void) {
#ifdef POINTING_DEVICE_ENABLE
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
#endif
}
void eeconfig_init_kb(void) {
#ifdef POINTING_DEVICE_ENABLE
keyboard_config.dpi_config = GLIDEPOINT_DPI_DEFAULT;
#endif
#ifdef DYNAMIC_TAPPING_TERM_ENABLE // only set tap term from eeprom if it is being configured dynamically
keyboard_config.dt_term_config = TAPPING_TERM;
#endif
eeconfig_update_kb(keyboard_config.raw);
eeconfig_init_user();
}
void matrix_init_kb(void) {
// is safe to just read DPI setting since matrix init
// comes before pointing device init.
keyboard_config.raw = eeconfig_read_kb();
#ifdef POINTING_DEVICE_ENABLE
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) {
eeconfig_init_kb();
}
#endif
matrix_init_user();
}
void keyboard_post_init_kb(void) {
#ifdef POINTING_DEVICE_ENABLE
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
#endif
#ifdef RGBLIGHT_ENABLE
rgblight_toggle_noeeprom(); //double toggle post init removes the weirdness with rgb strips having a yellow first LED
rgblight_toggle_noeeprom();
#endif
#ifdef DYNAMIC_TAPPING_TERM_ENABLE
tap_toggle(); // Need it to reevaluate this setting after initiating so that it is current after init
tap_toggle();
#endif
keyboard_post_init_user();
#ifdef OLED_ENABLE // purposefully after user post init to allow the RGB to startup first
wait_ms(200); // Avoids a startup issue where the oled renders and then turns off with blackpill
oled_on();
#endif
}

View file

@ -0,0 +1,56 @@
// Copyright 2022 Kyle McCreery (@kylemccreery)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
#define ___ KC_NO
/* This is a shortcut to help you visually see your layout.
*
* The first section contains all of the arguments representing the physical
* layout of the board and position of the keys.
*
* The second converts the arguments into a two-dimensional array which
* represents the switch matrix.
*/
#define LAYOUT( \
k00, k01, k02, k03, k05,\
k10, k15,\
k20, k25,\
k30, k35,\
k31, k32, k33, k34 \
) { \
{ k00, k01, k05, k31 }, \
{ k10, k02, k15, k32 }, \
{ k20, k03, k25, k33 }, \
{ k30, ___, k35, k34 } \
}
typedef union {
uint32_t raw;
struct {
uint8_t dpi_config;
int16_t dt_term_config;
};
} keyboard_config_t;
extern keyboard_config_t keyboard_config;
extern uint16_t dpi_array[];
enum keyboard_keycodes {
#ifdef VIA_ENABLE
DPI_UP = USER00,
#else
DPI_UP = SAFE_RANGE,
#endif
DPI_DN,
DPI_FINE,
TAP_UP,
TAP_DN,
TAP_ON,
TAP_OFF,
TAP_TOG,
NEW_SAFE_RANGE
};

View file

@ -0,0 +1,27 @@
# PuckBuddy
![PuckBuddy](https://i.imgur.com/iSVAHJzh.png)
A macropad with a Cirque Glidepoint Trackpad in the middle, powered by the STM32 Blackpill.
* Keyboard Maintainer: [Kyle McCreery](https://github.com/kylemccreery)
* Hardware Supported: PuckBuddy v1.0
* Hardware Availability: [PuckBuddy on MechWild](https://mechwild.com/product/puckbuddy/)
Make example for this keyboard (after setting up your build environment):
make mechwild/puckbuddy:default
Flashing example for this keyboard:
make mechwild/puckbuddy:default:flash
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (assigned to the top left key) and plug in the keyboard while holding it.
* **Physical reset button**: Press and hold the boot0 button on the blackpill, tap and release the nrst button on the blackpill, then release the boot0 button.
* **Keycode in layout**: Press the key mapped to `RESET` if it is available. By default this is the top right key on layer 1.
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).

View file

@ -0,0 +1,27 @@
# MCU name
MCU = STM32F401
# Bootloader selection
BOOTLOADER = stm32-dfu
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = no # Enable N-Key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
ENCODER_ENABLE = yes # Encoder Enabled
OLED_ENABLE = yes # OLED Enabled
OLED_DRIVER = SSD1306 # OLED Driver
DIP_SWITCH_ENABLE = yes # Dip Switch Enabled
POINTING_DEVICE_ENABLE = yes # Pointing Device Enabled
POINTING_DEVICE_DRIVER = cirque_pinnacle_spi # Pointing Device Driver
DYNAMIC_TAPPING_TERM_ENABLE = yes # Enable Dynamic Tapping Term to control the Tap term for the Cirque Pad easily