1
0
Fork 0

[Keyboard] Refactor jj40 to current standards (#5574)

* Refactor jj40 in line with current ps2avrgb template

* Disable bootmagic lite as it seems to not work on atmega32a/bootloadHID

* Add backlight pwm bodge till #4324 lands

* Increase planck keymap compatibility
This commit is contained in:
zvecr 2019-04-08 18:53:15 +01:00 committed by Drashna Jaelre
parent 9b393700d2
commit 91b18e263f
12 changed files with 142 additions and 762 deletions

View file

@ -1,213 +0,0 @@
/**
* Backlighting code for PS2AVRGB boards (ATMEGA32A)
* Kenneth A. (github.com/krusli | krusli.me)
*/
#include "backlight.h"
#include "quantum.h"
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "backlight_custom.h"
#include "breathing_custom.h"
// DEBUG
#include <stdlib.h>
#include <stdio.h>
// Port D: digital pins of the AVR chipset
#define NUMLOCK_PORT (1 << 0) // D0
#define CAPSLOCK_PORT (1 << 1) // D1
#define BACKLIGHT_PORT (1 << 4) // D4
#define SCROLLLOCK_PORT (1 << 6) // D6
#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64
#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default
#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask
#define PWM_MAX 0xFF
#define TIMER_TOP 255 // 8 bit PWM
extern backlight_config_t backlight_config;
/**
* References
* Port Registers: https://www.arduino.cc/en/Reference/PortManipulation
* TCCR1A: https://electronics.stackexchange.com/questions/92350/what-is-the-difference-between-tccr1a-and-tccr1b
* Timers: http://www.avrbeginners.net/architecture/timers/timers.html
* 16-bit timer setup: http://sculland.com/ATmega168/Interrupts-And-Timers/16-Bit-Timer-Setup/
* PS2AVRGB firmware: https://github.com/showjean/ps2avrU/tree/master/firmware
*/
// @Override
// turn LEDs on and off depending on USB caps/num/scroll lock states.
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {
if (usb_led & (1 << USB_LED_NUM_LOCK)) {
// turn on
DDRD |= NUMLOCK_PORT;
PORTD |= NUMLOCK_PORT;
} else {
// turn off
DDRD &= ~NUMLOCK_PORT;
PORTD &= ~NUMLOCK_PORT;
}
if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
DDRD |= CAPSLOCK_PORT;
PORTD |= CAPSLOCK_PORT;
} else {
DDRD &= ~CAPSLOCK_PORT;
PORTD &= ~CAPSLOCK_PORT;
}
if (usb_led & (1 << USB_LED_SCROLL_LOCK)) {
DDRD |= SCROLLLOCK_PORT;
PORTD |= SCROLLLOCK_PORT;
} else {
DDRD &= ~SCROLLLOCK_PORT;
PORTD &= ~SCROLLLOCK_PORT;
}
}
#ifdef BACKLIGHT_ENABLE
// sets up Timer 1 for 8-bit PWM
void timer1PWMSetup(void) { // NOTE ONLY CALL THIS ONCE
// default 8 bit mode
TCCR1A &= ~(1 << 1); // cbi(TCCR1A,PWM11); <- set PWM11 bit to HIGH
TCCR1A |= (1 << 0); // sbi(TCCR1A,PWM10); <- set PWM10 bit to LOW
// clear output compare value A
// outb(OCR1AH, 0);
// outb(OCR1AL, 0);
// clear output comparator registers for B
OCR1BH = 0; // outb(OCR1BH, 0);
OCR1BL = 0; // outb(OCR1BL, 0);
}
bool is_init = false;
void timer1Init(void) {
// timer1SetPrescaler(TIMER1PRESCALE)
// set to DIV/64
(TCCR1B) = ((TCCR1B) & ~TIMER_PRESCALE_MASK) | TIMER1PRESCALE;
// reset TCNT1
TCNT1H = 0; // outb(TCNT1H, 0);
TCNT1L = 0; // outb(TCNT1L, 0);
// TOIE1: Timer Overflow Interrupt Enable (Timer 1);
TIMSK |= _BV(TOIE1); // sbi(TIMSK, TOIE1);
is_init = true;
}
void timer1UnInit(void) {
// set prescaler back to NONE
(TCCR1B) = ((TCCR1B) & ~TIMER_PRESCALE_MASK) | 0x00; // TIMERRTC_CLK_STOP
// disable timer overflow interrupt
TIMSK &= ~_BV(TOIE1); // overflow bit?
setPWM(0);
is_init = false;
}
// handle TCNT1 overflow
//! Interrupt handler for tcnt1 overflow interrupt
ISR(TIMER1_OVF_vect, ISR_NOBLOCK)
{
// sei();
// handle breathing here
#ifdef BACKLIGHT_BREATHING
if (is_breathing()) {
custom_breathing_handler();
}
#endif
// TODO call user defined function
}
// enable timer 1 PWM
// timer1PWMBOn()
void timer1PWMBEnable(void) {
// turn on channel B (OC1B) PWM output
// set OC1B as non-inverted PWM
TCCR1A |= _BV(COM1B1);
TCCR1A &= ~_BV(COM1B0);
}
// disable timer 1 PWM
// timer1PWMBOff()
void timer1PWMBDisable(void) {
TCCR1A &= ~_BV(COM1B1);
TCCR1A &= ~_BV(COM1B0);
}
void enableBacklight(void) {
DDRD |= BACKLIGHT_PORT; // set digital pin 4 as output
PORTD |= BACKLIGHT_PORT; // set digital pin 4 to high
}
void disableBacklight(void) {
// DDRD &= ~BACKLIGHT_PORT; // set digital pin 4 as input
PORTD &= ~BACKLIGHT_PORT; // set digital pin 4 to low
}
void startPWM(void) {
timer1Init();
timer1PWMBEnable();
enableBacklight();
}
void stopPWM(void) {
timer1UnInit();
disableBacklight();
timer1PWMBDisable();
}
void b_led_init_ports(void) {
/* turn backlight on/off depending on user preference */
#if BACKLIGHT_ON_STATE == 0
// DDRx register: sets the direction of Port D
// DDRD &= ~BACKLIGHT_PORT; // set digital pin 4 as input
PORTD &= ~BACKLIGHT_PORT; // set digital pin 4 to low
#else
DDRD |= BACKLIGHT_PORT; // set digital pin 4 as output
PORTD |= BACKLIGHT_PORT; // set digital pin 4 to high
#endif
timer1PWMSetup();
startPWM();
#ifdef BACKLIGHT_BREATHING
breathing_enable();
#endif
}
void b_led_set(uint8_t level) {
if (level > BACKLIGHT_LEVELS) {
level = BACKLIGHT_LEVELS;
}
setPWM((int)(TIMER_TOP * (float) level / BACKLIGHT_LEVELS));
}
// called every matrix scan
void b_led_task(void) {
// do nothing for now
}
void setPWM(uint16_t xValue) {
if (xValue > TIMER_TOP) {
xValue = TIMER_TOP;
}
OCR1B = xValue; // timer1PWMBSet(xValue);
}
#endif // BACKLIGHT_ENABLE

