1
0
Fork 0

Backlight abstraction and other changes (#439)

* redoes matrix pins, abstracts backlight code for B5,6,7

* slimming down keyboard stuff, backlight breathing implemented

* don't call backlight init when no pin

* cleans up user/kb/quantum calls, keyboard files

* fix pvc atomic

* replaces CHANNEL with correct var in breathing

* removes .hexs, updates readmes, updates template

* cleans-up clueboards, readmes to lowercase

* updates readme
This commit is contained in:
Jack Humbert 2016-06-23 22:18:20 -04:00 committed by GitHub
parent ba116ceb49
commit 13bb6b4b7f
239 changed files with 1146 additions and 139888 deletions

View file

@ -5,46 +5,46 @@
#define COL2ROW 0
#define ROW2COL 1
/* I/O pins */
#define B0 { .input_addr = 3, .bit = 0 }
#define B1 { .input_addr = 3, .bit = 1 }
#define B2 { .input_addr = 3, .bit = 2 }
#define B3 { .input_addr = 3, .bit = 3 }
#define B4 { .input_addr = 3, .bit = 4 }
#define B5 { .input_addr = 3, .bit = 5 }
#define B6 { .input_addr = 3, .bit = 6 }
#define B7 { .input_addr = 3, .bit = 7 }
#define C0 { .input_addr = 6, .bit = 0 }
#define C1 { .input_addr = 6, .bit = 1 }
#define C2 { .input_addr = 6, .bit = 2 }
#define C3 { .input_addr = 6, .bit = 3 }
#define C4 { .input_addr = 6, .bit = 4 }
#define C5 { .input_addr = 6, .bit = 5 }
#define C6 { .input_addr = 6, .bit = 6 }
#define C7 { .input_addr = 6, .bit = 7 }
#define D0 { .input_addr = 9, .bit = 0 }
#define D1 { .input_addr = 9, .bit = 1 }
#define D2 { .input_addr = 9, .bit = 2 }
#define D3 { .input_addr = 9, .bit = 3 }
#define D4 { .input_addr = 9, .bit = 4 }
#define D5 { .input_addr = 9, .bit = 5 }
#define D6 { .input_addr = 9, .bit = 6 }
#define D7 { .input_addr = 9, .bit = 7 }
#define E0 { .input_addr = 0xC, .bit = 0 }
#define E1 { .input_addr = 0xC, .bit = 1 }
#define E2 { .input_addr = 0xC, .bit = 2 }
#define E3 { .input_addr = 0xC, .bit = 3 }
#define E4 { .input_addr = 0xC, .bit = 4 }
#define E5 { .input_addr = 0xC, .bit = 5 }
#define E6 { .input_addr = 0xC, .bit = 6 }
#define E7 { .input_addr = 0xC, .bit = 7 }
#define F0 { .input_addr = 0xF, .bit = 0 }
#define F1 { .input_addr = 0xF, .bit = 1 }
#define F2 { .input_addr = 0xF, .bit = 2 }
#define F3 { .input_addr = 0xF, .bit = 3 }
#define F4 { .input_addr = 0xF, .bit = 4 }
#define F5 { .input_addr = 0xF, .bit = 5 }
#define F6 { .input_addr = 0xF, .bit = 6 }
#define F7 { .input_addr = 0xF, .bit = 7 }
#define B0 0x30
#define B1 0x31
#define B2 0x32
#define B3 0x33
#define B4 0x34
#define B5 0x35
#define B6 0x36
#define B7 0x37
#define C0 0x60
#define C1 0x61
#define C2 0x62
#define C3 0x63
#define C4 0x64
#define C5 0x65
#define C6 0x66
#define C7 0x67
#define D0 0x90
#define D1 0x91
#define D2 0x92
#define D3 0x93
#define D4 0x94
#define D5 0x95
#define D6 0x96
#define D7 0x97
#define E0 0xC0
#define E1 0xC1
#define E2 0xC2
#define E3 0xC3
#define E4 0xC4
#define E5 0xC5
#define E6 0xC6
#define E7 0xC7
#define F0 0xF0
#define F1 0xF1
#define F2 0xF2
#define F3 0xF3
#define F4 0xF4
#define F5 0xF5
#define F6 0xF6
#define F7 0xF7
/* USART configuration */
#ifdef BLUETOOTH_ENABLE

View file

@ -125,8 +125,8 @@ enum quantum_keycodes {
MUV_DE,
// Midi mode on/off
MI_ON,
MI_OFF,
MIDI_ON,
MIDI_OFF,
// Backlight functionality
BL_0,
@ -154,7 +154,10 @@ enum quantum_keycodes {
KC_LSPO,
// Right shift, close paren
KC_RSPC
KC_RSPC,
// always leave at the end
SAFE_RANGE
};
// Ability to use mods in layouts
@ -266,6 +269,9 @@ enum quantum_keycodes {
#define BL_ON BL_9
#define BL_OFF BL_0
#define MI_ON MIDI_ON
#define MI_OFF MIDI_OFF
// GOTO layer - 16 layers max
// when:
// ON_PRESS = 1

View file

@ -1,54 +0,0 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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 <avr/io.h>
#include "stdint.h"
#include "led.h"
__attribute__ ((weak))
void led_set_kb(uint8_t usb_led) {
}
__attribute__ ((weak))
void led_init_ports(void)
{
}
__attribute__ ((weak))
void led_set(uint8_t usb_led)
{
// Example LED Code
//
// // Using PE6 Caps Lock LED
// if (usb_led & (1<<USB_LED_CAPS_LOCK))
// {
// // Output high.
// DDRE |= (1<<6);
// PORTE |= (1<<6);
// }
// else
// {
// // Output low.
// DDRE &= ~(1<<6);
// PORTE &= ~(1<<6);
// }
led_set_kb(usb_led);
}

View file

@ -32,8 +32,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define DEBOUNCING_DELAY 5
#endif
static const io_pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
/* matrix state */
#if DIODE_DIRECTION == COL2ROW
static matrix_row_t matrix[MATRIX_ROWS];
@ -52,10 +52,30 @@ static matrix_col_t read_rows(void);
__attribute__ ((weak))
void matrix_init_quantum(void) {
matrix_init_kb();
}
__attribute__ ((weak))
void matrix_scan_quantum(void) {
matrix_scan_kb();
}
__attribute__ ((weak))
void matrix_init_kb(void) {
matrix_init_user();
}
__attribute__ ((weak))
void matrix_scan_kb(void) {
matrix_scan_user();
}
__attribute__ ((weak))
void matrix_init_user(void) {
}
__attribute__ ((weak))
void matrix_scan_user(void) {
}
uint8_t matrix_rows(void) {
@ -70,22 +90,22 @@ void matrix_power_up(void) {
#if DIODE_DIRECTION == COL2ROW
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* DDRxn */
_SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit);
_SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
toggle_row(r);
}
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* PORTxn */
_SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit);
_SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
}
#else
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* DDRxn */
_SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit);
_SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
toggle_col(c);
}
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* PORTxn */
_SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit);
_SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF);
}
#endif
}
@ -100,22 +120,22 @@ void matrix_init(void) {
#if DIODE_DIRECTION == COL2ROW
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* DDRxn */
_SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit);
_SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
toggle_row(r);
}
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* PORTxn */
_SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit);
_SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
}
#else
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* DDRxn */
_SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit);
_SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
toggle_col(c);
}
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* PORTxn */
_SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit);
_SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF);
}
#endif
matrix_init_quantum();
@ -151,14 +171,14 @@ uint8_t matrix_scan(void) {
static void toggle_row(uint8_t row) {
/* PINxn */
_SFR_IO8(row_pins[row].input_addr) = _BV(row_pins[row].bit);
_SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF);
}
static matrix_row_t read_cols(void) {
matrix_row_t state = 0;
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* PINxn */
if (!(_SFR_IO8(col_pins[c].input_addr) & _BV(col_pins[c].bit))) {
if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) {
state |= (matrix_row_t)1 << c;
}
}
@ -199,14 +219,14 @@ uint8_t matrix_scan(void) {
static void toggle_col(uint8_t col) {
/* PINxn */
_SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit);
_SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF);
}
static matrix_col_t read_rows(void) {
matrix_col_t state = 0;
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* PINxn */
if (!(_SFR_IO8(row_pins[r].input_addr) & _BV(row_pins[r].bit))) {
if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) {
state |= (matrix_col_t)1 << r;
}
}

