/* * WARNING: be careful changing this code, it is very timing dependent * * 2018-10-28 checked * avr-gcc 4.9.2 * avr-gcc 5.4.0 * avr-gcc 7.3.0 */ #ifndef F_CPU #define F_CPU 16000000 #endif #include #include #include #include #include #include "serial.h" //#include #ifdef SOFT_SERIAL_PIN #ifdef __AVR_ATmega32U4__ // if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial. #ifdef USE_AVR_I2C #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1 #error Using ATmega32U4 I2C, so can not use PD0, PD1 #endif #endif #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3 #define SERIAL_PIN_DDR DDRD #define SERIAL_PIN_PORT PORTD #define SERIAL_PIN_INPUT PIND #if SOFT_SERIAL_PIN == D0 #define SERIAL_PIN_MASK _BV(PD0) #define EIMSK_BIT _BV(INT0) #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) #define SERIAL_PIN_INTERRUPT INT0_vect #elif SOFT_SERIAL_PIN == D1 #define SERIAL_PIN_MASK _BV(PD1) #define EIMSK_BIT _BV(INT1) #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) #define SERIAL_PIN_INTERRUPT INT1_vect #elif SOFT_SERIAL_PIN == D2 #define SERIAL_PIN_MASK _BV(PD2) #define EIMSK_BIT _BV(INT2) #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) #define SERIAL_PIN_INTERRUPT INT2_vect #elif SOFT_SERIAL_PIN == D3 #define SERIAL_PIN_MASK _BV(PD3) #define EIMSK_BIT _BV(INT3) #define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) #define SERIAL_PIN_INTERRUPT INT3_vect #endif #elif SOFT_SERIAL_PIN == E6 #define SERIAL_PIN_DDR DDRE #define SERIAL_PIN_PORT PORTE #define SERIAL_PIN_INPUT PINE #define SERIAL_PIN_MASK _BV(PE6) #define EIMSK_BIT _BV(INT6) #define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) #define SERIAL_PIN_INTERRUPT INT6_vect #else #error invalid SOFT_SERIAL_PIN value #endif #else #error serial.c now support ATmega32U4 only #endif #define ALWAYS_INLINE __attribute__((always_inline)) #define NO_INLINE __attribute__((noinline)) #define _delay_sub_us(x) __builtin_avr_delay_cycles(x) // parity check #define ODD_PARITY 1 #define EVEN_PARITY 0 #define PARITY EVEN_PARITY #ifdef SERIAL_DELAY // custom setup in config.h // #define TID_SEND_ADJUST 2 // #define SERIAL_DELAY 6 // micro sec // #define READ_WRITE_START_ADJUST 30 // cycles // #define READ_WRITE_WIDTH_ADJUST 8 // cycles #else // ============ Standard setups ============ #ifndef SELECT_SOFT_SERIAL_SPEED #define SELECT_SOFT_SERIAL_SPEED 1 // 0: about 189kbps (Experimental only) // 1: about 137kbps (default) // 2: about 75kbps // 3: about 39kbps // 4: about 26kbps // 5: about 20kbps #endif #if __GNUC__ < 6 #define TID_SEND_ADJUST 14 #else #define TID_SEND_ADJUST 2 #endif #if SELECT_SOFT_SERIAL_SPEED == 0 // Very High speed #define SERIAL_DELAY 4 // micro sec #if __GNUC__ < 6 #define READ_WRITE_START_ADJUST 33 // cycles #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_START_ADJUST 34 // cycles #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #elif SELECT_SOFT_SERIAL_SPEED == 1 // High speed #define SERIAL_DELAY 6 // micro sec #if __GNUC__ < 6 #define READ_WRITE_START_ADJUST 30 // cycles #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_START_ADJUST 33 // cycles #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #elif SELECT_SOFT_SERIAL_SPEED == 2 // Middle speed #define SERIAL_DELAY 12 // micro sec #define READ_WRITE_START_ADJUST 30 // cycles #if __GNUC__ < 6 #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #elif SELECT_SOFT_SERIAL_SPEED == 3 // Low speed #define SERIAL_DELAY 24 // micro sec #define READ_WRITE_START_ADJUST 30 // cycles #if __GNUC__ < 6 #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #elif SELECT_SOFT_SERIAL_SPEED == 4 // Very Low speed #define SERIAL_DELAY 36 // micro sec #define READ_WRITE_START_ADJUST 30 // cycles #if __GNUC__ < 6 #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #elif SELECT_SOFT_SERIAL_SPEED == 5 // Ultra Low speed #define SERIAL_DELAY 48 // micro sec #define READ_WRITE_START_ADJUST 30 // cycles #if __GNUC__ < 6 #define READ_WRITE_WIDTH_ADJUST 3 // cycles #else #define READ_WRITE_WIDTH_ADJUST 7 // cycles #endif #else #error invalid SELECT_SOFT_SERIAL_SPEED value #endif /* SELECT_SOFT_SERIAL_SPEED */ #endif /* SERIAL_DELAY */ #define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) #define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) #define SLAVE_INT_WIDTH_US 1 #ifndef SERIAL_USE
/* Copyright 2016 Jack Humbert
 *
 * 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 "process_leader.h"

__attribute__ ((weak))
void leader_start(void) {}

__attribute__ ((weak))
void leader_end(void) {}

// Leader key stuff
bool leading = false;
uint16_t leader_time = 0;

uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};
uint8_t leader_sequence_size = 0;

bool process_leader(uint16_t keycode, keyrecord_t *record) {
  // Leader key set-up
  if (record->event.pressed) {
    if (!leading && keycode == KC_LEAD) {
      leader_start();
      leading = true;
      leader_time = timer_read();
      leader_sequence_size = 0;
      leader_sequence[0] = 0;
      leader_sequence[1] = 0;
      leader_sequence[2] = 0;
      leader_sequence[3] = 0;
      leader_sequence[4] = 0;
      return false;
    }
    if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
      leader_sequence[leader_sequence_size] = keycode;
      leader_sequence_size++;
      return false;
    }
  }
  return true;
}