View file

@ -1,15 +0,0 @@
/**
* Backlighting code for PS2AVRGB boards (ATMEGA32A)
* Kenneth A. (github.com/krusli | krusli.me)
*/
#ifndef BACKLIGHT_CUSTOM_H
#define BACKLIGHT_CUSTOM_H
#include <avr/pgmspace.h>
void b_led_init_ports(void);
void b_led_set(uint8_t level);
void b_led_task(void);
void setPWM(uint16_t xValue);
#endif // BACKLIGHT_CUSTOM_H

View file

@ -1,140 +0,0 @@
/**
* Breathing effect code for PS2AVRGB boards (ATMEGA32A)
* Works in conjunction with `backlight.c`.
*
* Code adapted from `quantum.c` to register with the existing TIMER1 overflow
* handler in `backlight.c` instead of setting up its own timer.
* Kenneth A. (github.com/krusli | krusli.me)
*/
#ifdef BACKLIGHT_ENABLE
#ifdef BACKLIGHT_BREATHING
#include "backlight_custom.h"
#ifndef BREATHING_PERIOD
#define BREATHING_PERIOD 6
#endif
#define breathing_min() do {breathing_counter = 0;} while (0)
#define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
// TODO make this share code with quantum.c
#define BREATHING_NO_HALT 0
#define BREATHING_HALT_OFF 1
#define BREATHING_HALT_ON 2
#define BREATHING_STEPS 128
static uint8_t breathing_period = BREATHING_PERIOD;
static uint8_t breathing_halt = BREATHING_NO_HALT;
static uint16_t breathing_counter = 0;
static bool breathing = false;
bool is_breathing(void) {
return breathing;
}
// See http://jared.geek.nz/2013/feb/linear-led-pwm
static uint16_t cie_lightness(uint16_t v) {
if (v <= 5243) // if below 8% of max
return v / 9; // same as dividing by 900%
else {
uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
// to get a useful result with integer division, we shift left in the expression above
// and revert what we've done again after squaring.
y = y * y * y >> 8;
if (y > 0xFFFFUL) // prevent overflow
return 0xFFFFU;
else
return (uint16_t) y;
}
}
void breathing_enable(void) {
breathing = true;
breathing_counter = 0;
breathing_halt = BREATHING_NO_HALT;
// interrupt already registered
}
void breathing_pulse(void) {
if (get_backlight_level() == 0)
breathing_min();
else
breathing_max();
breathing_halt = BREATHING_HALT_ON;
// breathing_interrupt_enable();
breathing = true;
}
void breathing_disable(void) {
breathing = false;
// backlight_set(get_backlight_level());
b_led_set(get_backlight_level()); // custom implementation of backlight_set()
}
void breathing_self_disable(void)
{
if (get_backlight_level() == 0)
breathing_halt = BREATHING_HALT_OFF;
else
breathing_halt = BREATHING_HALT_ON;
}
void breathing_toggle(void) {
if (is_breathing())
breathing_disable();
else
breathing_enable();
}
void breathing_period_set(uint8_t value)
{
if (!value)
value = 1;
breathing_period = value;
}
void breathing_period_default(void) {
breathing_period_set(BREATHING_PERIOD);
}
void breathing_period_inc(void)
{
breathing_period_set(breathing_period+1);
}
void breathing_period_dec(void)
{
breathing_period_set(breathing_period-1);
}
/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Use this before the cie_lightness function.
static inline uint16_t scale_backlight(uint16_t v) {
return v / BACKLIGHT_LEVELS * get_backlight_level();
}
void custom_breathing_handler(void) {
uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
// resetting after one period to prevent ugly reset at overflow.
breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
uint8_t index = breathing_counter / interval % BREATHING_STEPS;
if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
{
// breathing_interrupt_disable();
}
setPWM(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
}
#endif // BACKLIGHT_BREATHING
#endif // BACKLIGHT_ENABLE

View file

@ -1,51 +1,55 @@
/* /*
Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com> Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com>
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "config_common.h" #pragma once
#ifndef CONFIG_H #include "config_common.h"
#define CONFIG_H
#define VENDOR_ID 0x20A0 #define VENDOR_ID 0x20A0
#define PRODUCT_ID 0x422D #define PRODUCT_ID 0x422D
// TODO: share these strings with usbconfig.h // TODO: share these strings with usbconfig.h
// Edit usbconfig.h to change these. // Edit usbconfig.h to change these.
#define MANUFACTURER winkeyless.kr #define MANUFACTURER Kprepublic
#define PRODUCT jj40 #define PRODUCT jj40
/* matrix size */ /* matrix size */
#define MATRIX_ROWS 8 #define MATRIX_ROWS 4
#define MATRIX_COLS 15 #define MATRIX_COLS 12
#define MATRIX_ROW_PINS { B0, B1, B3, B4 }
#define MATRIX_COL_PINS { C4, C5, C6, C7, A4, A5, A6, A7, A3, A2, A1, A0 }
/* COL2ROW or ROW2COL */ /* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW #define DIODE_DIRECTION COL2ROW
#define BACKLIGHT_PIN D4
#define BACKLIGHT_LEVELS 12 #define BACKLIGHT_LEVELS 12
// #define BACKLIGHT_BREATHING // works, but BL_TOGG might not work // #define BACKLIGHT_BREATHING // Requires #4324 to enable hardware pwm for atmega32a
#define TAPPING_TOGGLE 3 /* RGB underglow */
// NOTE: for PS2AVRGB boards, underglow commands are sent via I2C to 0xB0.
#define RGBLED_NUM 5
#define RGBLIGHT_ANIMATIONS
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
#define NO_UART 1 #define NO_UART 1
/* RGB underglow */ /* key combination for magic key command */
// The RGB_DI_PIN value seems to be shared between all PS2AVRGB boards. /* defined by default; to change, uncomment and set to the combination you want */
// The same pin is used on the JJ40, at least. // #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
#define RGBLED_NUM 5
#define RGB_DI_PIN E2 // NOTE: for PS2AVRGB boards, underglow commands are sent via I2C to 0xB0.
#define RGBLIGHT_ANIMATIONS
#endif /* Bootmagic Lite key configuration */
// #define BOOTMAGIC_LITE_ROW 0
// #define BOOTMAGIC_LITE_COLUMN 0

View file

@ -1,104 +0,0 @@
/*
Copyright 2016 Luiz Ribeiro <luizribeiro@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 <util/twi.h>
#include "i2c.h"
void i2c_set_bitrate(uint16_t bitrate_khz) {
uint8_t bitrate_div = ((F_CPU / 1000l) / bitrate_khz);
if (bitrate_div >= 16) {
bitrate_div = (bitrate_div - 16) / 2;
}
TWBR = bitrate_div;
}
void i2c_init(void) {
// set pull-up resistors on I2C bus pins
PORTC |= 0b11;
i2c_set_bitrate(400);
// enable TWI (two-wire interface)
TWCR |= (1 << TWEN);
// enable TWI interrupt and slave address ACK
TWCR |= (1 << TWIE);
TWCR |= (1 << TWEA);
}
uint8_t i2c_start(uint8_t address) {
// reset TWI control register
TWCR = 0;
// begin transmission and wait for it to end
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
// check if the start condition was successfully transmitted
if ((TWSR & 0xF8) != TW_START) {
return 1;
}
// transmit address and wait
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) {
return 1;
}
return 0;
}
void i2c_stop(void) {
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
uint8_t i2c_write(uint8_t data) {
TWDR = data;
// transmit data and wait
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != TW_MT_DATA_ACK) {
return 1;
}
return 0;
}
uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length) {
if (i2c_start(address)) {
return 1;
}
for (uint16_t i = 0; i < length; i++) {
if (i2c_write(data[i])) {
return 1;
}
}
i2c_stop();
return 0;
}

View file

@ -1,25 +0,0 @@
/*
Copyright 2016 Luiz Ribeiro <luizribeiro@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/>.
*/
#ifndef __I2C_H__
#define __I2C_H__
void i2c_init(void);
void i2c_set_bitrate(uint16_t bitrate_khz);
uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length);
#endif