View file

@ -655,6 +655,9 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
}
void matrix_init_quantum() {
#ifdef BACKLIGHT_ENABLE
backlight_init_ports();
#endif
matrix_init_kb();
}
@ -673,6 +676,7 @@ void matrix_scan_quantum() {
matrix_scan_kb();
}
#ifdef AUDIO_ENABLE
bool is_music_on(void) {
return (music_activated != 0);
@ -698,6 +702,348 @@ void matrix_scan_quantum() {
#endif
#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
static const uint8_t backlight_pin = BACKLIGHT_PIN;
#if BACKLIGHT_PIN == B7
# define COM1x1 COM1C1
# define OCR1x OCR1C
#elif BACKLIGHT_PIN == B6
# define COM1x1 COM1B1
# define OCR1x OCR1B
#elif BACKLIGHT_PIN == B5
# define COM1x1 COM1A1
# define OCR1x OCR1A
#else
# error "Backlight pin not supported - use B5, B6, or B7"
#endif
__attribute__ ((weak))
void backlight_init_ports(void)
{
// Setup backlight pin as output and output low.
// DDRx |= n
_SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
// Use full 16-bit resolution.
ICR1 = 0xFFFF;
// I could write a wall of text here to explain... but TL;DW
// Go read the ATmega32u4 datasheet.
// And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
// Pin PB7 = OCR1C (Timer 1, Channel C)
// Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
// (i.e. start high, go low when counter matches.)
// WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
// Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
backlight_init();
#ifdef BACKLIGHT_BREATHING
breathing_defaults();
#endif
}
__attribute__ ((weak))
void backlight_set(uint8_t level)
{
// Prevent backlight blink on lowest level
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
if ( level == 0 ) {
// Turn off PWM control on backlight pin, revert to output low.
TCCR1A &= ~(_BV(COM1x1));
OCR1x = 0x0;
} else if ( level == BACKLIGHT_LEVELS ) {
// Turn on PWM control of backlight pin
TCCR1A |= _BV(COM1x1);
// Set the brightness
OCR1x = 0xFFFF;
} else {
// Turn on PWM control of backlight pin
TCCR1A |= _BV(COM1x1);
// Set the brightness
OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
}
#ifdef BACKLIGHT_BREATHING
breathing_intensity_default();
#endif
}
#ifdef BACKLIGHT_BREATHING
#define BREATHING_NO_HALT 0
#define BREATHING_HALT_OFF 1
#define BREATHING_HALT_ON 2
static uint8_t breath_intensity;
static uint8_t breath_speed;
static uint16_t breathing_index;
static uint8_t breathing_halt;
void breathing_enable(void)
{
if (get_backlight_level() == 0)
{
breathing_index = 0;
}
else
{
// Set breathing_index to be at the midpoint (brightest point)
breathing_index = 0x20 << breath_speed;
}
breathing_halt = BREATHING_NO_HALT;
// Enable breathing interrupt
TIMSK1 |= _BV(OCIE1A);
}
void breathing_pulse(void)
{
if (get_backlight_level() == 0)
{
breathing_index = 0;
}
else
{
// Set breathing_index to be at the midpoint + 1 (brightest point)
breathing_index = 0x21 << breath_speed;
}
breathing_halt = BREATHING_HALT_ON;
// Enable breathing interrupt
TIMSK1 |= _BV(OCIE1A);
}
void breathing_disable(void)
{
// Disable breathing interrupt
TIMSK1 &= ~_BV(OCIE1A);
backlight_set(get_backlight_level());
}
void breathing_self_disable(void)
{
if (get_backlight_level() == 0)
{
breathing_halt = BREATHING_HALT_OFF;
}
else
{
breathing_halt = BREATHING_HALT_ON;
}
//backlight_set(get_backlight_level());
}
void breathing_toggle(void)
{
if (!is_breathing())
{
if (get_backlight_level() == 0)
{
breathing_index = 0;
}
else
{
// Set breathing_index to be at the midpoint + 1 (brightest point)
breathing_index = 0x21 << breath_speed;
}
breathing_halt = BREATHING_NO_HALT;
}
// Toggle breathing interrupt
TIMSK1 ^= _BV(OCIE1A);
// Restore backlight level
if (!is_breathing())
{
backlight_set(get_backlight_level());
}
}
bool is_breathing(void)
{
return (TIMSK1 && _BV(OCIE1A));
}
void breathing_intensity_default(void)
{
//breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
}
void breathing_intensity_set(uint8_t value)
{
breath_intensity = value;
}
void breathing_speed_default(void)
{
breath_speed = 4;
}
void breathing_speed_set(uint8_t value)
{
bool is_breathing_now = is_breathing();
uint8_t old_breath_speed = breath_speed;
if (is_breathing_now)
{
// Disable breathing interrupt
TIMSK1 &= ~_BV(OCIE1A);
}
breath_speed = value;
if (is_breathing_now)
{
// Adjust index to account for new speed
breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
// Enable breathing interrupt
TIMSK1 |= _BV(OCIE1A);
}
}
void breathing_speed_inc(uint8_t value)
{
if ((uint16_t)(breath_speed - value) > 10 )
{
breathing_speed_set(0);
}
else
{
breathing_speed_set(breath_speed - value);
}
}
void breathing_speed_dec(uint8_t value)
{
if ((uint16_t)(breath_speed + value) > 10 )
{
breathing_speed_set(10);
}
else
{
breathing_speed_set(breath_speed + value);
}
}
void breathing_defaults(void)
{
breathing_intensity_default();
breathing_speed_default();
breathing_halt = BREATHING_NO_HALT;
}
/* Breathing Sleep LED brighness(PWM On period) table
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
*
* http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
*/
static const uint8_t breathing_table[64] PROGMEM = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
ISR(TIMER1_COMPA_vect)
{
// OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
{
// Disable breathing interrupt
TIMSK1 &= ~_BV(OCIE1A);
}
OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
}
#endif // breathing
#else // backlight
__attribute__ ((weak))
void backlight_init_ports(void)
{
}
__attribute__ ((weak))
void backlight_set(uint8_t level)
{
}
#endif // backlight
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {
}
__attribute__ ((weak))
void led_set_kb(uint8_t usb_led) {
led_set_user(usb_led);
}
__attribute__ ((weak))
void led_init_ports(void)
{
}
__attribute__ ((weak))
void led_set(uint8_t usb_led)
{
// Example LED Code
//
// // Using PE6 Caps Lock LED
// if (usb_led & (1<<USB_LED_CAPS_LOCK))
// {
// // Output high.
// DDRE |= (1<<6);
// PORTE |= (1<<6);
// }
// else
// {
// // Output low.
// DDRE &= ~(1<<6);
// PORTE &= ~(1<<6);
// }
led_set_kb(usb_led);
}
//------------------------------------------------------------------------------
// Override these functions in your keymap file to play different tunes on
// different events such as startup and bootloader jump

View file

@ -27,6 +27,10 @@
#include <util/delay.h>
#include "bootloader.h"
#include "timer.h"
#include "config_common.h"
#include <avr/interrupt.h>
#include "led.h"
#include "action_util.h"
extern uint32_t default_layer_state;
@ -74,6 +78,8 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
void matrix_init_kb(void);
void matrix_scan_kb(void);
void matrix_init_user(void);
void matrix_scan_user(void);
bool process_action_kb(keyrecord_t *record);
bool process_record_kb(uint16_t keycode, keyrecord_t *record);
bool process_record_user(uint16_t keycode, keyrecord_t *record);
@ -89,4 +95,28 @@ void audio_on_user(void);
void music_on_user(void);
void music_scale_user(void);
#ifdef BACKLIGHT_ENABLE
void backlight_init_ports(void);
#ifdef BACKLIGHT_BREATHING
void breathing_enable(void);
void breathing_pulse(void);
void breathing_disable(void);
void breathing_self_disable(void);
void breathing_toggle(void);
bool is_breathing(void);
void breathing_defaults(void);
void breathing_intensity_default(void);
void breathing_speed_default(void);
void breathing_speed_set(uint8_t value);
void breathing_speed_inc(uint8_t value);
void breathing_speed_dec(uint8_t value);
#endif
#endif
void led_set_user(uint8_t usb_led);
void led_set_kb(uint8_t usb_led);
#endif

View file

@ -53,20 +53,20 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # 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
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 = no # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE = no # MIDI controls
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no # Audio output on port C6
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
ifndef QUANTUM_DIR
include ../../Makefile

View file

@ -48,6 +48,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
@ -56,7 +61,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
#define BACKLIGHT_LEVELS 3
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE

View file

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

View file

@ -0,0 +1,8 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here
#endif

View file

@ -1,6 +1,3 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "%KEYBOARD%.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -28,3 +25,20 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
}
return MACRO_NONE;
};
void matrix_init_user(void) {
}
void matrix_scan_user(void) {
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
void led_set_user(uint8_t usb_led) {
}

View file

@ -0,0 +1 @@
# The default keymap for %KEYBOARD%

View file

@ -3,7 +3,7 @@
## Quantum MK Firmware
For the full Quantum feature list, see [the parent README.md](/doc/README.md).
For the full Quantum feature list, see [the parent readme.md](/doc/readme.md).
## Building
@ -12,13 +12,17 @@ Download or clone the whole firmware and navigate to the keyboards/%KEYBOARD% fo
Depending on which keymap you would like to use, you will have to compile slightly differently.
### Default
To build with the default keymap, simply run `make`.
### Other Keymaps
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `<name>.c` in the keymaps folder, and see keymap document (you can find in top README.md) and existent keymap files.
To build the firmware binary hex file with a keymap just do `make` with `KEYMAP` option like:
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
To build the firmware binary hex file with a keymap just do `make` with `keymap` option like:
```
$ make KEYMAP=[default|jack|<name>]
$ make keymap=[default|jack|<name>]
```
Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.
Keymaps follow the format **__keymap.c__** and are stored in folders in the `keymaps` folder, eg `keymaps/my_keymap/`

View file

@ -1,26 +1,5 @@
#include "%KEYBOARD%.h"
__attribute__ ((weak))
void matrix_init_user(void) {
// leave this function blank - it can be defined in a keymap file
};
__attribute__ ((weak))
void matrix_scan_user(void) {
// leave this function blank - it can be defined in a keymap file
}
__attribute__ ((weak))
bool process_action_user(keyrecord_t *record) {
// leave this function blank - it can be defined in a keymap file
return true;
}
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {
// leave this function blank - it can be defined in a keymap file
}
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
@ -35,7 +14,7 @@ void matrix_scan_kb(void) {
matrix_scan_user();
}
bool process_action_kb(keyrecord_t *record) {
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
// put your per-action keyboard code here
// runs for every action, just before processing by the firmware
@ -47,64 +26,3 @@ void led_set_kb(uint8_t usb_led) {
led_set_user(usb_led);
}
#ifdef BACKLIGHT_ENABLE
#define CHANNEL OCR1C
void backlight_init_ports()
{
// Setup PB7 as output and output low.
DDRB |= (1<<7);
PORTB &= ~(1<<7);
// Use full 16-bit resolution.
ICR1 = 0xFFFF;
// I could write a wall of text here to explain... but TL;DW
// Go read the ATmega32u4 datasheet.
// And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
// Pin PB7 = OCR1C (Timer 1, Channel C)
// Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
// (i.e. start high, go low when counter matches.)
// WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
// Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
backlight_init();
}
void backlight_set(uint8_t level)
{
if ( level == 0 )
{
// Turn off PWM control on PB7, revert to output low.
TCCR1A &= ~(_BV(COM1C1));
CHANNEL = 0x0;
// Prevent backlight blink on lowest level
PORTB &= ~(_BV(PORTB7));
}
else if ( level == BACKLIGHT_LEVELS )
{
// Prevent backlight blink on lowest level
PORTB &= ~(_BV(PORTB7));
// Turn on PWM control of PB7
TCCR1A |= _BV(COM1C1);
// Set the brightness
CHANNEL = 0xFFFF;
}
else
{
// Prevent backlight blink on lowest level
PORTB &= ~(_BV(PORTB7));
// Turn on PWM control of PB7
TCCR1A |= _BV(COM1C1);
// Set the brightness
CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
}
}
#endif

View file

@ -1,13 +1,7 @@
#ifndef %KEYBOARD_UPPERCASE%_H
#define %KEYBOARD_UPPERCASE%_H
#include "matrix.h"
#include "keymap.h"
#ifdef BACKLIGHT_ENABLE
#include "backlight.h"
#endif
#include <avr/io.h>
#include <stddef.h>
#include "quantum.h"
// This a shortcut to help you visually see your layout.
// The following is an example using the Planck MIT layout
@ -22,9 +16,4 @@
{ k10, KC_NO, k11 }, \
}
void matrix_init_user(void);
void matrix_scan_user(void);
bool process_action_user(keyrecord_t *record);
void led_set_user(uint8_t usb_led);
#endif