~ruther/qmk_firmware

6e48ea082dc27ac25bd0422e974cefe7a00788f6 — holtenc 6 years ago 681db53
[Keyboard] Initial commit for Prime_E w/ VIA config support (#5285)

* Initial Prime_E commit

* Via support for Prime_EXL

* Backlight testing

* update libs

* Clean up and addition of VIA compatibility.

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/primekb/prime_e/keymaps/default/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/primekb/prime_e/keymaps/default/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/primekb/prime_e/keymaps/default/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/handwired/prime_exl/keymaps/via/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* Update keyboards/primekb/prime_e/keymaps/default/keymap.c

Co-Authored-By: holtenc <holtenc@gmail.com>

* removed IS_COMMAND from config.h. updated GPIO commands

* clean up libs
M keyboards/handwired/prime_exl/config.h => keyboards/handwired/prime_exl/config.h +22 -2
@@ 20,8 20,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"

/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED
#define PRODUCT_ID      0x4024
#define VENDOR_ID       0x5052
#define PRODUCT_ID      0x6578
#define DEVICE_VER      0x0001
#define MANUFACTURER    PrimeKB
#define PRODUCT         Prime_EXL


@@ 49,3 49,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE

#define DYNAMIC_KEYMAP_LAYER_COUNT 4

// EEPROM usage

// TODO: refactor with new user EEPROM code (coming soon)
#define EEPROM_MAGIC 0x451F
#define EEPROM_MAGIC_ADDR 32
// Bump this every time we change what we store
// This will automatically reset the EEPROM with defaults
// and avoid loading invalid data from the EEPROM
#define EEPROM_VERSION 0x08
#define EEPROM_VERSION_ADDR 34

// Dynamic keymap starts after EEPROM version
#define DYNAMIC_KEYMAP_EEPROM_ADDR 35
// Dynamic macro starts after dynamic keymaps (35+(4*10*9*2)) = (35+720)
#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 755
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 269    // 1024-DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#define DYNAMIC_KEYMAP_MACRO_COUNT 16
\ No newline at end of file

M keyboards/handwired/prime_exl/keymaps/default/keymap.c => keyboards/handwired/prime_exl/keymaps/default/keymap.c +21 -21
@@ 37,7 37,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 					KC_TRNS,												KC_TRNS, 			KC_VOLD, 		KC_VOLU, 	KC_MUTE, 	KC_TRNS,
		BL_TOGG,	BL_STEP,		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS
    ),
	

		[2] = LAYOUT(
		KC_ESC, 		KC_1, 			KC_2, 			KC_3, 			KC_4, 			KC_F9, 				KC_ESC, 		KC_Q, 			KC_W, 		KC_E, 			KC_R, 		KC_T,				 		KC_Y, 			KC_U, 			KC_I, 			KC_O, 				KC_P, 			KC_BSPC,
		KC_TAB, 		KC_Q, 			KC_W, 		KC_E, 			KC_R, 			KC_T,					KC_TAB, 		KC_A, 			KC_S, 			KC_D, 			KC_F, 		KC_G,			 	 		KC_H, 			KC_J, 			KC_K, 			KC_L, 				KC_QUOT, 	KC_ENT,


@@ 45,7 45,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
		KC_LSFT,		KC_Z,			KC_X,			KC_C,			KC_V,			KC_B,					KC_LCTL, 	KC_LALT, 	KC_LBRC, 	KC_RBRC, 			MO(5),									KC_SPC, 					KC_MINS, 	KC_EQL, 		KC_LGUI, 	MO(4),
		KC_LCTL,		KC_LALT,	TO(0),			KC_P,			KC_H,			KC_SPC
    ),
	

		[3] = LAYOUT(
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 				KC_TRNS, 		KC_1, 				KC_2, 				KC_3, 				KC_4, 				KC_5,				 				KC_6, 			KC_7, 			KC_8, 			KC_9, 			KC_0, 			KC_TRNS,
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,			 	 		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,


@@ 53,7 53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 					KC_TRNS,												KC_TRNS, 			KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS
    ),
	

		[4] = LAYOUT(
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 				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_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,			 	 		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,


@@ 61,7 61,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 					KC_TRNS,												KC_TRNS, 			KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS
    ),
	

		[5] = LAYOUT(
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 				KC_GRV, 		KC_1, 				KC_2, 				KC_3, 				KC_4, 				KC_5,				 				KC_TRNS, 	KC_TRNS, 	KC_UP, 			KC_TRNS, 	KC_TRNS, 	KC_DEL,
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,				KC_CAPS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,			 	 		KC_TRNS, 	KC_LEFT, 	KC_DOWN, 	KC_RGHT, 	KC_SCLN, 	KC_BSLS,


@@ 96,14 96,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {

void matrix_init_user(void) {
  // set CapsLock LED to output and low
  DDRC |= (1 << 6);
  PORTC &= ~(1 << 6);
  setPinOutput(C6);
  writePinHigh(C6);
  // set NumLock LED to output and low
  DDRB |= (1 << 6);
  PORTB &= ~(1 << 6);
  setPinOutput(B6);
  writePinHigh(B6);
  // set ScrollLock LED to output and low
  DDRB |= (1 << 5);
  PORTB &= ~(1 << 5);
  setPinOutput(B5);
  writePinHigh(B5);
}

void matrix_scan_user(void) {


@@ 112,21 112,21 @@ void matrix_scan_user(void) {


void led_set_user(uint8_t usb_led) {
  if (usb_led & (1<<USB_LED_NUM_LOCK)) {
    PORTB |= (1<<6);
  if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
    writePinLow(B6);
  } else {
    PORTB &= ~(1<<6);
    writePinHigh(B6);
  }
  if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
    PORTB |= (1<<5);
  if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
    writePinLow(B5);
  } else {
    PORTB &= ~(1<<5);
    writePinHigh(B5);
  }
  /*
  if (usb_led & (1<<USB_LED_SCROLL_LOCK)) {
    PORTC |= (1<<6);
  if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
    writePinLow(C6);
  } else {
    PORTC &= ~(1<<6);
    writePinHigh(C6);
  }
  */
}


@@ 135,9 135,9 @@ void led_set_user(uint8_t usb_led) {
uint32_t layer_state_set_user(uint32_t state)
{
    if (biton32(state) == 2) {
        PORTC |= (1<<6);
    writePinLow(C6);
	} else {
		PORTC &= ~(1<<6);
		writePinHigh(C6);
    }
    return state;
}

A keyboards/handwired/prime_exl/keymaps/via/keymap.c => keyboards/handwired/prime_exl/keymaps/via/keymap.c +101 -0
@@ 0,0 1,101 @@
/* Copyright 2018 Holten Campbell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include QMK_KEYBOARD_H



const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    LAYOUT(
		KC_NLCK, 	KC_LPRN, 	KC_RPRN, 	KC_PSLS, 	KC_PAST, 	KC_BSPC, 				KC_ESC, 		KC_Q, 			KC_W, 		KC_E, 			KC_R, 		KC_T,				 		KC_Y, 			KC_U, 			KC_I, 			KC_O, 				KC_P, 			KC_BSPC,
		KC_F1, 		KC_F2, 		KC_P7, 		KC_P8, 		KC_P9, 		KC_DEL,					KC_TAB, 		KC_A, 			KC_S, 			KC_D, 			KC_F, 		KC_G,			 	 		KC_H, 			KC_J, 			KC_K, 			KC_L, 				KC_QUOT, 	KC_ENT,
		KC_F3,		KC_F4,		KC_P4,		KC_P5,		KC_P6,		KC_PMNS,				KC_LSFT, 	KC_Z, 			KC_X, 			KC_C, 			KC_V, 		KC_B,				 		MO(3), 		KC_N, 			KC_M, 		KC_COMM,	KC_DOT, 	KC_SLSH, 	KC_LSFT,
		KC_F5,		KC_F6,		KC_P1,		KC_P2,		KC_P3,		KC_PPLS,				KC_LCTL, 	KC_LALT, 	KC_LBRC, 	KC_RBRC, 			MO(2),									KC_SPC, 					KC_MINS, 	KC_EQL, 			KC_LGUI, 	MO(3),
		KC_F7,		KC_F8,		MO(1),		KC_PDOT,	KC_P0,		KC_PENT
    ),

	LAYOUT(
		KC_ESC, 	KC_1, 		KC_2, 		KC_3, 		KC_4, 		KC_F9, 					KC_ESC, 	KC_Q, 		KC_W, 		KC_E, 			KC_R, 		KC_T,				 		KC_Y, 		KC_U, 		KC_I, 		KC_O, 		KC_P, 		KC_BSPC,
		KC_TAB, 	KC_Q, 		KC_W, 		KC_E, 		KC_R, 		KC_T,					KC_TAB, 	KC_A, 		KC_S, 		KC_D, 			KC_F, 		KC_G,			 	 		KC_H, 		KC_J, 		KC_K, 		KC_L, 		KC_QUOT, 	KC_ENT,
		KC_TAB,		KC_A,		KC_S,		KC_D,		KC_F,		KC_G,					KC_LSFT, 	KC_Z, 		KC_X, 		KC_C, 			KC_V, 		KC_B,				 		MO(3), 		KC_N, 		KC_M, 		KC_COMM,	KC_DOT, 	KC_SLSH, 	KC_LSFT,
		KC_LSFT,	KC_Z,		KC_X,		KC_C,		KC_V,		KC_B,					KC_LCTL, 	KC_LALT, 	KC_LBRC, 	KC_RBRC, 		MO(2),									KC_SPC, 				KC_MINS, 	KC_EQL, 	KC_LGUI, 	MO(3),
		KC_LCTL,	KC_LALT,	TO(0),		KC_P,		KC_H,		KC_SPC
    ),

	LAYOUT(
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 				KC_GRV, 		KC_1, 				KC_2, 				KC_3, 				KC_4, 				KC_5,				 				KC_TRNS, 	KC_TRNS, 	KC_UP, 			KC_TRNS, 	KC_TRNS, 	KC_DEL,
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,				KC_CAPS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,			 	 		KC_TRNS, 	KC_LEFT, 	KC_DOWN, 	KC_RGHT, 	KC_SCLN, 	KC_BSLS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,				 		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 		KC_TRNS,	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 					KC_TRNS,												KC_TRNS, 			KC_VOLD, 		KC_VOLU, 	KC_MUTE, 	KC_TRNS,
		BL_TOGG,	BL_STEP,		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS
    ),

	LAYOUT(
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 				KC_TRNS, 		KC_1, 				KC_2, 				KC_3, 				KC_4, 				KC_5,				 				KC_6, 			KC_7, 			KC_8, 			KC_9, 			KC_0, 			KC_TRNS,
		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,			 	 		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS,				 		KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,				KC_TRNS, 		KC_TRNS, 		KC_TRNS, 		KC_TRNS, 					KC_TRNS,												KC_TRNS, 			KC_TRNS, 	KC_TRNS, 	KC_TRNS, 	KC_TRNS,
		KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS,	KC_TRNS
    )
};


void matrix_init_user(void) {
  // set CapsLock LED to output and low
  setPinOutput(C6);
  writePinHigh(C6);
  // set NumLock LED to output and low
  setPinOutput(B6);
  writePinHigh(B6);
  // set ScrollLock LED to output and low
  setPinOutput(B5);
  writePinHigh(B5);
}

void matrix_scan_user(void) {

}


void led_set_user(uint8_t usb_led) {
  if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
    writePinLow(B6);
  } else {
    writePinHigh(B6);
  }
  if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
    writePinLow(B5);
  } else {
    writePinHigh(B5);
  }
  /*
  if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
    writePinLow(C6);
  } else {
    writePinHigh(C6);
  }
  */
}

//function for layer indicator LED
uint32_t layer_state_set_user(uint32_t state)
{
    if (biton32(state) == 2) {
    writePinLow(C6);
	} else {
		writePinHigh(C6);
    }
    return state;
}

A keyboards/handwired/prime_exl/keymaps/via/readme.md => keyboards/handwired/prime_exl/keymaps/via/readme.md +1 -0
@@ 0,0 1,1 @@
# The default keymap for prime_exl
\ No newline at end of file

A keyboards/handwired/prime_exl/keymaps/via/rules.mk => keyboards/handwired/prime_exl/keymaps/via/rules.mk +86 -0
@@ 0,0 1,86 @@
# MCU name
MCU = atmega32u4

# Processor frequency.
#     This will define a symbol, F_CPU, in all source code files equal to the
#     processor frequency in Hz. You can then use this symbol in your source code to
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
#
#     This will be an integer division of F_USB below, as it is sourced by
#     F_USB after it has run through any CPU prescalers. Note that this value
#     does not *change* the processor frequency - it should merely be updated to
#     reflect the processor speed set externally so that the code can use accurate
#     software delays.
F_CPU = 16000000


#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8

# Input clock frequency.
#     This will define a symbol, F_USB, in all source code files equal to the
#     input clock frequency (before any prescaling is performed) in Hz. This value may
#     differ from F_CPU if prescaling is used on the latter, and is required as the
#     raw input clock is fed directly to the PLL sections of the AVR for high speed
#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
#     at the end, this will be done automatically to create a 32-bit value in your
#     source code.
#
#     If no clock division is performed on the input clock inside the AVR (via the
#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)

# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT


# Bootloader selection
#   Teensy       halfkay
#   Pro Micro    caterina
#   Atmel DFU    atmel-dfu
#   LUFA DFU     lufa-dfu
#   QMK DFU      qmk-dfu
#   atmega32a    bootloadHID
BOOTLOADER = atmel-dfu


# If you don't know the bootloader type, then you can specify the
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
#   Teensy halfKay      512
#   Teensy++ halfKay    1024
#   Atmel DFU loader    4096
#   LUFA bootloader     4096
#   USBaspLoader        2048
# OPT_DEFS += -DBOOTLOADER_SIZE=4096


# Build Options
#   change yes to no to disable
#
BOOTMAGIC_ENABLE = no      # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no       # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes       # Audio control and System control(+450)
CONSOLE_ENABLE = no        # Console for debug(+400)
COMMAND_ENABLE = no        # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no       # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes            # USB Nkey Rollover
BACKLIGHT_ENABLE = yes       # Enable keyboard backlight functionality on B7 by default
RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow
MIDI_ENABLE = no            # MIDI support (+2400 to 4200, depending on config)
UNICODE_ENABLE = no         # Unicode
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no           # Audio output on port C6
FAUXCLICKY_ENABLE = no      # Use buzzer to emulate clicky switches
HD44780_ENABLE = no 		# Enable support for HD44780 based LCDs (+400)

# This is the VIA magic
RAW_ENABLE = yes
DYNAMIC_KEYMAP_ENABLE = yes
SRC += keyboards/wilba_tech/wt_main.c


M keyboards/handwired/prime_exl/prime_exl.c => keyboards/handwired/prime_exl/prime_exl.c +2 -1
@@ 14,7 14,7 @@
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "prime_exl.h"

/*
void matrix_init_kb(void) {
	// put your keyboard start-up code here
	// runs once when the firmware starts up


@@ 41,3 41,4 @@ void led_set_kb(uint8_t usb_led) {

	led_set_user(usb_led);
}
*/
\ No newline at end of file

M keyboards/handwired/prime_exl/prime_exl.h => keyboards/handwired/prime_exl/prime_exl.h +3 -3
@@ 13,8 13,8 @@
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef PRIME_EXL_H
#define PRIME_EXL_H
//#ifndef PRIME_EXL_H
//#define PRIME_EXL_H

#include "quantum.h"



@@ 37,4 37,4 @@
	{ K090,  K091,  K092,  KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }  \
}

#endif
\ No newline at end of file
//#endif
\ No newline at end of file

A keyboards/primekb/prime_e/config.h => keyboards/primekb/prime_e/config.h +72 -0
@@ 0,0 1,72 @@
/*
Copyright 2019 Holten Campbell

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "config_common.h"

/* USB Device descriptor parameter */
#define VENDOR_ID       0x5052
#define PRODUCT_ID      0x0051
#define DEVICE_VER      0x0001
#define MANUFACTURER    PrimeKB
#define PRODUCT         Prime_E
#define DESCRIPTION     Ergo_45

/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 13

/* Keyboard Matrix Assignments */
#define MATRIX_ROW_PINS { E6, C7, B5, B4 }
#define MATRIX_COL_PINS { F0, F1, F4, F5, F6, F7, D6, D4, D5, D3, D2, D1, D0 }
#define UNUSED_PINS

/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
#define DIODE_DIRECTION COL2ROW

#define BACKLIGHT_PIN B7
#define BACKLIGHT_LEVELS 5


/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 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

#define DYNAMIC_KEYMAP_LAYER_COUNT 4

// EEPROM usage

// TODO: refactor with new user EEPROM code (coming soon)
#define EEPROM_MAGIC 0x451F
#define EEPROM_MAGIC_ADDR 32
// Bump this every time we change what we store
// This will automatically reset the EEPROM with defaults
// and avoid loading invalid data from the EEPROM
#define EEPROM_VERSION 0x08
#define EEPROM_VERSION_ADDR 34

// Dynamic keymap starts after EEPROM version
#define DYNAMIC_KEYMAP_EEPROM_ADDR 35
// Dynamic macro starts after dynamic keymaps (35+(4*13*4*2)) = (35+416)
#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 451
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 573    // 1024-DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#define DYNAMIC_KEYMAP_MACRO_COUNT 16

A keyboards/primekb/prime_e/info.json => keyboards/primekb/prime_e/info.json +16 -0
@@ 0,0 1,16 @@
{
  "keyboard_name": "Prime_E",
  "url": "https://www.primekb.com",
  "maintainer": "holtenc",
  "width": 13,
  "height": 4,
  "layouts": {
      "LAYOUT": {
          "layout": [{"x":0,"y":0,"w":1,"h":1}, {"x":1,"y":0,"w":1,"h":1}, {"x":2,"y":0,"w":1,"h":1}, {"x":3,"y":0,"w":1,"h":1}, {"x":4,"y":0,"w":1,"h":1}, {"x":5,"y":0,"w":1,"h":1}, {"x":7,"y":0,"w":1,"h":1}, {"x":8,"y":0,"w":1,"h":1}, {"x":9,"y":0,"w":1,"h":1}, {"x":10,"y":0,"w":1,"h":1}, {"x":11,"y":0,"w":1,"h":1}, {"x":12,"y":0,"w":1,"h":1}, {"x":13,"y":0,"w":1,"h":1},
					 {"x":0,"y":1,"w":1.25,"h":1}, {"x":1.25,"y":1,"w":1,"h":1}, {"x":2.25,"y":1,"w":1,"h":1}, {"x":3.25,"y":1,"w":1,"h":1}, {"x":4.25,"y":1,"w":1,"h":1}, {"x":5.25,"y":1,"w":1,"h":1}, {"x":7.25,"y":1,"w":1,"h":1}, {"x":8.25,"y":1,"w":1,"h":1}, {"x":9.25,"y":1,"w":1,"h":1}, {"x":10.25,"y":1,"w":1,"h":1}, {"x":11.25,"y":1,"w":1,"h":1}, {"x":12.25,"y":1,"w":1.75,"h":1}, 
					 {"x":0,"y":2,"w":1.75,"h":1}, {"x":1.75,"y":2,"w":1,"h":1}, {"x":2.75,"y":2,"w":1,"h":1}, {"x":3.75,"y":2,"w":1,"h":1}, {"x":4.75,"y":2,"w":1,"h":1}, {"x":5.75,"y":2,"w":1,"h":1}, {"x":6.75,"y":2,"w":1,"h":1}, {"x":7.75,"y":2,"w":1,"h":1}, {"x":8.75,"y":2,"w":1,"h":1}, {"x":9.75,"y":2,"w":1,"h":1}, {"x":10.75,"y":2,"w":1,"h":1}, {"x":11.75,"y":2,"w":1,"h":1}, {"x":12.75,"y":2,"w":1.25,"h":1},
					 {"x":0,"y":3,"w":1.25,"h":1}, {"x":1.25,"y":3,"w":1.25,"h":1}, {"x":3.5,"y":3,"w":1.25,"h":1}, {"x":4.75,"y":3,"w":2,"h":1}, {"x":6.75,"y":3,"w":2.25,"h":1}, {"x":9,"y":3,"w":1.25,"h":1}, {"x":11.5,"y":3,"w":1.25,"h":1}, {"x":12.75,"y":3,"w":1.25,"h":1}
					 ]
      }
  }
}

A keyboards/primekb/prime_e/keymaps/default/keymap.c => keyboards/primekb/prime_e/keymaps/default/keymap.c +74 -0
@@ 0,0 1,74 @@
/* Copyright 2018 Holten Campbell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include QMK_KEYBOARD_H

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    LAYOUT(
		KC_ESC,   KC_Q,     KC_W,     KC_E,   KC_R,    KC_T,          KC_Y,   KC_U,     KC_I, KC_O,    KC_P,    KC_DEL, KC_BSPC,
		KC_TAB,   KC_A,     KC_S,     KC_D,   KC_F,    KC_G,          KC_H,   KC_J,     KC_K, KC_L,    KC_QUOT, KC_ENT,
		KC_LSFT,  KC_Z,     KC_X,     KC_C,   KC_V,    KC_B,          MO(1),  KC_N,     KC_M, KC_COMM, KC_DOT,  KC_SLSH, KC_LSFT,
		KC_LCTL,  KC_LALT,                    KC_RBRC, MO(1),	        KC_SPC, KC_MINS,                          KC_LGUI, TO(1)
    )

};

void matrix_init_user(void) {
  // set CapsLock LED to output and low
  setPinOutput(B1);
  writePinHigh(B1);
  // set NumLock LED to output and low
  setPinOutput(B2);
  writePinHigh(B2);
  // set ScrollLock LED to output and low
  setPinOutput(B3);
  writePinHigh(B3);
}

void matrix_scan_user(void) {

}


void led_set_user(uint8_t usb_led) {
  if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
    writePinLow(B2);
  } else {
    writePinHigh(B2);
  }
  if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
    writePinLow(B1);
  } else {
    writePinHigh(B1);
  }
/*
  if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
    writePinLow(B3);
  } else {
    writePinHigh(B3);
  }*/

}

//function for layer indicator LED
uint32_t layer_state_set_user(uint32_t state)
{
    if (biton32(state) == 1) {
    writePinLow(B3);
	} else {
		writePinHigh(B3);
    }
    return state;
}

A keyboards/primekb/prime_e/keymaps/default/readme.md => keyboards/primekb/prime_e/keymaps/default/readme.md +2 -0
@@ 0,0 1,2 @@
# The default keymap for Prime_E
This is the default keymap for Prime_E.
\ No newline at end of file

A keyboards/primekb/prime_e/keymaps/via/keymap.c => keyboards/primekb/prime_e/keymaps/via/keymap.c +73 -0
@@ 0,0 1,73 @@
/* Copyright 2018 Holten Campbell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include QMK_KEYBOARD_H

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    LAYOUT(
		KC_ESC,   KC_Q,     KC_W,     KC_E,   KC_R,    KC_T,          KC_Y,   KC_U,     KC_I, KC_O,    KC_P,    KC_DEL, KC_BSPC,
		KC_TAB,   KC_A,     KC_S,     KC_D,   KC_F,    KC_G,          KC_H,   KC_J,     KC_K, KC_L,    KC_QUOT, KC_ENT,
		KC_LSFT,  KC_Z,     KC_X,     KC_C,   KC_V,    KC_B,          MO(1),  KC_N,     KC_M, KC_COMM, KC_DOT,  KC_SLSH, KC_LSFT,
		KC_LCTL,  KC_LALT,                    KC_RBRC, MO(1),	        KC_SPC, KC_MINS,                          KC_LGUI, TO(1)
    )
};

void matrix_init_user(void) {
  // set CapsLock LED to output and low
  setPinOutput(B1);
  writePinHigh(B1);
  // set NumLock LED to output and low
  setPinOutput(B2);
  writePinHigh(B2);
  // set ScrollLock LED to output and low
  setPinOutput(B3);
  writePinHigh(B3);
}

void matrix_scan_user(void) {

}


void led_set_user(uint8_t usb_led) {
  if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
    writePinLow(B2);
  } else {
    writePinHigh(B2);
  }
  if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
    writePinLow(B1);
  } else {
    writePinHigh(B1);
  }
/*
  if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
    writePinLow(B3);
  } else {
    writePinHigh(B3);
  }*/

}