View file

@ -18,53 +18,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "jj40.h" #include "jj40.h"
#include <avr/pgmspace.h> #ifdef RGBLIGHT_ENABLE
#include "action_layer.h" #include <string.h>
#include "quantum.h" #include "i2c_master.h"
#include "rgblight.h"
#include "i2c.h" extern rgblight_config_t rgblight_config;
#include "backlight.h"
#include "backlight_custom.h"
// for keyboard subdirectory level init functions
// @Override
void matrix_init_kb(void) { void matrix_init_kb(void) {
i2c_init();
// call user level keymaps, if any // call user level keymaps, if any
matrix_init_user(); matrix_init_user();
} }
#ifdef BACKLIGHT_ENABLE
/// Overrides functions in `quantum.c`
void backlight_init_ports(void) {
b_led_init_ports();
}
void backlight_task(void) {
b_led_task();
}
void backlight_set(uint8_t level) {
b_led_set(level);
}
#endif
#ifdef RGBLIGHT_ENABLE
extern rgblight_config_t rgblight_config;
// custom RGB driver // custom RGB driver
void rgblight_set(void) { void rgblight_set(void) {
if (!rgblight_config.enable) { if (!rgblight_config.enable) {
for (uint8_t i=0; i<RGBLED_NUM; i++) { memset(led, 0, 3 * RGBLED_NUM);
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
}
} }
i2c_init(); i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100);
i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
} }
bool rgb_init = false; bool rgb_init = false;
@ -72,26 +45,12 @@ bool rgb_init = false;
void matrix_scan_kb(void) { void matrix_scan_kb(void) {
// if LEDs were previously on before poweroff, turn them back on // if LEDs were previously on before poweroff, turn them back on
if (rgb_init == false && rgblight_config.enable) { if (rgb_init == false && rgblight_config.enable) {
i2c_init(); i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100);
i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
rgb_init = true; rgb_init = true;
} }
rgblight_task(); rgblight_task();
#else
void matrix_scan_kb(void) {
#endif
matrix_scan_user(); matrix_scan_user();
/* Nothing else for now. */
} }
__attribute__((weak)) // overridable #endif
void matrix_init_user(void) {
}
__attribute__((weak)) // overridable
void matrix_scan_user(void) {
}

