Преглед на файлове

[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
zvecr преди 6 години
родител
ревизия
91b18e263f

+ 0 - 213
keyboards/jj40/backlight.c

@@ -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

+ 0 - 15
keyboards/jj40/backlight_custom.h

@@ -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

+ 0 - 140
keyboards/jj40/breathing_custom.h

@@ -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

+ 22 - 18
keyboards/jj40/config.h

@@ -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
-#define CONFIG_H
+#include "config_common.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_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 */
 /* 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 TAPPING_TOGGLE 3
-
-#define NO_UART 1
+// #define BACKLIGHT_BREATHING  // Requires #4324 to enable hardware pwm for atmega32a
 
 
 /* RGB underglow */
 /* 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 RGBLED_NUM 5
-#define RGB_DI_PIN E2 // NOTE: for PS2AVRGB boards, underglow commands are sent via I2C to 0xB0.
 #define RGBLIGHT_ANIMATIONS
 #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

+ 0 - 104
keyboards/jj40/i2c.c

@@ -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;
-}

+ 0 - 25
keyboards/jj40/i2c.h

@@ -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

+ 10 - 51
keyboards/jj40/jj40.c

@@ -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>
-
-#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) {
 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++) {
-      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;
 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_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
+    i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100);
     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
-void matrix_init_user(void) {
-
 }
 }
 
 
-
-__attribute__((weak)) // overridable
-void matrix_scan_user(void) {
-
-}
+#endif

+ 37 - 49
keyboards/jj40/jj40.h

@@ -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
-#define KEYMAP_COMMON_H
+#pragma once
 
 
 #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, \
-    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( \
 #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( \
 #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( \
 #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 LAYOUT_planck_mit
-
 #define LAYOUT_kc_ortho_4x12 LAYOUT_kc
 #define LAYOUT_kc_ortho_4x12 LAYOUT_kc
-
-#endif
+#define KC_LAYOUT_ortho_4x12 LAYOUT_kc

+ 45 - 14
keyboards/jj40/keymaps/default/keymap.c

@@ -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
 
 
-
-#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] = {
 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
-void matrix_scan_user(void) {
-  // Empty
-};
+uint32_t layer_state_set_user(uint32_t state) {
+  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}

+ 0 - 112
keyboards/jj40/matrix.c

@@ -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) {
-}

+ 22 - 22
keyboards/jj40/rules.mk

@@ -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
-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
 # 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
 # programming options
 PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex
 PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex

+ 7 - 0
quantum/quantum.c

@@ -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