//function for layer indicator LED
uint32_t layer_state_set_user(uint32_t state)
{
    if (biton32(state) == 1) {
    writePinLow(B3);
	} else {
		writePinHigh(B3);
    }
    return state;
}

A keyboards/primekb/prime_e/keymaps/via/readme.md => keyboards/primekb/prime_e/keymaps/via/readme.md +2 -0
@@ 0,0 1,2 @@
# The VIA keymap for Prime_E
This keymap is for compatibility with the VIA configurator.
\ No newline at end of file

A keyboards/primekb/prime_e/keymaps/via/rules.mk => keyboards/primekb/prime_e/keymaps/via/rules.mk +85 -0
@@ 0,0 1,85 @@
# MCU name
MCU = atmega32u4

# Processor frequency.
#     This will define a symbol, F_CPU, in all source code files equal to the
#     processor frequency in Hz. You can then use this symbol in your source code to
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
#
#     This will be an integer division of F_USB below, as it is sourced by
#     F_USB after it has run through any CPU prescalers. Note that this value
#     does not *change* the processor frequency - it should merely be updated to
#     reflect the processor speed set externally so that the code can use accurate
#     software delays.
F_CPU = 16000000


#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8

# Input clock frequency.
#     This will define a symbol, F_USB, in all source code files equal to the
#     input clock frequency (before any prescaling is performed) in Hz. This value may
#     differ from F_CPU if prescaling is used on the latter, and is required as the
#     raw input clock is fed directly to the PLL sections of the AVR for high speed
#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
#     at the end, this will be done automatically to create a 32-bit value in your
#     source code.
#
#     If no clock division is performed on the input clock inside the AVR (via the
#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)

# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT


# Bootloader selection
#   Teensy       halfkay
#   Pro Micro    caterina
#   Atmel DFU    atmel-dfu
#   LUFA DFU     lufa-dfu
#   QMK DFU      qmk-dfu
#   atmega32a    bootloadHID
BOOTLOADER = atmel-dfu


# If you don't know the bootloader type, then you can specify the
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
#   Teensy halfKay      512
#   Teensy++ halfKay    1024
#   Atmel DFU loader    4096
#   LUFA bootloader     4096
#   USBaspLoader        2048
# OPT_DEFS += -DBOOTLOADER_SIZE=4096


# Build Options
#   change yes to no to disable
#
BOOTMAGIC_ENABLE = no      # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no       # Mouse keys(+4700)
EXTRAKEY_ENABLE = no       # Audio control and System control(+450)
CONSOLE_ENABLE = no        # Console for debug(+400)
COMMAND_ENABLE = no        # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no       # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes            # USB Nkey Rollover
BACKLIGHT_ENABLE = yes       # Enable keyboard backlight functionality on B7 by default
RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow
MIDI_ENABLE = no            # MIDI support (+2400 to 4200, depending on config)
UNICODE_ENABLE = no         # Unicode
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no           # Audio output on port C6
FAUXCLICKY_ENABLE = no      # Use buzzer to emulate clicky switches
HD44780_ENABLE = no 		# Enable support for HD44780 based LCDs (+400)