View file

@ -15,80 +15,68 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef KEYMAP_COMMON_H #pragma once
#define KEYMAP_COMMON_H
#include "quantum.h" #include "quantum.h"
#include "quantum_keycodes.h"
#include "keycode.h"
#include "action.h"
void matrix_init_user(void); // TODO port this to other PS2AVRGB boards
#define XXX KC_NO
#define ___ KC_NO
#define LAYOUT_ortho_4x12( \ #define LAYOUT_ortho_4x12( \
K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \
K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \
K31, K32, K33, K34, K35, K36, K37, K38, K39, K310, K311, K312 \ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B \
) \ ) \
{ \ { \
{ K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \
{ K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \
{ XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \
{ K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B } \
{ K312, K311, K310, K39, K35, K36, K37, K38, K34, K33, K32, K31 } \
} }
#define LAYOUT_planck_mit( \ #define LAYOUT_planck_mit( \
K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \
K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \
K31, K32, K33, K34, K35, K3X, K38, K39, K310, K311, K312 \ K30, K31, K32, K33, K34, K3X, K37, K38, K39, K3A, K3B \
) \ ) \
{ \ { \
{ K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \
{ K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \
{ XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \
{ K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K30, K31, K32, K33, K34, K3X, ___, K37, K38, K39, K3A, K3B } \
{ K312, K311, K310, K39, K35, K3X, XXX, K38, K34, K33, K32, K31 } \
} }
#define LAYOUT_planck_1x2uR( \ #define LAYOUT_planck_1x2uR( \
K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \
K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \
K31, K32, K33, K34, K35, K36, K3X, K39, K310, K311, K312 \ K30, K31, K32, K33, K34, K35, K3X, K38, K39, K3A, K3B \
) \ ) \
{ \ { \
{ K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \
{ K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \
{ XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \
{ K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K30, K31, K32, K33, K34, K35, K3X, ___, K38, K39, K3A, K3B } \
{ K312, K311, K310, K39, K35, K36, K3X, XXX, K34, K33, K32, K31 } \
} }
#define LAYOUT_kc( \ #define LAYOUT_kc( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \
) \ ) \
LAYOUT_ortho_4x12( \ LAYOUT_ortho_4x12( \
KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b, \ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b, \
KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b, \ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b, \
KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b, \ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b, \
KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b \ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b \
) )
#define LAYOUT LAYOUT_planck_mit #define LAYOUT LAYOUT_planck_mit
#define LAYOUT_kc_ortho_4x12 LAYOUT_kc #define LAYOUT_kc_ortho_4x12 LAYOUT_kc
#define KC_LAYOUT_ortho_4x12 LAYOUT_kc
#endif

View file

@ -1,16 +1,30 @@
/* Copyright 2019
*
* 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 #include QMK_KEYBOARD_H
enum layers {
#define _QWERTY 0 _QWERTY = 0,
#define _LOWER 1 _LOWER,
#define _RAISE 2 _RAISE,
_ADJUST,
enum custom_keycodes {
QWERTY = SAFE_RANGE,
LOWER,
RAISE,
}; };
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty /* Qwerty
* ,-----------------------------------------------------------------------------------. * ,-----------------------------------------------------------------------------------.
@ -27,7 +41,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, 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_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \ KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
_______, KC_LCTL, KC_LALT, KC_LGUI, MO(_LOWER), KC_SPC, MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ _______, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
), ),
/* Lower /* Lower
@ -64,10 +78,27 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \ _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
),
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = LAYOUT_ortho_4x12( \
_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
_______, _______, BL_TOGG, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, RGB_TOG, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
) )
}; };
// Loop uint32_t layer_state_set_user(uint32_t state) {
void matrix_scan_user(void) { return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
// Empty }
};

View file

@ -1,112 +0,0 @@
/*
Copyright 2017 Luiz Ribeiro <luizribeiro@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 <util/delay.h>
#include "matrix.h"
#ifndef DEBOUNCE
# define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
void matrix_set_row_status(uint8_t row);
uint8_t bit_reverse(uint8_t x);
void matrix_init(void) {
// all outputs for rows high
DDRB = 0xFF;
PORTB = 0xFF;
// all inputs for columns
DDRA = 0x00;
DDRC &= ~(0x111111<<2);
DDRD &= ~(1<<PIND7);
// all columns are pulled-up
PORTA = 0xFF;
PORTC |= (0b111111<<2);
PORTD |= (1<<PIND7);
// initialize matrix state: all keys off
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
matrix[row] = 0x00;
matrix_debouncing[row] = 0x00;
}
matrix_init_quantum();
}
uint8_t matrix_scan(void) {
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
matrix_set_row_status(row);
_delay_us(5);
matrix_row_t cols = (
// cols 0..7, PORTA 0 -> 7
(~PINA) & 0xFF
) | (
// cols 8..13, PORTC 7 -> 0
bit_reverse((~PINC) & 0xFF) << 8
) | (
// col 14, PORTD 7
((~PIND) & (1 << PIND7)) << 7
);
if (matrix_debouncing[row] != cols) {
matrix_debouncing[row] = cols;
debouncing = DEBOUNCE;
}
}
if (debouncing) {
if (--debouncing) {
_delay_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
}
}
matrix_scan_quantum();
return 1;
}
// declarations
void matrix_set_row_status(uint8_t row) {
DDRB = (1 << row);
PORTB = ~(1 << row);
}
uint8_t bit_reverse(uint8_t x) {
x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
return x;
}
inline matrix_row_t matrix_get_row(uint8_t row) {
return matrix[row];
}
void matrix_print(void) {
}

View file

@ -30,29 +30,29 @@ F_CPU = 12000000
# automatically (+60). See bootloader.mk for all options. # automatically (+60). See bootloader.mk for all options.
BOOTLOADER = bootloadHID BOOTLOADER = bootloadHID
# build options # Build Options
BOOTMAGIC_ENABLE = no # change yes to no to disable
MOUSEKEY_ENABLE = no #
EXTRAKEY_ENABLE = yes BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
CONSOLE_ENABLE = no MOUSEKEY_ENABLE = no # Mouse keys(+4700)
COMMAND_ENABLE = yes EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
BACKLIGHT_ENABLE = yes COMMAND_ENABLE = no # Commands for debug and configuration
BACKLIGHT_CUSTOM_DRIVER = yes
RGBLIGHT_ENABLE = yes
RGBLIGHT_CUSTOM_DRIVER = yes
KEY_LOCK_ENABLE = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # 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 = yes # Enable keyboard backlight functionality on B7 by default
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
RGBLIGHT_CUSTOM_DRIVER = yes
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)
OPT_DEFS = -DDEBUG_LEVEL=0 SRC += i2c_master.c
# custom matrix setup
CUSTOM_MATRIX = yes
SRC = matrix.c i2c.c backlight.c
# programming options # programming options
PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex

View file

@ -1125,6 +1125,13 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN;
# define COMxx1 COM1A1 # define COMxx1 COM1A1
# define OCRxx OCR3A # define OCRxx OCR3A
# define ICRx ICR3 # define ICRx ICR3
#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
# define TCCRxA TCCR1A
# define TCCRxB TCCR1B
# define COMxx1 COM1B1
# define OCRxx OCR1B
# define ICRx ICR1
# define TIMSK1 TIMSK
#else #else
# define NO_HARDWARE_PWM # define NO_HARDWARE_PWM
#endif #endif