[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
12 files changed, 143 insertions(+), 763 deletions(-) D keyboards/jj40/backlight.c D keyboards/jj40/backlight_custom.h D keyboards/jj40/breathing_custom.h M keyboards/jj40/config.h D keyboards/jj40/i2c.c D keyboards/jj40/i2c.h M keyboards/jj40/jj40.c M keyboards/jj40/jj40.h M keyboards/jj40/keymaps/default/keymap.c D keyboards/jj40/matrix.c M keyboards/jj40/rules.mk M quantum/quantum.c
D keyboards/jj40/backlight.c => keyboards/jj40/backlight.c +0 -213
@@ 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
D keyboards/jj40/backlight_custom.h => keyboards/jj40/backlight_custom.h +0 -15
@@ 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
D keyboards/jj40/breathing_custom.h => keyboards/jj40/breathing_custom.h +0 -140
@@ 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
M keyboards/jj40/config.h => keyboards/jj40/config.h +22 -18
@@ 1,51 1,55 @@ /* 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 "config_common.h" #pragma once #ifndef CONFIG_H #define CONFIG_H #include "config_common.h" #define VENDOR_ID 0x20A0 #define PRODUCT_ID 0x422D // TODO: share these strings with usbconfig.h // Edit usbconfig.h to change these. #define MANUFACTURER winkeyless.kr #define MANUFACTURER Kprepublic #define PRODUCT jj40 /* matrix size */ #define MATRIX_ROWS 8 #define MATRIX_COLS 15 #define MATRIX_ROWS 4 #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 */ #define DIODE_DIRECTION COL2ROW #define BACKLIGHT_PIN D4 #define BACKLIGHT_LEVELS 12 // #define BACKLIGHT_BREATHING // works, but BL_TOGG might not work #define TAPPING_TOGGLE 3 #define NO_UART 1 // #define BACKLIGHT_BREATHING // Requires #4324 to enable hardware pwm for atmega32a /* RGB underglow */ // The RGB_DI_PIN value seems to be shared between all PS2AVRGB boards. // The same pin is used on the JJ40, at least. // NOTE: for PS2AVRGB boards, underglow commands are sent via I2C to 0xB0. #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 /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCING_DELAY 5 #define NO_UART 1 /* key combination for magic key command */ /* defined by default; to change, uncomment and set to the combination you want */ // #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) /* Bootmagic Lite key configuration */ // #define BOOTMAGIC_LITE_ROW 0 // #define BOOTMAGIC_LITE_COLUMN 0
D keyboards/jj40/i2c.c => keyboards/jj40/i2c.c +0 -104
@@ 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; }
D keyboards/jj40/i2c.h => keyboards/jj40/i2c.h +0 -25
@@ 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
M keyboards/jj40/jj40.c => keyboards/jj40/jj40.c +10 -51
@@ 18,53 18,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "jj40.h" #include <avr/pgmspace.h> #include "action_layer.h" #include "quantum.h" #ifdef RGBLIGHT_ENABLE #include "i2c.h" #include <string.h> #include "i2c_master.h" #include "rgblight.h" #include "backlight.h" #include "backlight_custom.h" extern rgblight_config_t rgblight_config; // for keyboard subdirectory level init functions // @Override void matrix_init_kb(void) { i2c_init(); // call user level keymaps, if any 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 void rgblight_set(void) { if (!rgblight_config.enable) { for (uint8_t i=0; i<RGBLED_NUM; i++) { led[i].r = 0; led[i].g = 0; led[i].b = 0; } memset(led, 0, 3 * RGBLED_NUM); } i2c_init(); i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM); i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100); } @@ bool rgb_init = false; 72,26 45,12 @@ bool rgb_init = false; void matrix_scan_kb(void) { // if LEDs were previously on before poweroff, turn them back on if (rgb_init == false && rgblight_config.enable) { i2c_init(); i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM); i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100); rgb_init = true; } rgblight_task(); #else void matrix_scan_kb(void) { #endif matrix_scan_user(); /* Nothing else for now. */ } __attribute__((weak)) // overridable void matrix_init_user(void) { } __attribute__((weak)) // overridable void matrix_scan_user(void) { } #endif
M keyboards/jj40/jj40.h => keyboards/jj40/jj40.h +37 -49
@@ 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/>. */ #ifndef KEYMAP_COMMON_H #define KEYMAP_COMMON_H #pragma once #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( \ K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K31, K32, K33, K34, K35, K36, K37, K38, K39, K310, K311, K312 \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B \ ) \ { \ { K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K312, K311, K310, K39, K35, K36, K37, K38, K34, K33, K32, K31 } \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B } \ } #define LAYOUT_planck_mit( \ K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K31, K32, K33, K34, K35, K3X, K38, K39, K310, K311, K312 \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ K30, K31, K32, K33, K34, K3X, K37, K38, K39, K3A, K3B \ ) \ { \ { K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K312, K311, K310, K39, K35, K3X, XXX, K38, K34, K33, K32, K31 } \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ { K30, K31, K32, K33, K34, K3X, ___, K37, K38, K39, K3A, K3B } \ } #define LAYOUT_planck_1x2uR( \ K01, K02, K03, K04, K05, K06, K07, K08, K09, K010, K011, K012, \ K11, K12, K13, K14, K15, K16, K17, K18, K19, K110, K111, K112, \ K21, K22, K23, K24, K25, K26, K27, K28, K29, K210, K211, K212, \ K31, K32, K33, K34, K35, K36, K3X, K39, K310, K311, K312 \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ K30, K31, K32, K33, K34, K35, K3X, K38, K39, K3A, K3B \ ) \ { \ { K012, K011, K010, K09, K05, K06, K07, K08, K04, K03, K02, K01 }, \ { K112, K111, K110, K19, K15, K16, K17, K18, K14, K13, K12, K11 }, \ { XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \ { K212, K211, K210, K29, K25, K26, K27, K28, K24, K23, K22, K21 }, \ { K312, K311, K310, K39, K35, K36, K3X, XXX, K34, K33, K32, K31 } \ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ { K30, K31, K32, K33, K34, K35, K3X, ___, K38, K39, K3A, K3B } \ } #define LAYOUT_kc( \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \ ) \ 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_##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_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \ ) \ 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_##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_##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_kc_ortho_4x12 LAYOUT_kc #endif #define KC_LAYOUT_ortho_4x12 LAYOUT_kc
M keyboards/jj40/keymaps/default/keymap.c => keyboards/jj40/keymaps/default/keymap.c +45 -14
@@ 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 #define _QWERTY 0 #define _LOWER 1 #define _RAISE 2 enum custom_keycodes { QWERTY = SAFE_RANGE, LOWER, RAISE, enum layers { _QWERTY = 0, _LOWER, _RAISE, _ADJUST, }; #define LOWER MO(_LOWER) #define RAISE MO(_RAISE) const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* 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_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_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 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_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, 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 void matrix_scan_user(void) { // Empty }; uint32_t layer_state_set_user(uint32_t state) { return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); }
D keyboards/jj40/matrix.c => keyboards/jj40/matrix.c +0 -112
@@ 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) { }
M keyboards/jj40/rules.mk => keyboards/jj40/rules.mk +22 -22
@@ 30,29 30,29 @@ F_CPU = 12000000 # automatically (+60). See bootloader.mk for all options. BOOTLOADER = bootloadHID # build options BOOTMAGIC_ENABLE = no MOUSEKEY_ENABLE = no EXTRAKEY_ENABLE = yes CONSOLE_ENABLE = no COMMAND_ENABLE = yes BACKLIGHT_ENABLE = yes BACKLIGHT_CUSTOM_DRIVER = yes RGBLIGHT_ENABLE = yes RGBLIGHT_CUSTOM_DRIVER = yes KEY_LOCK_ENABLE = yes # 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 OPT_DEFS = -DDEBUG_LEVEL=0 # custom matrix setup CUSTOM_MATRIX = yes SRC = matrix.c i2c.c backlight.c 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) SRC += i2c_master.c # programming options PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex
M quantum/quantum.c => quantum/quantum.c +7 -0
@@ 1125,6 1125,13 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN; # define COMxx1 COM1A1 # define OCRxx OCR3A # 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 # define NO_HARDWARE_PWM #endif