# This is the VIA magic
RAW_ENABLE = yes
DYNAMIC_KEYMAP_ENABLE = yes
SRC += keyboards/wilba_tech/wt_main.c
\ No newline at end of file

A keyboards/primekb/prime_e/prime_e.c => keyboards/primekb/prime_e/prime_e.c +22 -0
@@ 0,0 1,22 @@
/* Copyright 2019 Holten Campbell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "prime_e.h"

void led_set_kb(uint8_t usb_led) {
	// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here

	led_set_user(usb_led);
}

A keyboards/primekb/prime_e/prime_e.h => keyboards/primekb/prime_e/prime_e.h +34 -0
@@ 0,0 1,34 @@
/* Copyright 2019 Holten Campbell
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#pragma once

#include "quantum.h"


#define LAYOUT( \
	K000, K001, K002, K003, K004, K005,  		K006, K007, K008, K009, K010, K011, K012, \
	K100, K101, K102, K103, K104, K105,  		K106, K107, K108, K109, K110, K112, \
	K200, K201, K202, K203, K204, K205,  		K206, K207, K208, K209, K210, K211, K212, \
	K300, K301,  			K303, K304,  		K306, K308, 				K311, K312 \
) { \
	{ K000,  K001,  K002,  K003,  K004,  K005,  K006,  K007,  K008,  K009,  K010,  K011,  K012 }, \
	{ K100,  K101,  K102,  K103,  K104,  K105,  K106,  K107,  K108,  K109,  K110,  KC_NO, K112 }, \
	{ K200,  K201,  K202,  K203,  K204,  K205,  K206,  K207,  K208,  K209,  K210,  K211,  K212 }, \
	{ K300,  K301,  KC_NO, K303,  K304,  KC_NO, K306,  KC_NO, K308,  KC_NO, KC_NO, K311,  K312 } \
}


A keyboards/primekb/prime_e/readme.md => keyboards/primekb/prime_e/readme.md +16 -0
@@ 0,0 1,16 @@
# Prime_E

![Prime_E](https://imgur.com/7Rl4JOA.jpg)

An ergonomic 45%. 

Keyboard Maintainer: [Holtenc](https://github.com/holtenc/)  
Hardware Supported: Prime_E PCB, ATMega32u4  
Hardware Availability: Group Buy, Retail

Make example for this keyboard (after setting up your build environment):

    make prime_e:default
    make prime_e:via (when using VIA configurator)

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).

A keyboards/primekb/prime_e/rules.mk => keyboards/primekb/prime_e/rules.mk +80 -0
@@ 0,0 1,80 @@
# MCU name
MCU = atmega32u4

# Processor frequency.
#     This will define a symbol, F_CPU, in all source code files equal to the
#     processor frequency in Hz. You can then use this symbol in your source code to
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
#
#     This will be an integer division of F_USB below, as it is sourced by
#     F_USB after it has run through any CPU prescalers. Note that this value
#     does not *change* the processor frequency - it should merely be updated to
#     reflect the processor speed set externally so that the code can use accurate
#     software delays.
F_CPU = 16000000


#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8

# Input clock frequency.
#     This will define a symbol, F_USB, in all source code files equal to the
#     input clock frequency (before any prescaling is performed) in Hz. This value may
#     differ from F_CPU if prescaling is used on the latter, and is required as the
#     raw input clock is fed directly to the PLL sections of the AVR for high speed
#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
#     at the end, this will be done automatically to create a 32-bit value in your
#     source code.
#
#     If no clock division is performed on the input clock inside the AVR (via the
#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)

# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT


# Bootloader selection
#   Teensy       halfkay
#   Pro Micro    caterina
#   Atmel DFU    atmel-dfu
#   LUFA DFU     lufa-dfu
#   QMK DFU      qmk-dfu
#   atmega32a    bootloadHID
BOOTLOADER = atmel-dfu


# If you don't know the bootloader type, then you can specify the
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
#   Teensy halfKay      512
#   Teensy++ halfKay    1024
#   Atmel DFU loader    4096
#   LUFA bootloader     4096
#   USBaspLoader        2048
# OPT_DEFS += -DBOOTLOADER_SIZE=4096


# Build Options
#   change yes to no to disable
#
BOOTMAGIC_ENABLE = yes      # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no       # Mouse keys(+4700)
EXTRAKEY_ENABLE = no       # Audio control and System control(+450)
CONSOLE_ENABLE = no        # Console for debug(+400)
COMMAND_ENABLE = no        # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no       # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes            # USB Nkey Rollover
BACKLIGHT_ENABLE = yes       # Enable keyboard backlight functionality on B7 by default
RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow
MIDI_ENABLE = no            # MIDI support (+2400 to 4200, depending on config)
UNICODE_ENABLE = no         # Unicode
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no           # Audio output on port C6
FAUXCLICKY_ENABLE = no      # Use buzzer to emulate clicky switches
HD44780_ENABLE = no 		# Enable support for HD44780 based LCDs (+400)
\ No newline at end of file