summary refs log tree commit diff
diff options
context:
space:
mode:
authorQMK Bot <hello@qmk.fm>2022-08-10 00:24:17 +0000
committerQMK Bot <hello@qmk.fm>2022-08-10 00:24:17 +0000
commit9bbc0cbb3bcd32a5eb56aa2310fc09802256eccb (patch)
treea92e3913bc9a1d9100c8f3448d3c8e76e10d57aa
parent994a2542af324aef44a515effc9e51999b4fefe8 (diff)
parent7019d0bce890ca97937d62e843adcdc9b9a0d1fd (diff)
Merge remote-tracking branch 'origin/master' into develop
-rw-r--r--keyboards/mechwild/puckbuddy/config.h159
-rw-r--r--keyboards/mechwild/puckbuddy/glcdfont.c231
-rw-r--r--keyboards/mechwild/puckbuddy/halconf.h13
-rw-r--r--keyboards/mechwild/puckbuddy/info.json25
-rw-r--r--keyboards/mechwild/puckbuddy/keymaps/default/keymap.c64
-rw-r--r--keyboards/mechwild/puckbuddy/keymaps/via/keymap.c64
-rw-r--r--keyboards/mechwild/puckbuddy/keymaps/via/rules.mk1
-rw-r--r--keyboards/mechwild/puckbuddy/ld/STM32F401xE.ld88
-rw-r--r--keyboards/mechwild/puckbuddy/mcuconf.h12
-rw-r--r--keyboards/mechwild/puckbuddy/post_rules.mk7
-rw-r--r--keyboards/mechwild/puckbuddy/puckbuddy.c307
-rw-r--r--keyboards/mechwild/puckbuddy/puckbuddy.h56
-rw-r--r--keyboards/mechwild/puckbuddy/readme.md27
-rw-r--r--keyboards/mechwild/puckbuddy/rules.mk27
14 files changed, 1081 insertions, 0 deletions
diff --git a/keyboards/mechwild/puckbuddy/config.h b/keyboards/mechwild/puckbuddy/config.h
new file mode 100644
index 0000000000..fac68071bb
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/config.h
@@ -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
diff --git a/keyboards/mechwild/puckbuddy/glcdfont.c b/keyboards/mechwild/puckbuddy/glcdfont.c
new file mode 100644
index 0000000000..942f81dd06
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/glcdfont.c
@@ -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,
+};
diff --git a/keyboards/mechwild/puckbuddy/halconf.h b/keyboards/mechwild/puckbuddy/halconf.h
new file mode 100644
index 0000000000..07e8cdd17b
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/halconf.h
@@ -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>
diff --git a/keyboards/mechwild/puckbuddy/info.json b/keyboards/mechwild/puckbuddy/info.json
new file mode 100644
index 0000000000..2bba4ba506
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/info.json
@@ -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}]
+        }
+    }
+}
diff --git a/keyboards/mechwild/puckbuddy/keymaps/default/keymap.c b/keyboards/mechwild/puckbuddy/keymaps/default/keymap.c
new file mode 100644
index 0000000000..9c7dabcc6a
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/keymaps/default/keymap.c
@@ -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
+    )
+};
diff --git a/keyboards/mechwild/puckbuddy/keymaps/via/keymap.c b/keyboards/mechwild/puckbuddy/keymaps/via/keymap.c
new file mode 100644
index 0000000000..9c7dabcc6a
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/keymaps/via/keymap.c
@@ -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
+    )
+};
diff --git a/keyboards/mechwild/puckbuddy/keymaps/via/rules.mk b/keyboards/mechwild/puckbuddy/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/mechwild/puckbuddy/ld/STM32F401xE.ld b/keyboards/mechwild/puckbuddy/ld/STM32F401xE.ld
new file mode 100644
index 0000000000..daec7d8583
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/ld/STM32F401xE.ld
@@ -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 */
diff --git a/keyboards/mechwild/puckbuddy/mcuconf.h b/keyboards/mechwild/puckbuddy/mcuconf.h
new file mode 100644
index 0000000000..f71868d78e
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/mcuconf.h
@@ -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
diff --git a/keyboards/mechwild/puckbuddy/post_rules.mk b/keyboards/mechwild/puckbuddy/post_rules.mk
new file mode 100644
index 0000000000..ac527500d2
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/post_rules.mk
@@ -0,0 +1,7 @@
+ifeq ($(strip $(BOOTLOADER)), tinyuf2)
+    ifndef EEPROM_DRIVER
+        MCU_LDSCRIPT = STM32F401xE
+        EEPROM_DRIVER = vendor
+        UF2_BUILD = yes
+    endif
+endif
\ No newline at end of file
diff --git a/keyboards/mechwild/puckbuddy/puckbuddy.c b/keyboards/mechwild/puckbuddy/puckbuddy.c
new file mode 100644
index 0000000000..b82d06f565
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/puckbuddy.c
@@ -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
+}
diff --git a/keyboards/mechwild/puckbuddy/puckbuddy.h b/keyboards/mechwild/puckbuddy/puckbuddy.h
new file mode 100644
index 0000000000..13540a5075
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/puckbuddy.h
@@ -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
+};
diff --git a/keyboards/mechwild/puckbuddy/readme.md b/keyboards/mechwild/puckbuddy/readme.md
new file mode 100644
index 0000000000..1663ad4b9c
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/readme.md
@@ -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).
\ No newline at end of file
diff --git a/keyboards/mechwild/puckbuddy/rules.mk b/keyboards/mechwild/puckbuddy/rules.mk
new file mode 100644
index 0000000000..b769932064
--- /dev/null
+++ b/keyboards/mechwild/puckbuddy/rules.mk
@@ -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