diff options
Diffstat (limited to 'quantum')
70 files changed, 3330 insertions, 1292 deletions
diff --git a/quantum/api.h b/quantum/api.h index efc0ddca12..fc016391bc 100644 --- a/quantum/api.h +++ b/quantum/api.h @@ -17,7 +17,9 @@  #ifndef _API_H_  #define _API_H_ +#ifdef __AVR__  #include "lufa.h" +#endif  enum MESSAGE_TYPE {      MT_GET_DATA =      0x10, // Get data from keyboard @@ -28,7 +30,7 @@ enum MESSAGE_TYPE {      MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK)      MT_EXE_ACTION =    0x40, // executing actions on keyboard      MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) -    MT_TYPE_ERROR =    0x80 // type not recofgnised (ACK) +    MT_TYPE_ERROR =    0x80 // type not recognised (ACK)  };  enum DATA_TYPE { diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index c948a60d6c..6d6833ec11 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -223,7 +223,7 @@ void audio_init()              TCCR1B = (1 << WGM13)  | (1 << WGM12)  | (0 << CS12)  | (1 << CS11) | (0 << CS10);              TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));              TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); -        #endif  +        #endif          audio_initialized = true;      } @@ -231,7 +231,7 @@ void audio_init()      if (audio_config.enable) {          PLAY_SONG(startup_song);      } -     +  }  void stop_all_notes() @@ -464,7 +464,7 @@ ISR(TIMER3_AUDIO_vect)          note_position++;          bool end_of_note = false;          if (TIMER_3_PERIOD > 0) { -            if (!note_resting)  +            if (!note_resting)                  end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));              else                  end_of_note = (note_position >= (note_length)); @@ -604,7 +604,7 @@ ISR(TIMER1_AUDIO_vect)          note_position++;          bool end_of_note = false;          if (TIMER_1_PERIOD > 0) { -            if (!note_resting)  +            if (!note_resting)                  end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));              else                  end_of_note = (note_position >= (note_length)); diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index da09b2bcd2..8136c5b258 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -40,7 +40,8 @@ typedef union {      uint8_t raw;      struct {          bool    enable :1; -        uint8_t level  :7; +        bool    clicky_enable :1; +        uint8_t level  :6;      };  } audio_config_t; diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c index d38184f323..989f7a64be 100644 --- a/quantum/audio/audio_arm.c +++ b/quantum/audio/audio_arm.c @@ -80,6 +80,9 @@ float startup_song[][2] = STARTUP_SONG;  static void gpt_cb8(GPTDriver *gptp);  #define DAC_BUFFER_SIZE 720 +#ifndef DAC_SAMPLE_MAX +#define DAC_SAMPLE_MAX  65535U +#endif  #define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \      gptStartContinuous(&GPTD6, 2U) @@ -202,132 +205,16 @@ GPTConfig gpt8cfg1 = {  // squarewave  static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, - -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, -    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, -    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +  // First half is max, second half is 0 +  [0                 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX, +  [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE  -1] = 0,  };  // squarewave  static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { - -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, -    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, -    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -   0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, -  2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047 +  // opposite of dac_buffer above +  [0                 ... DAC_BUFFER_SIZE/2-1] = 0, +  [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE  -1] = DAC_SAMPLE_MAX,  };  /* @@ -363,7 +250,7 @@ static void error_cb1(DACDriver *dacp, dacerror_t err) {  }  static const DACConfig dac1cfg1 = { -  .init         = 2047U, +  .init         = DAC_SAMPLE_MAX,    .datamode     = DAC_DHRM_12BIT_RIGHT  }; @@ -375,7 +262,7 @@ static const DACConversionGroup dacgrpcfg1 = {  };  static const DACConfig dac1cfg2 = { -  .init         = 2047U, +  .init         = DAC_SAMPLE_MAX,    .datamode     = DAC_DHRM_12BIT_RIGHT  }; diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index e63616a994..9946084977 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h @@ -472,4 +472,34 @@      H__NOTE(_AS4), W__NOTE(_GS4), W__NOTE(_GS4), W__NOTE(_FS4), W__NOTE(_GS4), \      H__NOTE(_AS4), WD_NOTE(_DS4) +#define RICK_ROLL      \ +    Q__NOTE(_F4),      \ +    Q__NOTE(_G4),      \ +    Q__NOTE(_BF4),     \ +    Q__NOTE(_G4),      \ +    HD_NOTE(_D5),      \ +    HD_NOTE(_D5),      \ +    W__NOTE(_C5),      \ +    S__NOTE(_REST),    \ +    Q__NOTE(_F4),      \ +    Q__NOTE(_G4),      \ +    Q__NOTE(_BF4),     \ +    Q__NOTE(_G4),      \ +    HD_NOTE(_C5),      \ +    HD_NOTE(_C5),      \ +    W__NOTE(_BF4),     \ +    S__NOTE(_REST),    \ +    Q__NOTE(_F4),      \ +    Q__NOTE(_G4),      \ +    Q__NOTE(_BF4),     \ +    Q__NOTE(_G4),      \ +    W__NOTE(_BF4),     \ +    H__NOTE(_C5),      \ +    H__NOTE(_A4),      \ +    H__NOTE(_A4),      \ +    H__NOTE(_G4),      \ +    H__NOTE(_F4),      \ +    H__NOTE(_F4),      \ +    W__NOTE(_C5),      \ +    W__NOTE(_BF4),   #endif diff --git a/quantum/config_common.h b/quantum/config_common.h index f6f51b367d..cbff372eaf 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -1,4 +1,4 @@ -/* Copyright 2015-2017 Jack Humbert +/* Copyright 2015-2018 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 @@ -14,8 +14,7 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef CONFIG_DEFINITIONS_H -#define CONFIG_DEFINITIONS_H +#pragma once  /* diode directions */  #define COL2ROW       0 @@ -23,57 +22,205 @@  #define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */  #ifdef __AVR__ -  /* I/O pins */ -  #ifndef F0 -      #define B0 0x30 -      #define B1 0x31 -      #define B2 0x32 -      #define B3 0x33 -      #define B4 0x34 -      #define B5 0x35 -      #define B6 0x36 -      #define B7 0x37 -      #define C0 0x60 -      #define C1 0x61 -      #define C2 0x62 -      #define C3 0x63 -      #define C4 0x64 -      #define C5 0x65 -      #define C6 0x66 -      #define C7 0x67 -      #define D0 0x90 -      #define D1 0x91 -      #define D2 0x92 -      #define D3 0x93 -      #define D4 0x94 -      #define D5 0x95 -      #define D6 0x96 -      #define D7 0x97 -      #define E0 0xC0 -      #define E1 0xC1 -      #define E2 0xC2 -      #define E3 0xC3 -      #define E4 0xC4 -      #define E5 0xC5 -      #define E6 0xC6 -      #define E7 0xC7 -      #define F0 0xF0 -      #define F1 0xF1 -      #define F2 0xF2 -      #define F3 0xF3 -      #define F4 0xF4 -      #define F5 0xF5 -      #define F6 0xF6 -      #define F7 0xF7 -      #define A0 0x00 -      #define A1 0x01 -      #define A2 0x02 -      #define A3 0x03 -      #define A4 0x04 -      #define A5 0x05 -      #define A6 0x06 -      #define A7 0x07 -  #endif +    #ifndef __ASSEMBLER__ +      #include <avr/io.h> +    #endif +    #define PORT_SHIFTER 4 // this may be 4 for all AVR chips + +    // If you want to add more to this list, reference the PINx definitions in these header +    // files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr + +    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) +        #define ADDRESS_BASE 0x00 +        #define PINB_ADDRESS 0x3 +        #define PINC_ADDRESS 0x6 +        #define PIND_ADDRESS 0x9 +        #define PINE_ADDRESS 0xC +        #define PINF_ADDRESS 0xF +    #elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) +        #define ADDRESS_BASE 0x00 +        #define PINB_ADDRESS 0x3 +        #define PINC_ADDRESS 0x6 +        #define PIND_ADDRESS 0x9 +    #elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) +        #define ADDRESS_BASE 0x00 +        #define PINA_ADDRESS 0x0 +        #define PINB_ADDRESS 0x3 +        #define PINC_ADDRESS 0x6 +        #define PIND_ADDRESS 0x9 +        #define PINE_ADDRESS 0xC +        #define PINF_ADDRESS 0xF +    #elif defined(__AVR_ATmega32A__) +        #define ADDRESS_BASE 0x10 +        #define PIND_ADDRESS 0x0 +        #define PINC_ADDRESS 0x3 +        #define PINB_ADDRESS 0x6 +        #define PINA_ADDRESS 0x9 +    #else +        #error "Pins are not defined" +    #endif + +    /* I/O pins */ +    #define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin) + +    #ifdef PORTA +        #define A0 PINDEF(A, 0) +        #define A1 PINDEF(A, 1) +        #define A2 PINDEF(A, 2) +        #define A3 PINDEF(A, 3) +        #define A4 PINDEF(A, 4) +        #define A5 PINDEF(A, 5) +        #define A6 PINDEF(A, 6) +        #define A7 PINDEF(A, 7) +    #endif +    #ifdef PORTB +        #define B0 PINDEF(B, 0) +        #define B1 PINDEF(B, 1) +        #define B2 PINDEF(B, 2) +        #define B3 PINDEF(B, 3) +        #define B4 PINDEF(B, 4) +        #define B5 PINDEF(B, 5) +        #define B6 PINDEF(B, 6) +        #define B7 PINDEF(B, 7) +    #endif +    #ifdef PORTC +        #define C0 PINDEF(C, 0) +        #define C1 PINDEF(C, 1) +        #define C2 PINDEF(C, 2) +        #define C3 PINDEF(C, 3) +        #define C4 PINDEF(C, 4) +        #define C5 PINDEF(C, 5) +        #define C6 PINDEF(C, 6) +        #define C7 PINDEF(C, 7) +    #endif +    #ifdef PORTD +        #define D0 PINDEF(D, 0) +        #define D1 PINDEF(D, 1) +        #define D2 PINDEF(D, 2) +        #define D3 PINDEF(D, 3) +        #define D4 PINDEF(D, 4) +        #define D5 PINDEF(D, 5) +        #define D6 PINDEF(D, 6) +        #define D7 PINDEF(D, 7) +    #endif +    #ifdef PORTE +        #define E0 PINDEF(E, 0) +        #define E1 PINDEF(E, 1) +        #define E2 PINDEF(E, 2) +        #define E3 PINDEF(E, 3) +        #define E4 PINDEF(E, 4) +        #define E5 PINDEF(E, 5) +        #define E6 PINDEF(E, 6) +        #define E7 PINDEF(E, 7) +    #endif +    #ifdef PORTF +        #define F0 PINDEF(F, 0) +        #define F1 PINDEF(F, 1) +        #define F2 PINDEF(F, 2) +        #define F3 PINDEF(F, 3) +        #define F4 PINDEF(F, 4) +        #define F5 PINDEF(F, 5) +        #define F6 PINDEF(F, 6) +        #define F7 PINDEF(F, 7) +    #endif + +#elif defined(PROTOCOL_CHIBIOS) +    #define A0  PAL_LINE(GPIOA, 0) +    #define A1  PAL_LINE(GPIOA, 1) +    #define A2  PAL_LINE(GPIOA, 2) +    #define A3  PAL_LINE(GPIOA, 3) +    #define A4  PAL_LINE(GPIOA, 4) +    #define A5  PAL_LINE(GPIOA, 5) +    #define A6  PAL_LINE(GPIOA, 6) +    #define A7  PAL_LINE(GPIOA, 7) +    #define A8  PAL_LINE(GPIOA, 8) +    #define A9  PAL_LINE(GPIOA, 9) +    #define A10 PAL_LINE(GPIOA, 10) +    #define A11 PAL_LINE(GPIOA, 11) +    #define A12 PAL_LINE(GPIOA, 12) +    #define A13 PAL_LINE(GPIOA, 13) +    #define A14 PAL_LINE(GPIOA, 14) +    #define A15 PAL_LINE(GPIOA, 15) +    #define B0  PAL_LINE(GPIOB, 0) +    #define B1  PAL_LINE(GPIOB, 1) +    #define B2  PAL_LINE(GPIOB, 2) +    #define B3  PAL_LINE(GPIOB, 3) +    #define B4  PAL_LINE(GPIOB, 4) +    #define B5  PAL_LINE(GPIOB, 5) +    #define B6  PAL_LINE(GPIOB, 6) +    #define B7  PAL_LINE(GPIOB, 7) +    #define B8  PAL_LINE(GPIOB, 8) +    #define B9  PAL_LINE(GPIOB, 9) +    #define B10 PAL_LINE(GPIOB, 10) +    #define B11 PAL_LINE(GPIOB, 11) +    #define B12 PAL_LINE(GPIOB, 12) +    #define B13 PAL_LINE(GPIOB, 13) +    #define B14 PAL_LINE(GPIOB, 14) +    #define B15 PAL_LINE(GPIOB, 15) +    #define C0  PAL_LINE(GPIOC, 0) +    #define C1  PAL_LINE(GPIOC, 1) +    #define C2  PAL_LINE(GPIOC, 2) +    #define C3  PAL_LINE(GPIOC, 3) +    #define C4  PAL_LINE(GPIOC, 4) +    #define C5  PAL_LINE(GPIOC, 5) +    #define C6  PAL_LINE(GPIOC, 6) +    #define C7  PAL_LINE(GPIOC, 7) +    #define C8  PAL_LINE(GPIOC, 8) +    #define C9  PAL_LINE(GPIOC, 9) +    #define C10 PAL_LINE(GPIOC, 10) +    #define C11 PAL_LINE(GPIOC, 11) +    #define C12 PAL_LINE(GPIOC, 12) +    #define C13 PAL_LINE(GPIOC, 13) +    #define C14 PAL_LINE(GPIOC, 14) +    #define C15 PAL_LINE(GPIOC, 15) +    #define D0  PAL_LINE(GPIOD, 0) +    #define D1  PAL_LINE(GPIOD, 1) +    #define D2  PAL_LINE(GPIOD, 2) +    #define D3  PAL_LINE(GPIOD, 3) +    #define D4  PAL_LINE(GPIOD, 4) +    #define D5  PAL_LINE(GPIOD, 5) +    #define D6  PAL_LINE(GPIOD, 6) +    #define D7  PAL_LINE(GPIOD, 7) +    #define D8  PAL_LINE(GPIOD, 8) +    #define D9  PAL_LINE(GPIOD, 9) +    #define D10 PAL_LINE(GPIOD, 10) +    #define D11 PAL_LINE(GPIOD, 11) +    #define D12 PAL_LINE(GPIOD, 12) +    #define D13 PAL_LINE(GPIOD, 13) +    #define D14 PAL_LINE(GPIOD, 14) +    #define D15 PAL_LINE(GPIOD, 15) +    #define E0  PAL_LINE(GPIOE, 0) +    #define E1  PAL_LINE(GPIOE, 1) +    #define E2  PAL_LINE(GPIOE, 2) +    #define E3  PAL_LINE(GPIOE, 3) +    #define E4  PAL_LINE(GPIOE, 4) +    #define E5  PAL_LINE(GPIOE, 5) +    #define E6  PAL_LINE(GPIOE, 6) +    #define E7  PAL_LINE(GPIOE, 7) +    #define E8  PAL_LINE(GPIOE, 8) +    #define E9  PAL_LINE(GPIOE, 9) +    #define E10 PAL_LINE(GPIOE, 10) +    #define E11 PAL_LINE(GPIOE, 11) +    #define E12 PAL_LINE(GPIOE, 12) +    #define E13 PAL_LINE(GPIOE, 13) +    #define E14 PAL_LINE(GPIOE, 14) +    #define E15 PAL_LINE(GPIOE, 15) +    #define F0  PAL_LINE(GPIOF, 0) +    #define F1  PAL_LINE(GPIOF, 1) +    #define F2  PAL_LINE(GPIOF, 2) +    #define F3  PAL_LINE(GPIOF, 3) +    #define F4  PAL_LINE(GPIOF, 4) +    #define F5  PAL_LINE(GPIOF, 5) +    #define F6  PAL_LINE(GPIOF, 6) +    #define F7  PAL_LINE(GPIOF, 7) +    #define F8  PAL_LINE(GPIOF, 8) +    #define F9  PAL_LINE(GPIOF, 9) +    #define F10 PAL_LINE(GPIOF, 10) +    #define F11 PAL_LINE(GPIOF, 11) +    #define F12 PAL_LINE(GPIOF, 12) +    #define F13 PAL_LINE(GPIOF, 13) +    #define F14 PAL_LINE(GPIOF, 14) +    #define F15 PAL_LINE(GPIOF, 15)  #endif  /* USART configuration */ @@ -103,5 +250,3 @@  #define API_SYSEX_MAX_SIZE 32  #include "song_list.h" - -#endif diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c new file mode 100644 index 0000000000..14627a93d6 --- /dev/null +++ b/quantum/dynamic_keymap.c @@ -0,0 +1,230 @@ +/* Copyright 2017 Jason Williams (Wilba) + * + * 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.h" +#include "keymap.h" // to get keymaps[][][] +#include "tmk_core/common/eeprom.h" +#include "progmem.h" // to read default from flash +#include "quantum.h" // for send_string() +#include "dynamic_keymap.h" + +#ifdef DYNAMIC_KEYMAP_ENABLE + +#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR +#error DYNAMIC_KEYMAP_EEPROM_ADDR not defined +#endif + +#ifndef DYNAMIC_KEYMAP_LAYER_COUNT +#error DYNAMIC_KEYMAP_LAYER_COUNT not defined +#endif + +#ifndef DYNAMIC_KEYMAP_MACRO_COUNT +#error DYNAMIC_KEYMAP_MACRO_COUNT not defined +#endif + +#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR +#error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined +#endif + +#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE +#error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined +#endif + +uint8_t dynamic_keymap_get_layer_count(void) +{ +	return DYNAMIC_KEYMAP_LAYER_COUNT; +} + +void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) +{ +	// TODO: optimize this with some left shifts +	return ((void*)DYNAMIC_KEYMAP_EEPROM_ADDR) + ( layer * MATRIX_ROWS * MATRIX_COLS * 2 ) + +		( row * MATRIX_COLS * 2 ) + ( column * 2 ); +} + +uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) +{ +	void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); +	// Big endian, so we can read/write EEPROM directly from host if we want +	uint16_t keycode = eeprom_read_byte(address) << 8; +	keycode |= eeprom_read_byte(address + 1); +	return keycode; +} + +void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) +{ +	void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); +	// Big endian, so we can read/write EEPROM directly from host if we want +	eeprom_update_byte(address, (uint8_t)(keycode >> 8)); +	eeprom_update_byte(address+1, (uint8_t)(keycode & 0xFF)); +} + +void dynamic_keymap_reset(void) +{ +	// Reset the keymaps in EEPROM to what is in flash. +	// All keyboards using dynamic keymaps should define a layout +	// for the same number of layers as DYNAMIC_KEYMAP_LAYER_COUNT. +	for ( int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++ )	{ +		for ( int row = 0; row < MATRIX_ROWS; row++ ) { +			for ( int column = 0; column < MATRIX_COLS; column++ )	{ +				dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column])); +			} +		} +	} +} + +void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ) +{ +	uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; +	void *source = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset); +	uint8_t *target = data; +	for ( uint16_t i = 0; i < size; i++ ) { +		if ( offset + i < dynamic_keymap_eeprom_size ) { +			*target = eeprom_read_byte(source); +		} else { +			*target = 0x00; +		} +		source++; +		target++; +	} +} + +void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ) +{ +	uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; +	void *target = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset); +	uint8_t *source = data; +	for ( uint16_t i = 0; i < size; i++ ) { +		if ( offset + i < dynamic_keymap_eeprom_size ) { +			eeprom_update_byte(target, *source); +		} +		source++; +		target++; +	} +} + +// This overrides the one in quantum/keymap_common.c +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) +{ +	if ( layer < DYNAMIC_KEYMAP_LAYER_COUNT && +			key.row < MATRIX_ROWS && +			key.col < MATRIX_COLS ) { +		return dynamic_keymap_get_keycode(layer, key.row, key.col); +	} else { +		return KC_NO; +	} +} + + + +uint8_t dynamic_keymap_macro_get_count(void) +{ +	return DYNAMIC_KEYMAP_MACRO_COUNT; +} + +uint16_t dynamic_keymap_macro_get_buffer_size(void) +{ +	return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; +} + +void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ) +{ +	void *source = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset); +	uint8_t *target = data; +	for ( uint16_t i = 0; i < size; i++ ) { +		if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) { +			*target = eeprom_read_byte(source); +		} else { +			*target = 0x00; +		} +		source++; +		target++; +	} +} + +void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ) +{ +	void *target = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset); +	uint8_t *source = data; +	for ( uint16_t i = 0; i < size; i++ ) { +		if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) { +			eeprom_update_byte(target, *source); +		} +		source++; +		target++; +	} +} + +void dynamic_keymap_macro_reset(void) +{ +	void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); +	void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); +	while ( p != end ) { +		eeprom_update_byte(p, 0); +		++p; +	} +} + +void dynamic_keymap_macro_send( uint8_t id ) +{ +	if ( id >= DYNAMIC_KEYMAP_MACRO_COUNT )	{ +		return; +	} + +	// Check the last byte of the buffer. +	// If it's not zero, then we are in the middle +	// of buffer writing, possibly an aborted buffer +	// write. So do nothing. +	void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE-1); +	if ( eeprom_read_byte(p) != 0 )	{ +		return; +	} + +	// Skip N null characters +	// p will then point to the Nth macro +	p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); +	void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); +	while ( id > 0 ) { +		// If we are past the end of the buffer, then the buffer +		// contents are garbage, i.e. there were not DYNAMIC_KEYMAP_MACRO_COUNT +		// nulls in the buffer. +		if ( p == end ) { +			return; +		} +		if ( eeprom_read_byte(p) == 0 ) { +			--id; +		} +		++p; +	} + +	// Send the macro string one char at a time +	// by making temporary 1 char strings +	char data[2] = { 0, 0 }; +	// We already checked there was a null at the end of +	// the buffer, so this cannot go past the end +	while ( 1 ) { +		data[0] = eeprom_read_byte(p); +		// Stop at the null terminator of this macro string +		if ( data[0] == 0 ) { +			break; +		} +		send_string(data); +		++p; +	} +} + +#endif // DYNAMIC_KEYMAP_ENABLE + diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h new file mode 100644 index 0000000000..63653f6cb7 --- /dev/null +++ b/quantum/dynamic_keymap.h @@ -0,0 +1,63 @@ +/* Copyright 2017 Jason Williams (Wilba) + * + * 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/>. + */ +#pragma once + +#include <stdint.h> +#include <stdbool.h> + +uint8_t dynamic_keymap_get_layer_count(void); +void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column); +uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column); +void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); +void dynamic_keymap_reset(void); +// These get/set the keycodes as stored in the EEPROM buffer +// Data is big-endian 16-bit values (the keycodes) +// Order is by layer/row/column +// Thus offset 0 = 0,0,0, offset MATRIX_COLS*2 = 0,1,0, offset MATRIX_ROWS*MATRIX_COLS*2 = 1,0,0 +// Note the *2, because offset is in bytes and keycodes are two bytes +// This is only really useful for host applications that want to get a whole keymap fast, +// by reading 14 keycodes (28 bytes) at a time, reducing the number of raw HID transfers by +// a factor of 14. +void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ); +void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ); + +// This overrides the one in quantum/keymap_common.c +// uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); + + + +// Note regarding dynamic_keymap_macro_set_buffer(): +// The last byte of the buffer is used as a valid flag, +// so macro sending is disabled during writing a new buffer, +// should it happen during, or after an interrupted transfer. +// +// Users writing to the buffer must first set the last byte of the buffer +// to non-zero (i.e. 0xFF). After (or during) the final write, set the +// last byte of the buffer to zero. +// +// Since the contents of the buffer must be a list of null terminated +// strings, the last byte must be a null when at maximum capacity, +// and it not being null means the buffer can be considered in an +// invalid state. + +uint8_t dynamic_keymap_macro_get_count(void); +uint16_t dynamic_keymap_macro_get_buffer_size(void); +void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data ); +void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data ); +void dynamic_keymap_macro_reset(void); + +void dynamic_keymap_macro_send( uint8_t id ); + diff --git a/quantum/encoder.c b/quantum/encoder.c new file mode 100644 index 0000000000..6629a098b8 --- /dev/null +++ b/quantum/encoder.c @@ -0,0 +1,70 @@ +/* + * Copyright 2018 Jack Humbert <jack.humb@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 "encoder.h" + +#ifndef ENCODER_RESOLUTION +  #define ENCODER_RESOLUTION 4 +#endif + +#ifndef NUMBER_OF_ENCODERS +  #error "Number of encoders not defined by NUMBER_OF_ENCODERS" +#endif + +#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) +  #error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" +#endif + +static pin_t encoders_pad_a[NUMBER_OF_ENCODERS] = ENCODERS_PAD_A; +static pin_t encoders_pad_b[NUMBER_OF_ENCODERS] = ENCODERS_PAD_B; + +static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; + +static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; +static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; + +__attribute__ ((weak)) +void encoder_update_user(int8_t index, bool clockwise) { } + +__attribute__ ((weak)) +void encoder_update_kb(int8_t index, bool clockwise) { +  encoder_update_user(index, clockwise); +} + +void encoder_init(void) { +  for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { +    setPinInputHigh(encoders_pad_a[i]); +    setPinInputHigh(encoders_pad_b[i]); + +    encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); +  } +} + +void encoder_read(void) { +  for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { +    encoder_state[i] <<= 2; +    encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); +    encoder_value[i] += encoder_LUT[encoder_state[i] & 0xF]; +    if (encoder_value[i] >= ENCODER_RESOLUTION) { +        encoder_update_kb(i, COUNTRECLOCKWISE); +    } +    if (encoder_value[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise +        encoder_update_kb(i, CLOCKWISE); +    } +    encoder_value[i] %= ENCODER_RESOLUTION; +  } +} diff --git a/quantum/process_keycode/process_chording.h b/quantum/encoder.h index 8c0f4862a8..2024fa303f 100644 --- a/quantum/process_keycode/process_chording.h +++ b/quantum/encoder.h @@ -1,4 +1,5 @@ -/* Copyright 2016 Jack Humbert +/* + * Copyright 2018 Jack Humbert <jack.humb@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 @@ -14,19 +15,15 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef PROCESS_CHORDING_H -#define PROCESS_CHORDING_H +#pragma once  #include "quantum.h" -// Chording stuff -#define CHORDING_MAX 4 -bool chording = false; +#define COUNTRECLOCKWISE 0 +#define CLOCKWISE 1 -uint8_t chord_keys[CHORDING_MAX] = {0}; -uint8_t chord_key_count = 0; -uint8_t chord_key_down = 0; +void encoder_init(void); +void encoder_read(void); -bool process_chording(uint16_t keycode, keyrecord_t *record); - -#endif +void encoder_update_kb(int8_t index, bool clockwise); +void encoder_update_user(int8_t index, bool clockwise); diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 50af15d626..f6c8b70d28 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -64,7 +64,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)          case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:              action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));              break; -        case KC_AUDIO_MUTE ... KC_MEDIA_REWIND: +        case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:              action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));              break;          case KC_MS_UP ... KC_MS_ACCEL2: diff --git a/quantum/keymap_extras/keymap_belgian.h b/quantum/keymap_extras/keymap_belgian.h new file mode 100644 index 0000000000..ab89fbabfe --- /dev/null +++ b/quantum/keymap_extras/keymap_belgian.h @@ -0,0 +1,108 @@ +/* Copyright 2015-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/>. + */ +#ifndef KEYMAP_BELGIAN_H +#define KEYMAP_BELGIAN_H + +#include "keymap.h" + +// Normal characters +// Line 1 +#define BE_SUP2	KC_GRV +#define BE_AMP	KC_1 +#define BE_EACU	KC_2 +#define BE_QUOT	KC_3 +#define BE_APOS	KC_4 +#define BE_LPRN	KC_5 +#define BE_PARA	KC_6 +#define BE_EGRV	KC_7 +#define BE_EXLM	KC_8 +#define BE_CCED	KC_9 +#define BE_AGRV	KC_0 +#define BE_RPRN	KC_MINS +#define BE_MINS	KC_EQL + +// Line 2 +#define BE_A    KC_Q +#define BE_Z	  KC_W +#define	BE_CIRC	KC_LBRC +#define BE_DLR	KC_RBRC + +// Line 3 +#define BE_Q 	  KC_A +#define BE_M 	  KC_SCLN +#define BE_UGRV	KC_QUOT +#define BE_MU 	KC_NUHS + +// Line 4 +#define BE_LESS	KC_NUBS +#define BE_W	  KC_Z +#define BE_COMM	KC_M +#define BE_SCLN	KC_COMM +#define BE_COLN	KC_DOT +#define BE_EQL	KC_SLSH + +// Shifted characters +// Line 1 +#define BE_SUP3 KC_TILD +#define BE_1  	LSFT(KC_1) +#define BE_2 	  LSFT(KC_2) +#define BE_3 	  LSFT(KC_3) +#define BE_4 	  LSFT(KC_4) +#define BE_5 	  LSFT(KC_5) +#define BE_6 	  LSFT(KC_6) +#define BE_7 	  LSFT(KC_7) +#define BE_8 	  LSFT(KC_8) +#define BE_9 	  LSFT(KC_9) +#define BE_0 	  LSFT(KC_0) +#define BE_OVRR	KC_UNDS +#define BE_UNDS KC_PLUS + +// Line 2 +#define BE_UMLT	LSFT(BE_CIRC) +#define BE_PND	LSFT(BE_DLR) + +// Line 3 +#define	BE_PERC	LSFT(BE_UGRV) + +// Line 4 +#define BE_GRTR	LSFT(BE_LESS) +#define BE_QUES	LSFT(BE_COMM) +#define BE_DOT	LSFT(BE_SCLN) +#define BE_SLSH	LSFT(BE_COLN) +#define BE_PLUS	LSFT(BE_EQL) + +// Alt Gr-ed characters +// Line 1 +#define BE_PIPE ALGR(KC_1) +#define BE_AT	  ALGR(KC_2) +#define BE_HASH	ALGR(KC_3) +#define BE_LCBR ALGR(KC_9) +#define BE_RCBR	ALGR(KC_0) + +// Line 2 +#define BE_EURO	ALGR(KC_E) +#define BE_LSBR ALGR(BE_CIRC) +#define BE_RSBR ALGR(BE_DLR) + +// Line 3 +#define BE_ACUT ALGR(BE_UGRV) +#define BE_GRV	ALGR(BE_MU) + +// Line 4 +#define BE_BSLS ALGR(BE_LESS) +#define BE_TILT ALGR(BE_EQL) + +#endif diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h index 05fd2b0023..8d7b36ca3d 100644 --- a/quantum/keymap_extras/keymap_bepo.h +++ b/quantum/keymap_extras/keymap_bepo.h @@ -19,15 +19,6 @@  #include "keymap.h" -// Alt gr -#ifndef ALTGR -#define ALTGR(kc)   RALT(kc) -#endif -#ifndef ALGR -#define ALGR(kc)    ALTGR(kc) -#endif -#define BP_ALGR KC_RALT -  // Normal characters  // First row (on usual keyboards)  #define BP_DOLLAR           KC_GRAVE            // $ @@ -142,138 +133,138 @@  // AltGr-ed characters  // First row -#define BP_EN_DASH          ALTGR(BP_DOLLAR)    // – +#define BP_EN_DASH          ALGR(BP_DOLLAR)     // –  #define BP_NDSH             BP_EN_DASH -#define BP_EM_DASH          ALTGR(KC_1)         // — +#define BP_EM_DASH          ALGR(KC_1)          // —  #define BP_MDSH             BP_EM_DASH -#define BP_LESS             ALTGR(KC_2)         // < -#define BP_GREATER          ALTGR(KC_3)         // > +#define BP_LESS             ALGR(KC_2)          // < +#define BP_GREATER          ALGR(KC_3)          // >  #define BP_GRTR             BP_GREATER -#define BP_LBRACKET         ALTGR(KC_4)         // [ +#define BP_LBRACKET         ALGR(KC_4)          // [  #define BP_LBRC             BP_LBRACKET -#define BP_RBRACKET         ALTGR(KC_5)         // ] +#define BP_RBRACKET         ALGR(KC_5)          // ]  #define BP_RBRC             BP_RBRACKET -#define BP_CIRCUMFLEX       ALTGR(KC_6)         // ^ +#define BP_CIRCUMFLEX       ALGR(KC_6)          // ^  #define BP_CIRC             BP_CIRCUMFLEX -#define BP_PLUS_MINUS       ALTGR(KC_7)         // ± +#define BP_PLUS_MINUS       ALGR(KC_7)          // ±  #define BP_PSMS             BP_PLUS_MINUS -#define BP_MATH_MINUS       ALTGR(KC_8)         // − +#define BP_MATH_MINUS       ALGR(KC_8)          // −  #define BP_MMNS             BP_MATH_MINUS -#define BP_OBELUS           ALTGR(KC_9)         // ÷ +#define BP_OBELUS           ALGR(KC_9)          // ÷  #define BP_OBEL             BP_OBELUS  // more conventional name of the symbol  #define BP_DIVISION_SIGN    BP_OBELUS  #define BP_DVSN             BP_DIVISION_SIGN -#define BP_TIMES            ALTGR(KC_0)         // × +#define BP_TIMES            ALGR(KC_0)          // ×  #define BP_TIMS             BP_TIMES -#define BP_DIFFERENT        ALTGR(BP_EQUAL)     // ≠ +#define BP_DIFFERENT        ALGR(BP_EQUAL)      // ≠  #define BP_DIFF             BP_DIFFERENT -#define BP_PERMILLE         ALTGR(BP_PERCENT)   // ‰ +#define BP_PERMILLE         ALGR(BP_PERCENT)    // ‰  #define BP_PMIL             BP_PERMILLE  // Second row -#define BP_PIPE                 ALTGR(BP_B)         // | -#define BP_DEAD_ACUTE           ALTGR(BP_E_ACUTE)   // dead ´ +#define BP_PIPE                 ALGR(BP_B)          // | +#define BP_DEAD_ACUTE           ALGR(BP_E_ACUTE)    // dead ´  #define BP_DACT                 BP_DEAD_ACUTE -#define BP_AMPERSAND            ALTGR(BP_P)         // & +#define BP_AMPERSAND            ALGR(BP_P)          // &  #define BP_AMPR                 BP_AMPERSAND -#define BP_OE_LIGATURE          ALTGR(BP_O)         // œ +#define BP_OE_LIGATURE          ALGR(BP_O)          // œ  #define BP_OE                   BP_OE_LIGATURE -#define BP_DEAD_GRAVE           ALTGR(BP_E_GRAVE)   // ` +#define BP_DEAD_GRAVE           ALGR(BP_E_GRAVE)    // `  #define BP_DGRV                 BP_DEAD_GRAVE -#define BP_INVERTED_EXCLAIM     ALTGR(BP_DEAD_CIRCUMFLEX)   // ¡ +#define BP_INVERTED_EXCLAIM     ALGR(BP_DEAD_CIRCUMFLEX)    // ¡  #define BP_IXLM                 BP_INVERTED_EXCLAIM -#define BP_DEAD_CARON           ALTGR(BP_V)         // dead ˇ +#define BP_DEAD_CARON           ALGR(BP_V)          // dead ˇ  #define BP_DCAR                 BP_DEAD_CARON -#define BP_ETH                  ALTGR(BP_D)         // ð -#define BP_DEAD_SLASH           ALTGR(BP_L)         // dead / +#define BP_ETH                  ALGR(BP_D)          // ð +#define BP_DEAD_SLASH           ALGR(BP_L)          // dead /  #define BP_DSLH                 BP_DEAD_SLASH -#define BP_IJ_LIGATURE          ALTGR(BP_J)         // ij +#define BP_IJ_LIGATURE          ALGR(BP_J)          // ij  #define BP_IJ                   BP_IJ_LIGATURE -#define BP_SCHWA                ALTGR(BP_Z)         // ə +#define BP_SCHWA                ALGR(BP_Z)          // ə  #define BP_SCWA                 BP_SCHWA -#define BP_DEAD_BREVE           ALTGR(BP_W)         // dead ˘ +#define BP_DEAD_BREVE           ALGR(BP_W)          // dead ˘  #define BP_DBRV                 BP_DEAD_BREVE  // Third row -#define BP_AE_LIGATURE              ALTGR(BP_A)         // æ +#define BP_AE_LIGATURE              ALGR(BP_A)          // æ  #define BP_AE                       BP_AE_LIGATURE -#define BP_U_GRAVE                  ALTGR(BP_U)           // ù +#define BP_U_GRAVE                  ALGR(BP_U)          // ù  #define BP_UGRV                     BP_U_GRAVE -#define BP_DEAD_TREMA               ALTGR(BP_I)         // dead ¨ (trema/umlaut/diaresis) +#define BP_DEAD_TREMA               ALGR(BP_I)          // dead ¨ (trema/umlaut/diaresis)  #define BP_DTRM                     BP_DEAD_TREMA -#define BP_EURO                     ALTGR(BP_E)         // € -#define BP_TYPOGRAPHICAL_APOSTROPHE ALTGR(BP_COMMA)     // ’ +#define BP_EURO                     ALGR(BP_E)          // € +#define BP_TYPOGRAPHICAL_APOSTROPHE ALGR(BP_COMMA)      // ’  #define BP_TAPO                     BP_TYPOGRAPHICAL_APOSTROPHE -#define BP_COPYRIGHT                ALTGR(BP_C)         // © +#define BP_COPYRIGHT                ALGR(BP_C)          // ©  #define BP_CPRT                     BP_COPYRIGHT -#define BP_THORN                    ALTGR(BP_T)         // þ +#define BP_THORN                    ALGR(BP_T)          // þ  #define BP_THRN                     BP_THORN -#define BP_SHARP_S                  ALTGR(BP_S)         // ß +#define BP_SHARP_S                  ALGR(BP_S)          // ß  #define BP_SRPS                     BP_SHARP_S -#define BP_REGISTERED_TRADEMARK     ALTGR(BP_R)         // ® +#define BP_REGISTERED_TRADEMARK     ALGR(BP_R)          // ®  #define BP_RTM                      BP_REGISTERED_TRADEMARK -#define BP_DEAD_TILDE               ALTGR(BP_N)         // dead ~ +#define BP_DEAD_TILDE               ALGR(BP_N)          // dead ~  #define BP_DTLD                     BP_DEAD_TILDE -#define BP_DEAD_MACRON              ALTGR(BP_M)         // dead ¯ +#define BP_DEAD_MACRON              ALGR(BP_M)          // dead ¯  #define BP_DMCR                     BP_DEAD_MACRON -#define BP_DEAD_CEDILLA             ALTGR(BP_C_CEDILLA) // dead ¸ +#define BP_DEAD_CEDILLA             ALGR(BP_C_CEDILLA)  // dead ¸  #define BP_DCED                     BP_DEAD_CEDILLA  // Fourth row -#define BP_NONUS_SLASH          ALTGR(BP_E_CIRCUMFLEX)  // / on non-us backslash key (102nd key, ê in bépo) +#define BP_NONUS_SLASH          ALGR(BP_E_CIRCUMFLEX)   // / on non-us backslash key (102nd key, ê in bépo)  #define BP_NUSL                 BP_NONUS_SLASH -#define BP_BACKSLASH            ALTGR(BP_A_GRAVE)       /* \ */ +#define BP_BACKSLASH            ALGR(BP_A_GRAVE)        /* \ */  #define BP_BSLS                 BP_BACKSLASH -#define BP_LEFT_CURLY_BRACE     ALTGR(BP_Y)             // { +#define BP_LEFT_CURLY_BRACE     ALGR(BP_Y)              // {  #define BP_LCBR                 BP_LEFT_CURLY_BRACE -#define BP_RIGHT_CURLY_BRACE    ALTGR(BP_X)             // } +#define BP_RIGHT_CURLY_BRACE    ALGR(BP_X)              // }  #define BP_RCBR                 BP_RIGHT_CURLY_BRACE -#define BP_ELLIPSIS             ALTGR(BP_DOT)           // … +#define BP_ELLIPSIS             ALGR(BP_DOT)            // …  #define BP_ELPS                 BP_ELLIPSIS -#define BP_TILDE                ALTGR(BP_K)             // ~ +#define BP_TILDE                ALGR(BP_K)              // ~  #define BP_TILD                 BP_TILDE -#define BP_INVERTED_QUESTION    ALTGR(BP_QUESTION)      // ¿ +#define BP_INVERTED_QUESTION    ALGR(BP_QUESTION)       // ¿  #define BP_IQST                 BP_INVERTED_QUESTION -#define BP_DEAD_RING            ALTGR(BP_Q)             // dead ° +#define BP_DEAD_RING            ALGR(BP_Q)              // dead °  #define BP_DRNG                 BP_DEAD_RING -#define BP_DEAD_GREEK           ALTGR(BP_G)             // dead Greek key (following key will make a Greek letter) +#define BP_DEAD_GREEK           ALGR(BP_G)              // dead Greek key (following key will make a Greek letter)  #define BP_DGRK                 BP_DEAD_GREEK -#define BP_DAGGER               ALTGR(BP_H)             // † +#define BP_DAGGER               ALGR(BP_H)              // †  #define BP_DAGR                 BP_DAGGER -#define BP_DEAD_OGONEK          ALTGR(BP_F)             // dead ˛ +#define BP_DEAD_OGONEK          ALGR(BP_F)              // dead ˛  #define BP_DOGO                 BP_DEAD_OGONEK  // Space bar -#define BP_UNDERSCORE   ALTGR(KC_SPACE)     // _ +#define BP_UNDERSCORE   ALGR(KC_SPACE)      // _  #define BP_UNDS         BP_UNDERSCORE  // AltGr-Shifted characters (different from capitalised AltGr-ed characters)  // First row -#define BP_PARAGRAPH            ALTGR(BP_HASH)      // ¶ +#define BP_PARAGRAPH            ALGR(BP_HASH)       // ¶  #define BP_PARG                 BP_PARAGRAPH -#define BP_LOW_DOUBLE_QUOTE     ALTGR(BP_1)         // „ +#define BP_LOW_DOUBLE_QUOTE     ALGR(BP_1)          // „  #define BP_LWQT                 BP_LOW_DOUBLE_QUOTE -#define BP_LEFT_DOUBLE_QUOTE    ALTGR(BP_2)         // “ +#define BP_LEFT_DOUBLE_QUOTE    ALGR(BP_2)          // “  #define BP_LDQT                 BP_LEFT_DOUBLE_QUOTE -#define BP_RIGHT_DOUBLE_QUOTE   ALTGR(BP_3)         // ” +#define BP_RIGHT_DOUBLE_QUOTE   ALGR(BP_3)          // ”  #define BP_RDQT                 BP_RIGHT_DOUBLE_QUOTE -#define BP_LESS_OR_EQUAL        ALTGR(BP_4)         // ≤ +#define BP_LESS_OR_EQUAL        ALGR(BP_4)          // ≤  #define BP_LEQL                 BP_LESS_OR_EQUAL -#define BP_GREATER_OR_EQUAL     ALTGR(BP_5)         // ≥ +#define BP_GREATER_OR_EQUAL     ALGR(BP_5)          // ≥  #define BP_GEQL                 BP_GREATER_OR_EQUAL -// nothing on ALTGR(BP_6) -#define BP_NEGATION             ALTGR(BP_7)         // ¬ +// nothing on ALGR(BP_6) +#define BP_NEGATION             ALGR(BP_7)          // ¬  #define BP_NEGT                 BP_NEGATION -#define BP_ONE_QUARTER          ALTGR(BP_8)         // ¼ +#define BP_ONE_QUARTER          ALGR(BP_8)          // ¼  #define BP_1QRT                 BP_ONE_QUARTER -#define BP_ONE_HALF             ALTGR(BP_9)         // ½ +#define BP_ONE_HALF             ALGR(BP_9)          // ½  #define BP_1HLF                 BP_ONE_HALF -#define BP_THREE_QUARTERS       ALTGR(BP_0)         // ¾ +#define BP_THREE_QUARTERS       ALGR(BP_0)          // ¾  #define BP_3QRT                 BP_THREE_QUARTERS -#define BP_MINUTES              ALTGR(BP_DEGREE)    // ′ +#define BP_MINUTES              ALGR(BP_DEGREE)     // ′  #define BP_MNUT                 BP_MINUTES -#define BP_SECONDS              ALTGR(BP_GRAVE)     // ″ +#define BP_SECONDS              ALGR(BP_GRAVE)      // ″  #define BP_SCND                 BP_SECONDS  // Second row @@ -281,7 +272,7 @@  #define BP_BPIP                 BP_BROKEN_PIPE  #define BP_DEAD_DOUBLE_ACUTE    LSFT(BP_DEAD_ACUTE)     // ˝  #define BP_DDCT                 BP_DEAD_DOUBLE_ACUTE -#define BP_SECTION              ALTGR(LSFT(BP_P))       // § +#define BP_SECTION              ALGR(LSFT(BP_P))        // §  #define BP_SECT                 BP_SECTION  // LSFT(BP_DEAD_GRAVE) is actually the same character as LSFT(BP_PERCENT)  #define BP_GRAVE_BIS            LSFT(BP_DEAD_GRAVE)     // ` @@ -292,35 +283,35 @@  #define BP_DDTA                 BP_DEAD_DOT_ABOVE  #define BP_DEAD_CURRENCY        LSFT(BP_EURO)           // dead ¤ (next key will generate a currency code like ¥ or £)  #define BP_DCUR                 BP_DEAD_CURRENCY -#define BP_DEAD_HORN            LSFT(ALTGR(BP_COMMA))   // dead ̛ +#define BP_DEAD_HORN            LSFT(ALGR(BP_COMMA))    // dead ̛  #define BP_DHRN                 BP_DEAD_HORN -#define BP_LONG_S               LSFT(ALTGR(BP_C))       // ſ +#define BP_LONG_S               LSFT(ALGR(BP_C))        // ſ  #define BP_LNGS                 BP_LONG_S  #define BP_TRADEMARK            LSFT(BP_REGISTERED_TRADEMARK)   // ™  #define BP_TM                   BP_TRADEMARK -#define BP_ORDINAL_INDICATOR_O  LSFT(ALTGR(BP_M))               // º +#define BP_ORDINAL_INDICATOR_O  LSFT(ALGR(BP_M))        // º  #define BP_ORDO                 BP_ORDINAL_INDICATOR_O  #define BP_DEAD_COMMA           LSFT(BP_DEAD_CEDILLA)   // dead ˛  #define BP_DCOM                 BP_DEAD_COMMA  // Fourth row -#define BP_LEFT_QUOTE           LSFT(ALTGR(BP_Y))       // ‘ +#define BP_LEFT_QUOTE           LSFT(ALGR(BP_Y))        // ‘  #define BP_LQOT                 BP_LEFT_QUOTE -#define BP_RIGHT_QUOTE          LSFT(ALTGR(BP_X))       // ’ +#define BP_RIGHT_QUOTE          LSFT(ALGR(BP_X))        // ’  #define BP_RQOT                 BP_RIGHT_QUOTE -#define BP_INTERPUNCT           LSFT(ALTGR(BP_DOT))     // · +#define BP_INTERPUNCT           LSFT(ALGR(BP_DOT))      // ·  #define BP_IPCT                 BP_INTERPUNCT -#define BP_DEAD_HOOK_ABOVE      LSFT(ALTGR(BP_QUESTION))    // dead ̉ +#define BP_DEAD_HOOK_ABOVE      LSFT(ALGR(BP_QUESTION)) // dead ̉  #define BP_DHKA                 BP_DEAD_HOOK_ABOVE  #define BP_DEAD_UNDERDOT        LSFT(BP_DEAD_RING)      // dead ̣  #define BP_DUDT                 BP_DEAD_UNDERDOT  #define BP_DOUBLE_DAGGER        LSFT(BP_DAGGER)         // ‡  #define BP_DDGR                 BP_DOUBLE_DAGGER -#define BP_ORDINAL_INDICATOR_A  LSFT(ALTGR(BP_F))       // ª +#define BP_ORDINAL_INDICATOR_A  LSFT(ALGR(BP_F))        // ª  #define BP_ORDA                 BP_ORDINAL_INDICATOR_A  // Space bar -#define BP_NARROW_NON_BREAKING_SPACE    ALTGR(BP_NON_BREAKING_SPACE) +#define BP_NARROW_NON_BREAKING_SPACE    ALGR(BP_NON_BREAKING_SPACE)  #define BP_NNBS                         BP_NARROW_NON_BREAKING_SPACE  #endif diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h index 1d45bee32e..2b5b95d6fa 100644 --- a/quantum/keymap_extras/keymap_canadian_multilingual.h +++ b/quantum/keymap_extras/keymap_canadian_multilingual.h @@ -13,22 +13,11 @@   * 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_CANADIAN_MULTILINGUAG_H -#define KEYMAP_CANADIAN_MULTILINGUAG_H +#ifndef KEYMAP_CANADIAN_MULTILINGUAL_H +#define KEYMAP_CANADIAN_MULTILINGUAL_H  #include "keymap.h" -// Alt gr -#ifndef ALTGR -#define ALTGR(kc)   RALT(kc) -#endif -#ifndef ALGR -#define ALGR(kc)    ALTGR(kc) -#endif - -#define CSA_ALTGR   KC_RALT -#define CSA_ALGR    CSA_ALTGR -  #ifndef GR2A  #define GR2A(kc)    RCTL(kc)  #endif @@ -78,43 +67,43 @@  // Alt Gr-ed characters  // First row -#define CSA_PIPE                ALTGR(CSA_SLASH)        // | -#define CSA_CURRENCY            ALTGR(KC_4)             // ¤ +#define CSA_PIPE                ALGR(CSA_SLASH)         // | +#define CSA_CURRENCY            ALGR(KC_4)              // ¤  #define CSA_CURR                CSA_CURRENCY -#define CSA_LEFT_CURLY_BRACE    ALTGR(KC_7)             // { +#define CSA_LEFT_CURLY_BRACE    ALGR(KC_7)              // {  #define CSA_LCBR                CSA_LEFT_CURLY_BRACE -#define CSA_RIGHT_CURLY_BRACE   ALTGR(KC_8)             // } +#define CSA_RIGHT_CURLY_BRACE   ALGR(KC_8)              // }  #define CSA_RCBR                CSA_RIGHT_CURLY_BRACE -#define CSA_LBRACKET            ALTGR(KC_9)             // [ +#define CSA_LBRACKET            ALGR(KC_9)              // [  #define CSA_LBRC                CSA_LBRACKET -#define CSA_RBRACKET            ALTGR(KC_0)             // ] +#define CSA_RBRACKET            ALGR(KC_0)              // ]  #define CSA_RBRC                CSA_RBRACKET -#define CSA_NEGATION            ALTGR(KC_EQUAL)         // ¬ +#define CSA_NEGATION            ALGR(KC_EQUAL)          // ¬  #define CSA_NEGT                CSA_NEGATION  // Second row  // euro symbol not available on Linux? (X.org) -#define CSA_EURO        ALTGR(KC_E)                 // € -#define CSA_DEAD_GRAVE  ALTGR(CSA_DEAD_CIRCUMFLEX) +#define CSA_EURO        ALGR(KC_E)                  // € +#define CSA_DEAD_GRAVE  ALGR(CSA_DEAD_CIRCUMFLEX)  #define CSA_DGRV        CSA_DEAD_GRAVE              // dead ` -#define CSA_DEAD_TILDE  ALTGR(CSA_C_CEDILLA)        // ~ +#define CSA_DEAD_TILDE  ALGR(CSA_C_CEDILLA)         // ~  #define CSA_DTLD        CSA_DEAD_TILDE  // Third row -#define CSA_DEGREE  ALTGR(KC_SCOLON)    // ° +#define CSA_DEGREE  ALGR(KC_SCOLON)     // °  #define CSA_DEGR    CSA_DEGREE  // Fourth row -#define CSA_LEFT_GUILLEMET      ALTGR(KC_Z)         // « +#define CSA_LEFT_GUILLEMET      ALGR(KC_Z)          // «  #define CSA_LGIL                CSA_LEFT_GUILLEMET -#define CSA_RIGHT_GUILLEMET     ALTGR(KC_X)         // » +#define CSA_RIGHT_GUILLEMET     ALGR(KC_X)          // »  #define CSA_RGIL                CSA_RIGHT_GUILLEMET -#define CSA_LESS                ALTGR(KC_COMMA)     // < -#define CSA_GREATER             ALTGR(KC_DOT)       // > +#define CSA_LESS                ALGR(KC_COMMA)      // < +#define CSA_GREATER             ALGR(KC_DOT)        // >  #define CSA_GRTR                CSA_GREATER  // Space bar -#define CSA_NON_BREAKING_SPACE  ALTGR(KC_SPACE) +#define CSA_NON_BREAKING_SPACE  ALGR(KC_SPACE)  #define CSA_NBSP                CSA_NON_BREAKING_SPACE  // GR2A-ed characters @@ -201,7 +190,7 @@  // nothing on 2  #define CSA_POUND               GR2A(LSFT(KC_3))    // £  #define CSA_GBP                 CSA_POUND_SIGN -// already on ALTGR(KC_E) +// already on ALGR(KC_E)  #define CSA_EURO_BIS            GR2A(LSFT(KC_4))    // €  #define CSA_EURB                CSA_EURO_BIS  #define CSA_THREE_EIGHTHS       GR2A(LSFT(KC_5))    // ⅜ diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h index c0ca832a6f..69f9547bb9 100644 --- a/quantum/keymap_extras/keymap_fr_ch.h +++ b/quantum/keymap_extras/keymap_fr_ch.h @@ -18,10 +18,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define FR_CH_ALGR KC_RALT -  // normal characters  #define FR_CH_Z KC_Y  #define FR_CH_Y KC_Z diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index 3308dc5f77..bef7754707 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -18,12 +18,6 @@  #include "keymap.h" -// Alt gr -#ifndef ALGR -#define ALGR(kc) RALT(kc) -#endif -#define NO_ALGR KC_RALT -  // Normal characters  #define FR_SUP2	KC_GRV  #define FR_AMP	KC_1 diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h index e007c26ef5..0ba3570df7 100644 --- a/quantum/keymap_extras/keymap_german.h +++ b/quantum/keymap_extras/keymap_german.h @@ -19,10 +19,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define DE_ALGR KC_RALT -  // normal characters  #define DE_Z KC_Y  #define DE_Y KC_Z diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h index 67350d6602..bd1ef89a19 100644 --- a/quantum/keymap_extras/keymap_german_ch.h +++ b/quantum/keymap_extras/keymap_german_ch.h @@ -18,10 +18,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define CH_ALGR KC_RALT -  // normal characters  #define CH_Z KC_Y  #define CH_Y KC_Z diff --git a/quantum/keymap_extras/keymap_hungarian.h b/quantum/keymap_extras/keymap_hungarian.h index b372440928..ff43535f38 100644 --- a/quantum/keymap_extras/keymap_hungarian.h +++ b/quantum/keymap_extras/keymap_hungarian.h @@ -19,10 +19,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define HU_ALGR KC_RALT -  // basic letters  #define HU_Z KC_Y  #define HU_Y KC_Z diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h index 0ff6ce8762..fe0f5eb847 100644 --- a/quantum/keymap_extras/keymap_italian.h +++ b/quantum/keymap_extras/keymap_italian.h @@ -19,14 +19,7 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define IT_ALGR KC_RALT -  // normal characters - - -  #define IT_A KC_A  #define IT_B KC_B  #define IT_C KC_C diff --git a/quantum/keymap_extras/keymap_jp.h b/quantum/keymap_extras/keymap_jp.h index fb74bce8d4..b0235f1120 100644 --- a/quantum/keymap_extras/keymap_jp.h +++ b/quantum/keymap_extras/keymap_jp.h @@ -40,6 +40,9 @@  #define JP_HENK KC_INT4 // henkan  #define JP_KANA KC_INT2 // katakana/hiragana|ro-mazi +#define JP_MKANA KC_LANG1 //kana on MacOSX +#define JP_MEISU KC_LANG2 //eisu on MacOSX +  //Aliases for shifted symbols  #define JP_DQT  LSFT(KC_2)    // " diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h index 174f4a6eec..818a739c76 100644 --- a/quantum/keymap_extras/keymap_neo2.h +++ b/quantum/keymap_extras/keymap_neo2.h @@ -73,6 +73,6 @@  #define NEO_L1_R DE_HASH  #define NEO_L2_L DE_LESS -#define NEO_L2_R DE_ALGR +#define NEO_L2_R KC_ALGR  #endif diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index 6b34db5588..551a4212b2 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -18,10 +18,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define NO_ALGR KC_RALT -  // Normal characters  #define NO_HALF	KC_GRV  #define NO_PLUS	KC_MINS diff --git a/quantum/keymap_extras/keymap_plover_dvorak.h b/quantum/keymap_extras/keymap_plover_dvorak.h new file mode 100644 index 0000000000..83bb1e8b87 --- /dev/null +++ b/quantum/keymap_extras/keymap_plover_dvorak.h @@ -0,0 +1,47 @@ +/* Copyright 2016 James Kay + * + * 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 KEYMAP_PLOVER_DVORAK_H +#define KEYMAP_PLOVER_DVORAK_H + +#include "keymap_dvorak.h" + +#define PD_NUM  DV_1 +#define PD_LS   DV_Q +#define PD_LT   DV_W +#define PD_LP   DV_E +#define PD_LH   DV_R +#define PD_LK   DV_S +#define PD_LW   DV_D +#define PD_LR   DV_F + +#define PD_STAR DV_Y +#define PD_RF   DV_U +#define PD_RP   DV_I +#define PD_RL   DV_O +#define PD_RT   DV_P +#define PD_RD   DV_LBRC +#define PD_RR   DV_J +#define PD_RB   DV_K +#define PD_RG   DV_L +#define PD_RS   DV_SCLN +#define PD_RZ   DV_QUOT + +#define PD_A    DV_C +#define PD_O    DV_V +#define PD_E    DV_N +#define PD_U    DV_M + +#endif diff --git a/quantum/keymap_extras/keymap_slovenian.h b/quantum/keymap_extras/keymap_slovenian.h new file mode 100644 index 0000000000..892283e702 --- /dev/null +++ b/quantum/keymap_extras/keymap_slovenian.h @@ -0,0 +1,107 @@ +/* Copyright 2018 Žan Pevec + + * + * 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 KEYMAP_SLOVENIAN +#define KEYMAP_SLOVENIAN + +#include "keymap.h" + +//Swapped Z and Y +#define SI_Z KC_Y +#define SI_Y KC_Z + +//Special characters +#define SI_CV KC_SCLN +#define SI_SV KC_LBRC +#define SI_ZV KC_BSLS + +#define SI_A KC_A +#define SI_B KC_B +#define SI_C KC_C +#define SI_D KC_D +#define SI_E KC_E +#define SI_F KC_F +#define SI_G KC_G +#define SI_H KC_H +#define SI_I KC_I +#define SI_J KC_J +#define SI_K KC_K +#define SI_L KC_L +#define SI_M KC_M +#define SI_N KC_N +#define SI_O KC_O +#define SI_P KC_P +#define SI_Q KC_Q +#define SI_R KC_R +#define SI_S KC_S +#define SI_T KC_T +#define SI_U KC_U +#define SI_V KC_V +#define SI_W KC_W +#define SI_X KC_X + +#define SI_0 KC_0 +#define SI_1 KC_1 +#define SI_2 KC_2 +#define SI_3 KC_3 +#define SI_4 KC_4 +#define SI_5 KC_5 +#define SI_6 KC_6 +#define SI_7 KC_7 +#define SI_8 KC_8 +#define SI_9 KC_9 + +#define SI_DOT KC_DOT +#define SI_COMM KC_COMM + +#define SI_PLUS KC_EQL // + and * and ~ +#define SI_QOT KC_MINS // Single quote +#define SI_MINS KC_SLSH // - and _ + +// shifted characters +#define SI_EXLM LSFT(KC_1) // ! +#define SI_DQOT LSFT(KC_2) // " +#define SI_HASH LSFT(KC_3) // # +#define SI_DLR  LSFT(KC_4) // $ +#define SI_PERC LSFT(KC_5) // % +#define SI_AMPR LSFT(KC_6) // & +#define SI_SLSH LSFT(KC_7) // / +#define SI_LPRN LSFT(KC_8) // ( +#define SI_RPRN LSFT(KC_9) // ) +#define SI_EQL  LSFT(KC_0) // = +#define SI_QST  LSFT(SI_QOT) // ? +#define SI_ASTR LSFT(SI_PLUS) // * +#define SI_COLN LSFT(KC_DOT) // : +#define SI_SCLN LSFT(KC_COMM) // ; +#define SI_UNDS LSFT(SI_MINS) // _ + +// Alt Gr-ed characters +#define SI_CIRC ALGR(KC_3) // ^ +#define SI_DEG ALGR(KC_5) // ° +#define SI_GRV ALGR(KC_7) // ` +#define SI_ACCU ALGR(KC_9) // ´ +#define SI_LCBR ALGR(KC_B) // { +#define SI_RCBR ALGR(KC_N) // } +#define SI_LBRC ALGR(KC_F) // [ +#define SI_RBRC ALGR(KC_G) // ] +#define SI_BSLS ALGR(KC_Q) // backslash +#define SI_AT  ALGR(KC_V) // @ +#define SI_EURO ALGR(KC_E) // € +#define SI_TILD ALGR(KC_1) // ~ +#define SI_PIPE ALGR(KC_W) // | + +#endif diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index 224db7be16..1f183327f9 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -18,10 +18,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define NO_ALGR KC_RALT -  // Normal characters  #define ES_OVRR KC_GRV  #define ES_APOS	KC_MINS diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h index 9044bb74e7..d1a0f4f227 100644 --- a/quantum/keymap_extras/keymap_swedish.h +++ b/quantum/keymap_extras/keymap_swedish.h @@ -41,8 +41,8 @@  #define NO_DLR_MAC  LSFT(KC_4) // $  #define NO_GRV_MAC ALGR(NO_BSLS) // `  #define NO_GRTR_MAC LSFT(KC_GRV)  // > -#define NO_LCBR_MAC ALGR(LSFT(KC_8))  // } -#define NO_LESS_MAC KC_GRV  // > +#define NO_LCBR_MAC ALGR(LSFT(KC_8))  // { +#define NO_LESS_MAC KC_GRV  // <  #define NO_PIPE_MAC ALGR(KC_7)  // |  #define NO_RCBR_MAC ALGR(LSFT(KC_9))  // } diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index de47103cb9..cc3d0039e2 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -18,10 +18,6 @@  #include "keymap.h" -// Alt gr -#define ALGR(kc) RALT(kc) -#define NO_ALGR KC_RALT -  // Normal characters  #define UK_HASH KC_NUHS  #define UK_BSLS	KC_NUBS diff --git a/quantum/keymap_extras/sendstring_german.h b/quantum/keymap_extras/sendstring_german.h new file mode 100644 index 0000000000..1eaafee317 --- /dev/null +++ b/quantum/keymap_extras/sendstring_german.h @@ -0,0 +1,81 @@ +/* Copyright 2018 Patrick Hener + * + * 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/>. + */ +/* Sendstring definitions for the German layout */ +#ifndef SENDSTRING_GERMAN +#define SENDSTRING_GERMAN + +#include "keymap_german.h" + +const bool ascii_to_shift_lut[0x80] PROGMEM = { +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +     +    0, 1, 1, 0, 1, 1, 1, 1, +    1, 1, 1, 0, 0, 0, 0, 1, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 1, 1, 0, 1, 1, 1, +    1, 1, 1, 1, 1, 1, 1, 1, +    1, 1, 1, 1, 1, 1, 1, 1, +    1, 1, 1, 1, 1, 1, 1, 1, +    1, 1, 1, 0, 0, 0, 0, 1, +    1, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 1, 1, 1, 1, 0 +}; + +/* Until an ALT table/functionality is added, the following symbols will not work: +* § @ [ ] { } \ ~ äA öÖ ß ´ +* Following characters can be printed using other characters like so: +* [ in makro will be ü +* { in makro will be Ü +* ~ in makro will be ° +*/ +const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = { +    0, 0, 0, 0, 0, 0, 0, 0, +    KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, KC_ESC, 0, 0, 0, 0, + +  /* SPACE   !     "      #        $     %     &      '                    */ +    KC_SPC, KC_1, KC_2, DE_HASH, KC_4, KC_5, KC_6, DE_HASH, +  /*  (      )     *      +        ,        -        .       /                    */ +    KC_8, KC_9, DE_PLUS, DE_PLUS, KC_COMM, DE_MINS, KC_DOT, KC_7, +  /*   0     1     2     3     4     5    6     7                    */ +    KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, +  /*   8     9      :       ;         <        =       >       ?                     */ +    KC_8, KC_9, KC_DOT, KC_COMM, DE_LESS,    KC_0, DE_LESS, KC_MINS, +  /*   @     A     B     C     D     E     F     G                    */ +    KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, +  /*   H     I     J     K     L     M     N     O                    */ +    KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, +  /*   P     Q     R     S     T     U     V     W                    */ +    KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, +  /*   X     Y     Z      [         \       ]       ^      _                    */ +    KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, DE_CIRC, DE_MINS, +  /*   `       a     b     c     d     e     f     g                    */ +    DE_ACUT, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, +  /*   h     i     j     k     l     m     n     o                    */ +    KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, +  /*    p    q     r     s     t     u     v     w                      */ +    KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, +  /*    x    y     z      {        |        }        ~    DELETE                    */ +    KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL +}; + +#endif diff --git a/quantum/matrix.c b/quantum/matrix.c index 3600d4e7b5..9b5ce33d23 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -1,5 +1,5 @@  /* -Copyright 2012-2017 Jun Wako, Jack Humbert +Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar  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 @@ -16,15 +16,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  */  #include <stdint.h>  #include <stdbool.h> -#if defined(__AVR__) -#include <avr/io.h> -#endif  #include "wait.h"  #include "print.h"  #include "debug.h"  #include "util.h"  #include "matrix.h"  #include "timer.h" +#include "quantum.h"  /* Set 0 if debouncing isn't needed */ @@ -60,8 +58,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #endif  #if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) -static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;  #endif  /* matrix state(1:on, 0:off) */ @@ -271,9 +269,7 @@ uint8_t matrix_key_count(void)  static void init_cols(void)  {      for(uint8_t x = 0; x < MATRIX_COLS; x++) { -        uint8_t pin = col_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(col_pins[x]);      }  } @@ -293,8 +289,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)      for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {          // Select the col pin to read (active low) -        uint8_t pin = col_pins[col_index]; -        uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)); +        uint8_t pin_state = readPin(col_pins[col_index]);          // Populate the matrix row with the state of the col pin          current_matrix[current_row] |=  pin_state ? 0 : (ROW_SHIFTER << col_index); @@ -308,24 +303,19 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)  static void select_row(uint8_t row)  { -    uint8_t pin = row_pins[row]; -    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT -    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +    setPinOutput(row_pins[row]); +    writePinLow(row_pins[row]);  }  static void unselect_row(uint8_t row)  { -    uint8_t pin = row_pins[row]; -    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +    setPinInputHigh(row_pins[row]);  }  static void unselect_rows(void)  {      for(uint8_t x = 0; x < MATRIX_ROWS; x++) { -        uint8_t pin = row_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInput(row_pins[x]);      }  } @@ -334,9 +324,7 @@ static void unselect_rows(void)  static void init_rows(void)  {      for(uint8_t x = 0; x < MATRIX_ROWS; x++) { -        uint8_t pin = row_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(row_pins[x]);      }  } @@ -356,7 +344,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)          matrix_row_t last_row_value = current_matrix[row_index];          // Check row pin state -        if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) +        if (readPin(row_pins[row_index]) == 0)          {              // Pin LO, set col bit              current_matrix[row_index] |= (ROW_SHIFTER << current_col); @@ -382,24 +370,19 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)  static void select_col(uint8_t col)  { -    uint8_t pin = col_pins[col]; -    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT -    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +    setPinOutput(col_pins[col]); +    writePinLow(col_pins[col]);  }  static void unselect_col(uint8_t col)  { -    uint8_t pin = col_pins[col]; -    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +    setPinInputHigh(col_pins[col]);  }  static void unselect_cols(void)  {      for(uint8_t x = 0; x < MATRIX_COLS; x++) { -        uint8_t pin = col_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(col_pins[x]);      }  } diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 01d99445b0..0d0930ee67 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c @@ -173,6 +173,8 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {        case KC_DOT:        case KC_SLSH:        case KC_GRAVE: +      case KC_NONUS_BSLASH: +      case KC_NONUS_HASH:  #endif          autoshift_flush(); diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c deleted file mode 100644 index 6c6ebe300a..0000000000 --- a/quantum/process_keycode/process_chording.c +++ /dev/null @@ -1,76 +0,0 @@ -/* 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_chording.h" - -bool keys_chord(uint8_t keys[]) { -  uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); -  bool pass = true; -  uint8_t in = 0; -  for (uint8_t i = 0; i < chord_key_count; i++) { -    bool found = false; -    for (uint8_t j = 0; j < keys_size; j++) { -      if (chord_keys[i] == (keys[j] & 0xFF)) { -        in++; // detects key in chord -        found = true; -        break; -      } -    } -    if (found) -      continue; -    if (chord_keys[i] != 0)  { -      pass = false; // makes sure rest are blank -    } -  } -  return (pass && (in == keys_size)); -} - -bool process_chording(uint16_t keycode, keyrecord_t *record) { -  if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { -    if (record->event.pressed) { -      if (!chording) { -        chording = true; -        for (uint8_t i = 0; i < CHORDING_MAX; i++) -          chord_keys[i] = 0; -        chord_key_count = 0; -        chord_key_down = 0; -      } -      chord_keys[chord_key_count] = (keycode & 0xFF); -      chord_key_count++; -      chord_key_down++; -      return false; -    } else { -      if (chording) { -        chord_key_down--; -        if (chord_key_down == 0) { -          chording = false; -          // Chord Dictionary -          if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { -            register_code(KC_A); -            unregister_code(KC_A); -            return false; -          } -          for (uint8_t i = 0; i < chord_key_count; i++) { -            register_code(chord_keys[i]); -            unregister_code(chord_keys[i]); -            return false; -          } -        } -      } -    } -  } -  return true; -} diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c index 1e950d1113..8238c263f9 100644 --- a/quantum/process_keycode/process_clicky.c +++ b/quantum/process_keycode/process_clicky.c @@ -3,11 +3,6 @@  #ifdef AUDIO_CLICKY -#ifdef AUDIO_CLICKY_ON -bool clicky_enable = true; -#else // AUDIO_CLICKY_ON -bool clicky_enable = false; -#endif // AUDIO_CLICKY_ON  #ifndef AUDIO_CLICKY_FREQ_DEFAULT  #define AUDIO_CLICKY_FREQ_DEFAULT 440.0f  #endif // !AUDIO_CLICKY_FREQ_DEFAULT @@ -25,8 +20,11 @@ bool clicky_enable = false;  #endif // !AUDIO_CLICKY_FREQ_RANDOMNESS  float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; +float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS;  float clicky_song[][2]  = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations +extern audio_config_t audio_config; +  #ifndef NO_MUSIC_MODE  extern bool music_activated;  extern bool midi_activated; @@ -36,31 +34,61 @@ void clicky_play(void) {  #ifndef NO_MUSIC_MODE    if (music_activated || midi_activated) return;  #endif // !NO_MUSIC_MODE -  clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); -  clicky_song[1][0] = clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); +  clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); +  clicky_song[1][0] = clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) );    PLAY_SONG(clicky_song);  } +void clicky_freq_up(void) { +  float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; +  if (new_freq < AUDIO_CLICKY_FREQ_MAX) { +    clicky_freq = new_freq; +  } +} + +void clicky_freq_down(void) { +  float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR; +  if (new_freq > AUDIO_CLICKY_FREQ_MIN) { +    clicky_freq = new_freq; +  } +} + +void clicky_freq_reset(void) { +  clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; +} + +void clicky_toggle(void) { +  audio_config.clicky_enable ^= 1; +  eeconfig_update_audio(audio_config.raw); +} + +void clicky_on(void) { +  audio_config.clicky_enable = 1; +  eeconfig_update_audio(audio_config.raw); +} + +void clicky_off(void) { +  audio_config.clicky_enable = 0; +  eeconfig_update_audio(audio_config.raw); +} + +bool is_clicky_on(void) { +      return (audio_config.clicky_enable != 0); +} +  bool process_clicky(uint16_t keycode, keyrecord_t *record) { -    if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_enable = !clicky_enable; } +    if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_toggle(); } -    if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; } +    if (keycode == CLICKY_ENABLE && record->event.pressed) { clicky_on(); } +    if (keycode == CLICKY_DISABLE && record->event.pressed) { clicky_off(); } -    if (keycode == CLICKY_UP && record->event.pressed) { -      float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; -      if (new_freq < AUDIO_CLICKY_FREQ_MAX) { -        clicky_freq = new_freq; -      } -    } -    if (keycode == CLICKY_DOWN && record->event.pressed) { -      float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR; -      if (new_freq > AUDIO_CLICKY_FREQ_MIN) { -        clicky_freq = new_freq; -      } -    } +    if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq_reset(); } + +    if (keycode == CLICKY_UP && record->event.pressed) { clicky_freq_up(); } +    if (keycode == CLICKY_DOWN && record->event.pressed) { clicky_freq_down(); } -    if ( clicky_enable ) { +    if ( audio_config.clicky_enable ) {        if (record->event.pressed) {          clicky_play();;        } diff --git a/quantum/process_keycode/process_clicky.h b/quantum/process_keycode/process_clicky.h index e274af56f1..f746edb951 100644 --- a/quantum/process_keycode/process_clicky.h +++ b/quantum/process_keycode/process_clicky.h @@ -4,4 +4,14 @@  void clicky_play(void);  bool process_clicky(uint16_t keycode, keyrecord_t *record); +void clicky_freq_up(void); +void clicky_freq_down(void); +void clicky_freq_reset(void); + +void clicky_toggle(void); +void clicky_on(void); +void clicky_off(void); + +bool is_clicky_on(void); +  #endif diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c index c87ef115af..897e9eabf6 100644 --- a/quantum/process_keycode/process_leader.c +++ b/quantum/process_keycode/process_leader.c @@ -14,7 +14,7 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef DISABLE_LEADER +#ifdef LEADER_ENABLE  #include "process_leader.h" @@ -35,25 +35,40 @@ uint16_t leader_time = 0;  uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};  uint8_t leader_sequence_size = 0; +void qk_leader_start(void) { +  if (leading) { return; } +  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; +} +  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; +    if (leading) { +      if (timer_elapsed(leader_time) < LEADER_TIMEOUT) { +#ifndef LEADER_KEY_STRICT_KEY_PROCESSING +        if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { +          keycode = keycode & 0xFF; +        } +#endif // LEADER_KEY_STRICT_KEY_PROCESSING +        leader_sequence[leader_sequence_size] = keycode; +        leader_sequence_size++; +#ifdef LEADER_PER_KEY_TIMING +        leader_time = timer_read(); +#endif +        return false; +      } +    } else { +      if (keycode == KC_LEAD) { +        qk_leader_start(); +      }      }    }    return true; diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h index 59c3eed1be..15bccc3f67 100644 --- a/quantum/process_keycode/process_leader.h +++ b/quantum/process_keycode/process_leader.h @@ -24,7 +24,7 @@ bool process_leader(uint16_t keycode, keyrecord_t *record);  void leader_start(void);  void leader_end(void); - +void qk_leader_start(void);  #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)  #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 8337806912..16d33dddee 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -16,6 +16,10 @@  #include "quantum.h"  #include "action_tapping.h" +#ifndef TAPPING_TERM +#define TAPPING_TERM 200 +#endif +  #ifndef NO_ACTION_ONESHOT  uint8_t get_oneshot_mods(void);  #endif @@ -127,6 +131,7 @@ void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {        if (keycode == action->state.keycode && keycode == last_td)          continue;        action->state.interrupted = true; +      action->state.interrupting_keycode = keycode;        process_tap_dance_action_on_dance_finished (action);        reset_tap_dance (&action->state);      } @@ -205,5 +210,6 @@ void reset_tap_dance (qk_tap_dance_state_t *state) {    state->count = 0;    state->interrupted = false;    state->finished = false; +  state->interrupting_keycode = 0;    last_td = 0;  } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 8b0a47c49b..ca12f4746e 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -27,6 +27,7 @@ typedef struct    uint8_t oneshot_mods;    uint8_t weak_mods;    uint16_t keycode; +  uint16_t interrupting_keycode;    uint16_t timer;    bool interrupted;    bool pressed; diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c index 86c0937f5e..5de2e41fc3 100644 --- a/quantum/process_keycode/process_ucis.c +++ b/quantum/process_keycode/process_ucis.c @@ -32,6 +32,10 @@ void qk_ucis_start_user(void) {    unicode_input_finish();  } +__attribute__((weak)) +void qk_ucis_success(uint8_t symbol_index) { +} +  static bool is_uni_seq(char *seq) {    uint8_t i; @@ -142,6 +146,10 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) {      }      unicode_input_finish(); +    if (symbol_found) { +      qk_ucis_success(i); +    } +      qk_ucis_state.in_progress = false;      return false;    } diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h index 3f736a709f..b114d839ab 100644 --- a/quantum/process_keycode/process_ucis.h +++ b/quantum/process_keycode/process_ucis.h @@ -14,8 +14,7 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef PROCESS_UCIS_H -#define PROCESS_UCIS_H +#pragma once  #include "quantum.h"  #include "process_unicode_common.h" @@ -45,7 +44,6 @@ extern const qk_ucis_symbol_t ucis_symbol_table[];  void qk_ucis_start(void);  void qk_ucis_start_user(void);  void qk_ucis_symbol_fallback (void); +void qk_ucis_success(uint8_t symbol_index);  void register_ucis(const char *hex);  bool process_ucis (uint16_t keycode, keyrecord_t *record); - -#endif diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index fd008eca12..19beb84520 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -17,14 +17,8 @@  #include "action_util.h"  #include "eeprom.h" -static uint8_t first_flag = 0; -  bool process_unicode(uint16_t keycode, keyrecord_t *record) {    if (keycode > QK_UNICODE && record->event.pressed) { -    if (first_flag == 0) { -      set_unicode_input_mode(eeprom_read_byte(EECONFIG_UNICODEMODE)); -      first_flag = 1; -    }      uint16_t unicode = keycode & 0x7FFF;      unicode_input_start();      register_hex(unicode); @@ -32,4 +26,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {    }    return true;  } - diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index c525b74f03..0913e99107 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -13,12 +13,9 @@   * 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 PROCESS_UNICODE_H -#define PROCESS_UNICODE_H +#pragma once  #include "quantum.h"  #include "process_unicode_common.h"  bool process_unicode(uint16_t keycode, keyrecord_t *record); - -#endif diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 7f34ad57cf..3286f45b5d 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -16,94 +16,115 @@  #include "process_unicode_common.h"  #include "eeprom.h" +#include <ctype.h> +#include <string.h> -static uint8_t input_mode; -uint8_t mods; +unicode_config_t unicode_config; +#if UNICODE_SELECTED_MODES != -1 +static uint8_t selected[] = { UNICODE_SELECTED_MODES }; +static uint8_t selected_count = sizeof selected / sizeof *selected; +static uint8_t selected_index; +#endif -void set_unicode_input_mode(uint8_t os_target) -{ -  input_mode = os_target; -  eeprom_update_byte(EECONFIG_UNICODEMODE, os_target); +void unicode_input_mode_init(void) { +  unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); +#if UNICODE_SELECTED_MODES != -1 +  #if UNICODE_CYCLE_PERSIST +  // Find input_mode in selected modes +  uint8_t i; +  for (i = 0; i < selected_count; i++) { +    if (selected[i] == unicode_config.input_mode) { +      selected_index = i; +      break; +    } +  } +  if (i == selected_count) { +    // Not found: input_mode isn't selected, change to one that is +    unicode_config.input_mode = selected[selected_index = 0]; +  } +  #else +  // Always change to the first selected input mode +  unicode_config.input_mode = selected[selected_index = 0]; +  #endif +#endif +  dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);  }  uint8_t get_unicode_input_mode(void) { -  return input_mode; +  return unicode_config.input_mode;  } +void set_unicode_input_mode(uint8_t mode) { +  unicode_config.input_mode = mode; +  persist_unicode_input_mode(); +  dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); +} + +void cycle_unicode_input_mode(uint8_t offset) { +#if UNICODE_SELECTED_MODES != -1 +  selected_index = (selected_index + offset) % selected_count; +  unicode_config.input_mode = selected[selected_index]; +  #if UNICODE_CYCLE_PERSIST +  persist_unicode_input_mode(); +  #endif +  dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode); +#endif +} + +void persist_unicode_input_mode(void) { +  eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); +} + +static uint8_t saved_mods; +  __attribute__((weak)) -void unicode_input_start (void) { -  // save current mods -  mods = keyboard_report->mods; - -  // unregister all mods to start from clean state -  if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT); -  if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT); -  if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL); -  if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL); -  if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT); -  if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT); -  if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI); -  if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI); - -  switch(input_mode) { +void unicode_input_start(void) { +  saved_mods = get_mods(); // Save current mods +  clear_mods(); // Unregister mods to start from a clean state + +  switch (unicode_config.input_mode) {    case UC_OSX: -    register_code(KC_LALT); -    break; -  case UC_OSX_RALT: -    register_code(KC_RALT); +    register_code(UNICODE_OSX_KEY);      break;    case UC_LNX:      register_code(KC_LCTL);      register_code(KC_LSFT); -    register_code(KC_U); -    unregister_code(KC_U); +    tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test      unregister_code(KC_LSFT);      unregister_code(KC_LCTL);      break;    case UC_WIN:      register_code(KC_LALT); -    register_code(KC_PPLS); -    unregister_code(KC_PPLS); +    tap_code(KC_PPLS);      break;    case UC_WINC: -    register_code(KC_RALT); -    unregister_code(KC_RALT); -    register_code(KC_U); -    unregister_code(KC_U); +    tap_code(UNICODE_WINC_KEY); +    tap_code(KC_U); +    break;    } +    wait_ms(UNICODE_TYPE_DELAY);  }  __attribute__((weak)) -void unicode_input_finish (void) { -  switch(input_mode) { -    case UC_OSX: -    case UC_WIN: -      unregister_code(KC_LALT); -      break; -    case UC_OSX_RALT: -      unregister_code(KC_RALT); -      break; -    case UC_LNX: -      register_code(KC_SPC); -      unregister_code(KC_SPC); -      break; +void unicode_input_finish(void) { +  switch (unicode_config.input_mode) { +  case UC_OSX: +    unregister_code(UNICODE_OSX_KEY); +    break; +  case UC_LNX: +    tap_code(KC_SPC); +    break; +  case UC_WIN: +    unregister_code(KC_LALT); +    break;    } -  // reregister previously set mods -  if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT); -  if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT); -  if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL); -  if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL); -  if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT); -  if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT); -  if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI); -  if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI); +  set_mods(saved_mods); // Reregister previously set mods  }  __attribute__((weak)) -uint16_t hex_to_keycode(uint8_t hex) -{ +uint16_t hex_to_keycode(uint8_t hex) {    if (hex == 0x0) {      return KC_0;    } else if (hex < 0xA) { @@ -116,7 +137,89 @@ uint16_t hex_to_keycode(uint8_t hex)  void register_hex(uint16_t hex) {    for(int i = 3; i >= 0; i--) {      uint8_t digit = ((hex >> (i*4)) & 0xF); -    register_code(hex_to_keycode(digit)); -    unregister_code(hex_to_keycode(digit)); +    tap_code(hex_to_keycode(digit)); +  } +} + +void send_unicode_hex_string(const char *str) { +  if (!str) { return; } + +  while (*str) { +    // Find the next code point (token) in the string +    for (; *str == ' '; str++); +    size_t n = strcspn(str, " "); // Length of the current token +    char code_point[n+1]; +    strncpy(code_point, str, n); +    code_point[n] = '\0'; // Make sure it's null-terminated + +    // Normalize the code point: make all hex digits lowercase +    for (char *p = code_point; *p; p++) { +      *p = tolower((unsigned char)*p); +    } + +    // Send the code point as a Unicode input string +    unicode_input_start(); +    send_string(code_point); +    unicode_input_finish(); + +    str += n; // Move to the first ' ' (or '\0') after the current token +  } +} + +bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { +  if (record->event.pressed) { +    switch (keycode) { +    case UNICODE_MODE_FORWARD: +      cycle_unicode_input_mode(+1); +      break; +    case UNICODE_MODE_REVERSE: +      cycle_unicode_input_mode(-1); +      break; + +    case UNICODE_MODE_OSX: +      set_unicode_input_mode(UC_OSX); +#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX) +      static float song_osx[][2] = UNICODE_SONG_OSX; +      PLAY_SONG(song_osx); +#endif +      break; +    case UNICODE_MODE_LNX: +      set_unicode_input_mode(UC_LNX); +#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX) +      static float song_lnx[][2] = UNICODE_SONG_LNX; +      PLAY_SONG(song_lnx); +#endif +      break; +    case UNICODE_MODE_WIN: +      set_unicode_input_mode(UC_WIN); +#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN) +      static float song_win[][2] = UNICODE_SONG_WIN; +      PLAY_SONG(song_win); +#endif +      break; +    case UNICODE_MODE_BSD: +      set_unicode_input_mode(UC_BSD); +#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD) +      static float song_bsd[][2] = UNICODE_SONG_BSD; +      PLAY_SONG(song_bsd); +#endif +      break; +    case UNICODE_MODE_WINC: +      set_unicode_input_mode(UC_WINC); +#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC) +      static float song_winc[][2] = UNICODE_SONG_WINC; +      PLAY_SONG(song_winc); +#endif +      break; +    }    } +#if   defined(UNICODE_ENABLE) +  return process_unicode(keycode, record); +#elif defined(UNICODEMAP_ENABLE) +  return process_unicode_map(keycode, record); +#elif defined(UCIS_ENABLE) +  return process_ucis(keycode, record); +#else +  return true; +#endif  } diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index 4d2b04fb39..e608ab76be 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h @@ -14,33 +14,71 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef PROCESS_UNICODE_COMMON_H -#define PROCESS_UNICODE_COMMON_H +#pragma once  #include "quantum.h" -#ifndef UNICODE_TYPE_DELAY -#define UNICODE_TYPE_DELAY 10 +#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1 +  #error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time" +#endif + +// Keycodes used for starting Unicode input on different platforms +#ifndef UNICODE_OSX_KEY +  #define UNICODE_OSX_KEY  KC_LALT +#endif +#ifndef UNICODE_WINC_KEY +  #define UNICODE_WINC_KEY KC_RALT  #endif -__attribute__ ((unused)) -static uint8_t input_mode; +// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) +// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX +#ifndef UNICODE_SELECTED_MODES +  #define UNICODE_SELECTED_MODES -1 +#endif + +// Whether input mode changes in cycle should be written to EEPROM +#ifndef UNICODE_CYCLE_PERSIST +  #define UNICODE_CYCLE_PERSIST true +#endif -void set_unicode_input_mode(uint8_t os_target); +// Delay between starting Unicode input and sending a sequence, in ms +#ifndef UNICODE_TYPE_DELAY +  #define UNICODE_TYPE_DELAY 10 +#endif + +enum unicode_input_modes { +  UC_OSX,   // Mac OS X using Unicode Hex Input +  UC_LNX,   // Linux using IBus +  UC_WIN,   // Windows using EnableHexNumpad +  UC_BSD,   // BSD (not implemented) +  UC_WINC,  // Windows using WinCompose (https://github.com/samhocevar/wincompose) +  UC__COUNT // Number of available input modes (always leave at the end) +}; + +typedef union { +  uint32_t raw; +  struct { +    uint8_t input_mode : 8; +  }; +} unicode_config_t; + +extern unicode_config_t unicode_config; + +void unicode_input_mode_init(void);  uint8_t get_unicode_input_mode(void); +void set_unicode_input_mode(uint8_t mode); +void cycle_unicode_input_mode(uint8_t offset); +void persist_unicode_input_mode(void); +  void unicode_input_start(void);  void unicode_input_finish(void); +  void register_hex(uint16_t hex); +void send_unicode_hex_string(const char *str); -#define UC_OSX 0  // Mac OS X -#define UC_LNX 1  // Linux -#define UC_WIN 2  // Windows 'HexNumpad' -#define UC_BSD 3  // BSD (not implemented) -#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose -#define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose +bool process_unicode_common(uint16_t keycode, keyrecord_t *record);  #define UC_BSPC	UC(0x0008) -  #define UC_SPC	UC(0x0020)  #define UC_EXLM	UC(0x0021) @@ -145,5 +183,3 @@ void register_hex(uint16_t hex);  #define UC_RCBR	UC(0x007D)  #define UC_TILD	UC(0x007E)  #define UC_DEL	UC(0x007F) - -#endif diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c index 47c27b9117..75f35112b1 100644 --- a/quantum/process_keycode/process_unicodemap.c +++ b/quantum/process_keycode/process_unicodemap.c @@ -50,7 +50,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {      const uint32_t* map = unicode_map;      uint16_t index = keycode - QK_UNICODE_MAP;      uint32_t code = pgm_read_dword(&map[index]); -    if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) { +    if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) {        // Convert to UTF-16 surrogate pair        code -= 0x10000;        uint32_t lo = code & 0x3ff; @@ -59,7 +59,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {        register_hex32(hi + 0xd800);        register_hex32(lo + 0xdc00);        unicode_input_finish(); -    } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) { +    } else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {        // when character is out of range supported by the OS        unicode_map_input_error();      } else { diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h index 929c88c0b6..f6d64bb86b 100644 --- a/quantum/process_keycode/process_unicodemap.h +++ b/quantum/process_keycode/process_unicodemap.h @@ -14,12 +14,10 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef PROCESS_UNICODEMAP_H -#define PROCESS_UNICODEMAP_H +#pragma once  #include "quantum.h"  #include "process_unicode_common.h"  void unicode_map_input_error(void);  bool process_unicode_map(uint16_t keycode, keyrecord_t *record); -#endif diff --git a/quantum/quantum.c b/quantum/quantum.c index ab47fa48ff..85db100ab4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -42,6 +42,11 @@ extern backlight_config_t backlight_config;  #include "process_midi.h"  #endif + +#ifdef ENCODER_ENABLE +#include "encoder.h" +#endif +  #ifdef AUDIO_ENABLE    #ifndef GOODBYE_SONG      #define GOODBYE_SONG SONG(GOODBYE_SOUND) @@ -127,6 +132,14 @@ void unregister_code16 (uint16_t code) {    }  } +void tap_code16(uint16_t code) { +  register_code16(code); +  #if TAP_CODE_DELAY > 0 +    wait_ms(TAP_CODE_DELAY); +  #endif +  unregister_code16(code); +} +  __attribute__ ((weak))  bool process_action_kb(keyrecord_t *record) {    return true; @@ -196,7 +209,7 @@ bool process_record_quantum(keyrecord_t *record) {    keypos_t key = record->event.key;    uint16_t keycode; -  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) +  #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)      /* TODO: Use store_or_get_action() or a similar function. */      if (!disable_action_cache) {        uint8_t layer; @@ -230,7 +243,7 @@ bool process_record_quantum(keyrecord_t *record) {      process_key_lock(&keycode, record) &&    #endif    #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) -      process_clicky(keycode, record) && +    process_clicky(keycode, record) &&    #endif //AUDIO_CLICKY      process_record_kb(keycode, record) &&    #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES) @@ -245,36 +258,27 @@ bool process_record_quantum(keyrecord_t *record) {    #ifdef STENO_ENABLE      process_steno(keycode, record) &&    #endif -  #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE) +  #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)      process_music(keycode, record) &&    #endif    #ifdef TAP_DANCE_ENABLE      process_tap_dance(keycode, record) &&    #endif -  #ifndef DISABLE_LEADER -    process_leader(keycode, record) && +  #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE) +    process_unicode_common(keycode, record) &&    #endif -  #ifndef DISABLE_CHORDING -    process_chording(keycode, record) && +  #ifdef LEADER_ENABLE +    process_leader(keycode, record) &&    #endif    #ifdef COMBO_ENABLE      process_combo(keycode, record) &&    #endif -  #ifdef UNICODE_ENABLE -    process_unicode(keycode, record) && -  #endif -  #ifdef UCIS_ENABLE -    process_ucis(keycode, record) && -  #endif    #ifdef PRINTING_ENABLE      process_printer(keycode, record) &&    #endif    #ifdef AUTO_SHIFT_ENABLE      process_auto_shift(keycode, record) &&    #endif -  #ifdef UNICODEMAP_ENABLE -    process_unicode_map(keycode, record) && -  #endif    #ifdef TERMINAL_ENABLE      process_terminal(keycode, record) &&    #endif @@ -296,6 +300,11 @@ bool process_record_quantum(keyrecord_t *record) {            print("DEBUG: enabled.\n");        }      return false; +    case EEPROM_RESET: +      if (record->event.pressed) { +          eeconfig_init(); +      } +    return false;    #ifdef FAUXCLICKY_ENABLE    case FC_TOG:      if (record->event.pressed) { @@ -445,75 +454,97 @@ bool process_record_quantum(keyrecord_t *record) {      return false;    case RGB_MODE_PLAIN:      if (record->event.pressed) { -      rgblight_mode(1); +      rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);        #ifdef SPLIT_KEYBOARD            RGB_DIRTY = true;        #endif      }      return false;    case RGB_MODE_BREATHE: +  #ifdef RGBLIGHT_EFFECT_BREATHING      if (record->event.pressed) { -      if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) { +      if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {          rgblight_step();        } else { -        rgblight_mode(2); +        rgblight_mode(RGBLIGHT_MODE_BREATHING);        }      } +  #endif      return false;    case RGB_MODE_RAINBOW: +  #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD      if (record->event.pressed) { -      if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) { +      if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {          rgblight_step();        } else { -        rgblight_mode(6); +        rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);        }      } +  #endif      return false;    case RGB_MODE_SWIRL: +  #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL      if (record->event.pressed) { -      if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) { +      if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {          rgblight_step();        } else { -        rgblight_mode(9); +        rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);        }      } +  #endif      return false;    case RGB_MODE_SNAKE: +  #ifdef RGBLIGHT_EFFECT_SNAKE      if (record->event.pressed) { -      if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) { +      if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {          rgblight_step();        } else { -        rgblight_mode(15); +        rgblight_mode(RGBLIGHT_MODE_SNAKE);        }      } +  #endif      return false;    case RGB_MODE_KNIGHT: +  #ifdef RGBLIGHT_EFFECT_KNIGHT      if (record->event.pressed) { -      if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) { +      if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {          rgblight_step();        } else { -        rgblight_mode(21); +        rgblight_mode(RGBLIGHT_MODE_KNIGHT);        }      } +  #endif      return false;    case RGB_MODE_XMAS: +  #ifdef RGBLIGHT_EFFECT_CHRISTMAS      if (record->event.pressed) { -      rgblight_mode(24); +      rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);      } +  #endif      return false;    case RGB_MODE_GRADIENT: +  #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT      if (record->event.pressed) { -      if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) { +      if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && +          (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {          rgblight_step();        } else { -        rgblight_mode(25); +        rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);        }      } +  #endif      return false;    case RGB_MODE_RGBTEST: +  #ifdef RGBLIGHT_EFFECT_RGB_TEST      if (record->event.pressed) { -      rgblight_mode(35); +      rgblight_mode(RGBLIGHT_MODE_RGB_TEST);      } +  #endif      return false;    #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)      #ifdef PROTOCOL_LUFA @@ -607,6 +638,17 @@ bool process_record_quantum(keyrecord_t *record) {                PLAY_SONG(ag_norm_song);              #endif              break; +          case MAGIC_TOGGLE_ALT_GUI: +            keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; +            keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; +            #ifdef AUDIO_ENABLE +              if (keymap_config.swap_ralt_rgui) { +                PLAY_SONG(ag_swap_song); +              } else { +                PLAY_SONG(ag_norm_song); +              } +            #endif +            break;            case MAGIC_TOGGLE_NKRO:              keymap_config.nkro = !keymap_config.nkro;              break; @@ -914,7 +956,42 @@ void tap_random_base64(void) {    }  } +__attribute__((weak)) +void bootmagic_lite(void) { +  // The lite version of TMK's bootmagic based on Wilba. +  // 100% less potential for accidentally making the +  // keyboard do stupid things. + +  // We need multiple scans because debouncing can't be turned off. +  matrix_scan(); +  #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0 +    wait_ms(DEBOUNCING_DELAY * 2); +  #elif defined(DEBOUNCE) && DEBOUNCE > 0 +    wait_ms(DEBOUNCE * 2); +  #else +    wait_ms(30); +  #endif +  matrix_scan(); + +  // If the Esc and space bar are held down on power up, +  // reset the EEPROM valid state and jump to bootloader. +  // Assumes Esc is at [0,0]. +  // This isn't very generalized, but we need something that doesn't +  // rely on user's keymaps in firmware or EEPROM. +  if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { +    eeconfig_disable(); +    // Jump to bootloader. +    bootloader_jump(); +  } +} +  void matrix_init_quantum() { +  #ifdef BOOTMAGIC_LITE +    bootmagic_lite(); +  #endif +  if (!eeconfig_is_enabled()) { +    eeconfig_init(); +  }    #ifdef BACKLIGHT_ENABLE      backlight_init_ports();    #endif @@ -924,6 +1001,12 @@ void matrix_init_quantum() {    #ifdef RGB_MATRIX_ENABLE      rgb_matrix_init();    #endif +  #ifdef ENCODER_ENABLE +    encoder_init(); +  #endif +  #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE) +    unicode_input_mode_init(); +  #endif    matrix_init_kb();  } @@ -958,6 +1041,10 @@ void matrix_scan_quantum() {      rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));    #endif +  #ifdef ENCODER_ENABLE +    encoder_read(); +  #endif +    matrix_scan_kb();  }  #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) diff --git a/quantum/quantum.h b/quantum/quantum.h index 1db9846f04..f78915fdfb 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -1,4 +1,4 @@ -/* Copyright 2016-2017 Erez Zukerman, Jack Humbert +/* Copyright 2016-2018 Erez Zukerman, Jack Humbert, Yiancar   *   * 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 @@ -17,9 +17,12 @@  #define QUANTUM_H  #if defined(__AVR__) -#include <avr/pgmspace.h> -#include <avr/io.h> -#include <avr/interrupt.h> +    #include <avr/pgmspace.h> +    #include <avr/io.h> +    #include <avr/interrupt.h> +#endif +#if defined(PROTOCOL_CHIBIOS) +    #include "hal.h"  #endif  #include "wait.h"  #include "matrix.h" @@ -32,6 +35,12 @@  #endif  #ifdef RGBLIGHT_ENABLE    #include "rgblight.h" +#else +    #ifdef RGB_MATRIX_ENABLE +        /* dummy define RGBLIGHT_MODE_xxxx */ +        #define RGBLIGHT_H_DUMMY_DEFINE +        #include "rgblight.h" +    #endif  #endif  #ifdef SPLIT_KEYBOARD @@ -39,7 +48,7 @@  #endif  #ifdef RGB_MATRIX_ENABLE -	#include "rgb_matrix.h" +    #include "rgb_matrix.h"  #endif  #include "action_layer.h" @@ -58,78 +67,119 @@  extern uint32_t default_layer_state;  #ifndef NO_ACTION_LAYER -	extern uint32_t layer_state; +    extern uint32_t layer_state;  #endif  #ifdef MIDI_ENABLE  #ifdef MIDI_ADVANCED -	#include "process_midi.h" +    #include "process_midi.h"  #endif  #endif // MIDI_ENABLE  #ifdef AUDIO_ENABLE -	#include "audio.h" - 	#include "process_audio.h" -  #ifdef AUDIO_CLICKY -    #include "process_clicky.h" -  #endif // AUDIO_CLICKY +    #include "audio.h" +    #include "process_audio.h" +    #ifdef AUDIO_CLICKY +        #include "process_clicky.h" +    #endif // AUDIO_CLICKY  #endif  #ifdef STENO_ENABLE -	#include "process_steno.h" +    #include "process_steno.h"  #endif  #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) -	#include "process_music.h" -#endif - -#ifndef DISABLE_LEADER -	#include "process_leader.h" +    #include "process_music.h"  #endif -#define DISABLE_CHORDING -#ifndef DISABLE_CHORDING -	#include "process_chording.h" +#ifdef LEADER_ENABLE +    #include "process_leader.h"  #endif  #ifdef UNICODE_ENABLE -	#include "process_unicode.h" +    #include "process_unicode.h"  #endif  #ifdef UCIS_ENABLE -	#include "process_ucis.h" +    #include "process_ucis.h"  #endif  #ifdef UNICODEMAP_ENABLE -	#include "process_unicodemap.h" +    #include "process_unicodemap.h"  #endif -#include "process_tap_dance.h" +#ifdef TAP_DANCE_ENABLE +  #include "process_tap_dance.h" +#endif  #ifdef PRINTING_ENABLE -	#include "process_printer.h" +    #include "process_printer.h"  #endif  #ifdef AUTO_SHIFT_ENABLE -	#include "process_auto_shift.h" +    #include "process_auto_shift.h"  #endif  #ifdef COMBO_ENABLE -	#include "process_combo.h" +    #include "process_combo.h"  #endif  #ifdef KEY_LOCK_ENABLE -	#include "process_key_lock.h" +    #include "process_key_lock.h"  #endif  #ifdef TERMINAL_ENABLE -	#include "process_terminal.h" +    #include "process_terminal.h"  #else -	#include "process_terminal_nop.h" +    #include "process_terminal_nop.h"  #endif  #ifdef HD44780_ENABLE -	#include "hd44780.h" +    #include "hd44780.h" +#endif + +//Function substitutions to ease GPIO manipulation +#ifdef __AVR__ +    #define PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset) + +    #define pin_t uint8_t +    #define setPinInput(pin) PIN_ADDRESS(pin, 1) &= ~ _BV(pin & 0xF) +    #define setPinInputHigh(pin) ({\ +            PIN_ADDRESS(pin, 1) &= ~ _BV(pin & 0xF);\ +            PIN_ADDRESS(pin, 2) |=   _BV(pin & 0xF);\ +            }) +    #define setPinInputLow(pin) _Static_assert(0, "AVR Processors cannot impliment an input as pull low") +    #define setPinOutput(pin) PIN_ADDRESS(pin, 1) |= _BV(pin & 0xF) + +    #define writePinHigh(pin) PIN_ADDRESS(pin, 2) |=  _BV(pin & 0xF) +    #define writePinLow(pin) PIN_ADDRESS(pin, 2) &= ~_BV(pin & 0xF) +    static inline void writePin(pin_t pin, uint8_t level){ +        if (level){ +            PIN_ADDRESS(pin, 2) |=  _BV(pin & 0xF); +        } else { +            PIN_ADDRESS(pin, 2) &= ~_BV(pin & 0xF); +        } +    } + +    #define readPin(pin) ((bool)(PIN_ADDRESS(pin, 0) & _BV(pin & 0xF))) +#elif defined(PROTOCOL_CHIBIOS) +    #define pin_t ioline_t +    #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) +    #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) +    #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) +    #define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL) + +    #define writePinHigh(pin) palSetLine(pin) +    #define writePinLow(pin) palClearLine(pin) +    static inline void writePin(pin_t pin, uint8_t level){ +        if (level){ +            palSetLine(pin); +        } else { +            palClearLine(pin); +        } +    } + +    #define readPin(pin) palReadLine(pin)  #endif  #define STRINGIZE(z) #z @@ -147,6 +197,7 @@ extern uint32_t default_layer_state;  #define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)  #define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT)  #define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) +#define SS_ALGR(string) SS_RALT(string)  #define SEND_STRING(str) send_string_P(PSTR(str))  extern const bool ascii_to_shift_lut[0x80]; @@ -176,13 +227,23 @@ bool process_action_kb(keyrecord_t *record);  bool process_record_kb(uint16_t keycode, keyrecord_t *record);  bool process_record_user(uint16_t keycode, keyrecord_t *record); +#ifndef BOOTMAGIC_LITE_COLUMN +  #define BOOTMAGIC_LITE_COLUMN 0 +#endif +#ifndef BOOTMAGIC_LITE_ROW +  #define BOOTMAGIC_LITE_ROW 0 +#endif + +void bootmagic_lite(void); +  void reset_keyboard(void);  void startup_user(void);  void shutdown_user(void); -void register_code16 (uint16_t code); -void unregister_code16 (uint16_t code); +void register_code16(uint16_t code); +void unregister_code16(uint16_t code); +void tap_code16(uint16_t code);  #ifdef BACKLIGHT_ENABLE  void backlight_init_ports(void); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index f2cdb8a3bf..2b309f4d52 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -63,10 +63,6 @@ enum quantum_keycodes {      QK_ONE_SHOT_LAYER_MAX = 0x54FF,      QK_ONE_SHOT_MOD       = 0x5500,      QK_ONE_SHOT_MOD_MAX   = 0x55FF, -#ifndef DISABLE_CHORDING -    QK_CHORDING           = 0x5600, -    QK_CHORDING_MAX       = 0x56FF, -#endif      QK_TAP_DANCE          = 0x5700,      QK_TAP_DANCE_MAX      = 0x57FF,      QK_LAYER_TAP_TOGGLE   = 0x5800, @@ -85,9 +81,6 @@ enum quantum_keycodes {  #endif      QK_MOD_TAP            = 0x6000,      QK_MOD_TAP_MAX        = 0x7FFF, -#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE) -    #error "Cannot enable both UNICODEMAP && UNICODE" -#endif  #ifdef UNICODE_ENABLE      QK_UNICODE            = 0x8000,      QK_UNICODE_MAX        = 0xFFFF, @@ -120,10 +113,11 @@ enum quantum_keycodes {      MAGIC_UNHOST_NKRO,      MAGIC_UNSWAP_ALT_GUI,      MAGIC_TOGGLE_NKRO, +    MAGIC_TOGGLE_ALT_GUI,      GRAVE_ESC,      // Leader key -#ifndef DISABLE_LEADER +#ifdef LEADER_ENABLE      KC_LEAD,  #endif @@ -142,10 +136,13 @@ enum quantum_keycodes {      // Faux clicky as part of main audio feature      CLICKY_TOGGLE, +    CLICKY_ENABLE, +    CLICKY_DISABLE,      CLICKY_UP,      CLICKY_DOWN,      CLICKY_RESET, +  #ifdef FAUXCLICKY_ENABLE      // Faux clicky      FC_ON, @@ -454,32 +451,43 @@ enum quantum_keycodes {      TERM_OFF,  #endif +    EEPROM_RESET, + +    UNICODE_MODE_FORWARD, +    UNICODE_MODE_REVERSE, + +    UNICODE_MODE_OSX, +    UNICODE_MODE_LNX, +    UNICODE_MODE_WIN, +    UNICODE_MODE_BSD, +    UNICODE_MODE_WINC, +      // always leave at the end      SAFE_RANGE  };  // Ability to use mods in layouts -#define LCTL(kc) (kc | QK_LCTL) -#define LSFT(kc) (kc | QK_LSFT) -#define LALT(kc) (kc | QK_LALT) -#define LGUI(kc) (kc | QK_LGUI) +#define LCTL(kc) (QK_LCTL | (kc)) +#define LSFT(kc) (QK_LSFT | (kc)) +#define LALT(kc) (QK_LALT | (kc)) +#define LGUI(kc) (QK_LGUI | (kc))  #define LCMD(kc) LGUI(kc)  #define LWIN(kc) LGUI(kc) -#define RCTL(kc) (kc | QK_RCTL) -#define RSFT(kc) (kc | QK_RSFT) -#define RALT(kc) (kc | QK_RALT) -#define RGUI(kc) (kc | QK_RGUI) +#define RCTL(kc) (QK_RCTL | (kc)) +#define RSFT(kc) (QK_RSFT | (kc)) +#define RALT(kc) (QK_RALT | (kc)) +#define ALGR(kc) RALT(kc) +#define RGUI(kc) (QK_RGUI | (kc))  #define RCMD(kc) RGUI(kc)  #define RWIN(kc) RGUI(kc) -#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) -#define MEH(kc)  (kc | QK_LCTL | QK_LSFT | QK_LALT) -#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) -#define ALTG(kc) (kc | QK_RCTL | QK_RALT) -#define SGUI(kc) (kc | QK_LGUI | QK_LSFT) +#define HYPR(kc) (QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI | (kc)) +#define MEH(kc)  (QK_LCTL | QK_LSFT | QK_LALT | (kc)) +#define LCAG(kc) (QK_LCTL | QK_LALT | QK_LGUI | (kc)) +#define SGUI(kc) (QK_LGUI | QK_LSFT | (kc))  #define SCMD(kc) SGUI(kc)  #define SWIN(kc) SGUI(kc) -#define LCA(kc) (kc | QK_LCTL | QK_LALT) +#define LCA(kc)  (QK_LCTL | QK_LALT | (kc))  #define MOD_HYPR 0xf  #define MOD_MEH 0x7 @@ -557,26 +565,29 @@ enum quantum_keycodes {  #define KC_DELT KC_DELETE // Del key (four letter code)  // Alias for function layers than expand past FN31 -#define FUNC(kc) (kc | QK_FUNCTION) +#define FUNC(kc) (QK_FUNCTION | (kc))  // Aliases  #define S(kc) LSFT(kc)  #define F(kc) FUNC(kc) -#define M(kc) (kc | QK_MACRO) +#define M(kc) (QK_MACRO | (kc)) -#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8) +#define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc))  #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)  #define KC_GESC GRAVE_ESC +#define EEP_RST EEPROM_RESET +  #define CK_TOGG CLICKY_TOGGLE  #define CK_RST CLICKY_RESET  #define CK_UP CLICKY_UP  #define CK_DOWN CLICKY_DOWN +#define CK_ON CLICKY_ENABLE +#define CK_OFF CLICKY_DISABLE  #define RGB_MOD RGB_MODE_FORWARD -#define RGB_SMOD RGB_MODE_FORWARD  #define RGB_RMOD RGB_MODE_REVERSE  #define RGB_M_P RGB_MODE_PLAIN @@ -590,10 +601,11 @@ enum quantum_keycodes {  #define RGB_M_T RGB_MODE_RGBTEST  // L-ayer, T-ap - 256 keycode max, 16 layer max -#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) +#define LT(layer, kc) (QK_LAYER_TAP | ((layer & 0xF) << 8) | ((kc) & 0xFF))  #define AG_SWAP MAGIC_SWAP_ALT_GUI  #define AG_NORM MAGIC_UNSWAP_ALT_GUI +#define AG_TOGG MAGIC_TOGGLE_ALT_GUI  // GOTO layer - 16 layers max  // when: @@ -602,32 +614,32 @@ enum quantum_keycodes {  // Unless you have a good reason not to do so, prefer  ON_PRESS (1) as your default.  // In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own  // keycode modeled after the old version, kept below for this. -/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */ -#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4)) +/* #define TO(layer, when) (QK_TO | (when << 0x4) | (layer & 0xFF)) */ +#define TO(layer) (QK_TO | (ON_PRESS << 0x4) | (layer & 0xFF))  // Momentary switch layer - 256 layer max -#define MO(layer) (layer | QK_MOMENTARY) +#define MO(layer) (QK_MOMENTARY | (layer & 0xFF))  // Set default layer - 256 layer max -#define DF(layer) (layer | QK_DEF_LAYER) +#define DF(layer) (QK_DEF_LAYER | (layer & 0xFF))  // Toggle to layer - 256 layer max -#define TG(layer) (layer | QK_TOGGLE_LAYER) +#define TG(layer) (QK_TOGGLE_LAYER | (layer & 0xFF))  // One-shot layer - 256 layer max -#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) +#define OSL(layer) (QK_ONE_SHOT_LAYER | (layer & 0xFF))  // L-ayer M-od: Momentary switch layer with modifiers active - 16 layer max, left mods only -#define LM(layer, mod) (QK_LAYER_MOD | (((layer) & 0xF) << 4) | ((mod) & 0xF)) +#define LM(layer, mod) (QK_LAYER_MOD | ((layer & 0xF) << 4) | ((mod) & 0xF))  // One-shot mod -#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD) +#define OSM(mod) (QK_ONE_SHOT_MOD | ((mod) & 0xFF))  // Layer tap-toggle -#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE) +#define TT(layer) (QK_LAYER_TAP_TOGGLE | (layer & 0xFF))  // M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8)) +#define MT(mod, kc) (QK_MOD_TAP | (((mod) & 0x1F) << 8) | ((kc) & 0xFF))  #define CTL_T(kc) MT(MOD_LCTL, kc)  #define LCTL_T(kc) MT(MOD_LCTL, kc) @@ -640,7 +652,7 @@ enum quantum_keycodes {  #define ALT_T(kc) MT(MOD_LALT, kc)  #define LALT_T(kc) MT(MOD_LALT, kc)  #define RALT_T(kc) MT(MOD_RALT, kc) -#define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR +#define ALGR_T(kc) RALT_T(kc)  #define GUI_T(kc) MT(MOD_LGUI, kc)  #define CMD_T(kc) GUI_T(kc) @@ -652,15 +664,15 @@ enum quantum_keycodes {  #define RCMD_T(kc) RGUI_T(kc)  #define RWIN_T(kc) RGUI_T(kc) -#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal -#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui -#define RCAG_T(kc) MT((MOD_RCTL | MOD_RALT | MOD_RGUI), kc) // Right control alt and gui -#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ -#define SGUI_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) +#define C_S_T(kc)  MT(MOD_LCTL | MOD_LSFT, kc) // Control + Shift e.g. for gnome-terminal +#define MEH_T(kc)  MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl +#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left control alt and gui +#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right control alt and gui +#define ALL_T(kc)  MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ +#define SGUI_T(kc) MT(MOD_LGUI | MOD_LSFT, kc)  #define SCMD_T(kc) SGUI_T(kc)  #define SWIN_T(kc) SGUI_T(kc) -#define LCA_T(kc) MT((MOD_LCTL | MOD_LALT), kc) // Left control and left alt +#define LCA_T(kc)  MT(MOD_LCTL | MOD_LALT, kc) // Left control and left alt  // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap  #define KC_HYPR HYPR(KC_NO) @@ -670,22 +682,31 @@ enum quantum_keycodes {      // For sending unicode codes.      // You may not send codes over 7FFF -- this supports most of UTF8.      // To have a key that sends out Œ, go UC(0x0152) -    #define UNICODE(n) (n | QK_UNICODE) +    #define UNICODE(n) (QK_UNICODE | (n))      #define UC(n) UNICODE(n)  #endif  #ifdef UNICODEMAP_ENABLE -    #define X(n) (n | QK_UNICODE_MAP) +    #define X(n) (QK_UNICODE_MAP | (n))  #endif +#define UC_MOD  UNICODE_MODE_FORWARD +#define UC_RMOD UNICODE_MODE_REVERSE + +#define UC_M_OS UNICODE_MODE_OSX +#define UC_M_LN UNICODE_MODE_LNX +#define UC_M_WI UNICODE_MODE_WIN +#define UC_M_BS UNICODE_MODE_BSD +#define UC_M_WC UNICODE_MODE_WINC +  #ifdef SWAP_HANDS_ENABLE -  #define SH_T(key)  (QK_SWAP_HANDS | key) -  #define SH_TG      (QK_SWAP_HANDS | OP_SH_TOGGLE) -  #define SH_TT      (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) -  #define SH_MON     (QK_SWAP_HANDS | OP_SH_ON_OFF) -  #define SH_MOFF    (QK_SWAP_HANDS | OP_SH_OFF_ON) -  #define SH_ON      (QK_SWAP_HANDS | OP_SH_ON) -  #define SH_OFF     (QK_SWAP_HANDS | OP_SH_OFF) +  #define SH_T(kc) (QK_SWAP_HANDS | (kc)) +  #define SH_TG    (QK_SWAP_HANDS | OP_SH_TOGGLE) +  #define SH_TT    (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) +  #define SH_MON   (QK_SWAP_HANDS | OP_SH_ON_OFF) +  #define SH_MOFF  (QK_SWAP_HANDS | OP_SH_OFF_ON) +  #define SH_ON    (QK_SWAP_HANDS | OP_SH_ON) +  #define SH_OFF   (QK_SWAP_HANDS | OP_SH_OFF)  #endif  #endif // QUANTUM_KEYCODES_H diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c index b4bbc3dc07..2ed36304dc 100644 --- a/quantum/rgb_matrix.c +++ b/quantum/rgb_matrix.c @@ -1,5 +1,6 @@  /* Copyright 2017 Jason Williams   * Copyright 2017 Jack Humbert + * Copyright 2018 Yiancar   *   * 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 @@ -17,18 +18,22 @@  #include "rgb_matrix.h" -#include <avr/io.h> -#include "i2c_master.h" -#include <util/delay.h> -#include <avr/interrupt.h>  #include "progmem.h"  #include "config.h"  #include "eeprom.h" -#include "lufa.h" +#include <string.h>  #include <math.h>  rgb_config_t rgb_matrix_config; +#ifndef MAX +    #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) +#endif + +#ifndef MIN +    #define MIN(a,b) ((a) < (b)? (a): (b)) +#endif +  #ifndef RGB_DISABLE_AFTER_TIMEOUT      #define RGB_DISABLE_AFTER_TIMEOUT 0  #endif @@ -45,6 +50,15 @@ rgb_config_t rgb_matrix_config;      #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 255  #endif +#ifndef RGB_DIGITAL_RAIN_DROPS +    // lower the number for denser effect/wider keyboard +    #define RGB_DIGITAL_RAIN_DROPS 24 +#endif + +#if !defined(DISABLE_RGB_MATRIX_RAINDROPS) || !defined(DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS) || !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN) +    #define TRACK_PREVIOUS_EFFECT +#endif +  bool g_suspend_state = false;  // Global tick at 20 Hz @@ -69,7 +83,12 @@ void eeconfig_update_rgb_matrix(uint32_t val) {  void eeconfig_update_rgb_matrix_default(void) {    dprintf("eeconfig_update_rgb_matrix_default\n");    rgb_matrix_config.enable = 1; +#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL    rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT; +#else +  // fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace +  rgb_matrix_config.mode = RGB_MATRIX_SOLID_COLOR; +#endif    rgb_matrix_config.hue = 0;    rgb_matrix_config.sat = 255;    rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS; @@ -106,16 +125,15 @@ void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i, uint8_t  }  void rgb_matrix_update_pwm_buffers(void) { -    IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); -    IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +    rgb_matrix_driver.flush();  }  void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { -    IS31FL3731_set_color( index, red, green, blue ); +    rgb_matrix_driver.set_color(index, red, green, blue);  }  void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { -    IS31FL3731_set_color_all( red, green, blue ); +    rgb_matrix_driver.set_color_all(red, green, blue);  }  bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { @@ -178,47 +196,6 @@ void rgb_matrix_test(void) {      }  } -// This tests the LEDs -// Note that it will change the LED control registers -// in the LED drivers, and leave them in an invalid -// state for other backlight effects. -// ONLY USE THIS FOR TESTING LEDS! -void rgb_matrix_single_LED_test(void) { -    static uint8_t color = 0; // 0,1,2 for R,G,B -    static uint8_t row = 0; -    static uint8_t column = 0; - -    static uint8_t tick = 0; -    tick++; - -    if ( tick > 2 ) -    { -        tick = 0; -        column++; -    } -    if ( column > MATRIX_COLS ) -    { -        column = 0; -        row++; -    } -    if ( row > MATRIX_ROWS ) -    { -        row = 0; -        color++; -    } -    if ( color > 2 ) -    { -        color = 0; -    } - -    uint8_t led[8], led_count; -    map_row_column_to_led(row,column,led,&led_count); -    for(uint8_t i = 0; i < led_count; i++) { -        rgb_matrix_set_color_all( 40, 40, 40 ); -        rgb_matrix_test_led( led[i], color==0, color==1, color==2 ); -    } -} -  // All LEDs off  void rgb_matrix_all_off(void) {      rgb_matrix_set_color_all( 0, 0, 0 ); @@ -420,10 +397,12 @@ void rgb_matrix_cycle_up_down(void) {  void rgb_matrix_dual_beacon(void) {      HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };      RGB rgb; -    rgb_led led; +    Point point; +    double cos_value = cos(g_tick * PI / 128) / 32; +    double sin_value =  sin(g_tick * PI / 128) / 112;      for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { -        led = g_rgb_leds[i]; -        hsv.h = ((led.point.y - 32.0)* cos(g_tick * PI / 128) / 32 + (led.point.x - 112.0) * sin(g_tick * PI / 128) / (112)) * (180) + rgb_matrix_config.hue; +        point = g_rgb_leds[i].point; +        hsv.h = ((point.y - 32.0)* cos_value + (point.x - 112.0) * sin_value) * (180) + rgb_matrix_config.hue;          rgb = hsv_to_rgb( hsv );          rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );      } @@ -432,10 +411,12 @@ void rgb_matrix_dual_beacon(void) {  void rgb_matrix_rainbow_beacon(void) {      HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };      RGB rgb; -    rgb_led led; +    Point point; +    double cos_value = cos(g_tick * PI / 128); +    double sin_value =  sin(g_tick * PI / 128);      for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { -        led = g_rgb_leds[i]; -        hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.y - 32.0)* cos(g_tick * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - 112.0) * sin(g_tick * PI / 128) + rgb_matrix_config.hue; +        point = g_rgb_leds[i].point; +        hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.y - 32.0)* cos_value + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.x - 112.0) * sin_value + rgb_matrix_config.hue;          rgb = hsv_to_rgb( hsv );          rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );      } @@ -444,10 +425,12 @@ void rgb_matrix_rainbow_beacon(void) {  void rgb_matrix_rainbow_pinwheels(void) {      HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };      RGB rgb; -    rgb_led led; +    Point point; +    double cos_value = cos(g_tick * PI / 128); +    double sin_value =  sin(g_tick * PI / 128);      for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { -        led = g_rgb_leds[i]; -        hsv.h = (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.y - 32.0)* cos(g_tick * PI / 128) + (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (66 - abs(led.point.x - 112.0)) * sin(g_tick * PI / 128) + rgb_matrix_config.hue; +        point = g_rgb_leds[i].point; +        hsv.h = (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.y - 32.0)* cos_value + (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (66 - abs(point.x - 112.0)) * sin_value + rgb_matrix_config.hue;          rgb = hsv_to_rgb( hsv );          rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );      } @@ -456,12 +439,14 @@ void rgb_matrix_rainbow_pinwheels(void) {  void rgb_matrix_rainbow_moving_chevron(void) {      HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };      RGB rgb; -    rgb_led led; +    Point point; +    uint8_t r = 128; +    double cos_value = cos(r * PI / 128); +    double sin_value =  sin(r * PI / 128); +    double multiplier = (g_tick / 256.0 * 224);      for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { -        led = g_rgb_leds[i]; -        // uint8_t r = g_tick; -        uint8_t r = 32; -        hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(led.point.y - 32.0)* sin(r * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - (g_tick / 256.0 * 224)) * cos(r * PI / 128) + rgb_matrix_config.hue; +        point = g_rgb_leds[i].point; +        hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(point.y - 32.0)* sin_value + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.x - multiplier) * cos_value + rgb_matrix_config.hue;          rgb = hsv_to_rgb( hsv );          rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );      } @@ -492,6 +477,68 @@ void rgb_matrix_jellybean_raindrops( bool initialize ) {      }  } +void rgb_matrix_digital_rain( const bool initialize ) { +    // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain +    const uint8_t drop_ticks           = 28; +    const uint8_t pure_green_intensity = 0xd0; +    const uint8_t max_brightness_boost = 0xc0; +    const uint8_t max_intensity        = 0xff; + +    static uint8_t map[MATRIX_COLS][MATRIX_ROWS] = {{0}}; +    static uint8_t drop = 0; + +    if (initialize) { +        rgb_matrix_set_color_all(0, 0, 0); +        memset(map, 0, sizeof map); +        drop = 0; +    } +    for (uint8_t col = 0; col < MATRIX_COLS; col++) { +        for (uint8_t row = 0; row < MATRIX_ROWS; row++) { +            if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) { +                // top row, pixels have just fallen and we're +                // making a new rain drop in this column +                map[col][row] = max_intensity; +            } +            else if (map[col][row] > 0 && map[col][row] < max_intensity) { +                // neither fully bright nor dark, decay it +                map[col][row]--; +            } +            // set the pixel colour +            uint8_t led, led_count; +            map_row_column_to_led(row, col, &led, &led_count); + +            if (map[col][row] > pure_green_intensity) { +                const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost +                        * (map[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity)); +                rgb_matrix_set_color(led, boost, max_intensity, boost); +            } +            else { +                const uint8_t green = (uint8_t) ((uint16_t) max_intensity * map[col][row] / pure_green_intensity); +                rgb_matrix_set_color(led, 0, green, 0); +            } +        } +    } +    if (++drop > drop_ticks) { +        // reset drop timer +        drop = 0; +        for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) { +            for (uint8_t col = 0; col < MATRIX_COLS; col++) { +                // if ths is on the bottom row and bright allow decay +                if (row == MATRIX_ROWS - 1 && map[col][row] == max_intensity) { +                    map[col][row]--; +                } +                // check if the pixel above is bright +                if (map[col][row - 1] == max_intensity) { +                    // allow old bright pixel to decay +                    map[col][row - 1]--; +                    // make this pixel bright +                    map[col][row] = max_intensity; +                } +            } +        } +    } +} +  void rgb_matrix_multisplash(void) {      // if (g_any_key_hit < 0xFF) {          HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; @@ -580,11 +627,16 @@ void rgb_matrix_custom(void) {  }  void rgb_matrix_task(void) { -    static uint8_t toggle_enable_last = 255; +  #ifdef TRACK_PREVIOUS_EFFECT +      static uint8_t toggle_enable_last = 255; +  #endif  	if (!rgb_matrix_config.enable) { -    	rgb_matrix_all_off(); -        toggle_enable_last = rgb_matrix_config.enable; -    	return; +     rgb_matrix_all_off(); +     rgb_matrix_indicators(); +     #ifdef TRACK_PREVIOUS_EFFECT +         toggle_enable_last = rgb_matrix_config.enable; +     #endif +     return;      }      // delay 1 second before driving LEDs or doing anything else      static uint8_t startup_tick = 0; @@ -619,13 +671,16 @@ void rgb_matrix_task(void) {              (RGB_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20));      uint8_t effect = suspend_backlight ? 0 : rgb_matrix_config.mode; -    // Keep track of the effect used last time, -    // detect change in effect, so each effect can -    // have an optional initialization. -    static uint8_t effect_last = 255; -    bool initialize = (effect != effect_last) || (rgb_matrix_config.enable != toggle_enable_last); -    effect_last = effect; -    toggle_enable_last = rgb_matrix_config.enable; +    #ifdef TRACK_PREVIOUS_EFFECT +        // Keep track of the effect used last time, +        // detect change in effect, so each effect can +        // have an optional initialization. + +        static uint8_t effect_last = 255; +        bool initialize = (effect != effect_last) || (rgb_matrix_config.enable != toggle_enable_last); +        effect_last = effect; +        toggle_enable_last = rgb_matrix_config.enable; +    #endif      // this gets ticked at 20 Hz.      // each effect can opt to do calculations @@ -634,56 +689,93 @@ void rgb_matrix_task(void) {          case RGB_MATRIX_SOLID_COLOR:              rgb_matrix_solid_color();              break; -        case RGB_MATRIX_ALPHAS_MODS: -            rgb_matrix_alphas_mods(); -            break; -        case RGB_MATRIX_DUAL_BEACON: -            rgb_matrix_dual_beacon(); -            break; -        case RGB_MATRIX_GRADIENT_UP_DOWN: -            rgb_matrix_gradient_up_down(); -            break; -        case RGB_MATRIX_RAINDROPS: -            rgb_matrix_raindrops( initialize ); -            break; -        case RGB_MATRIX_CYCLE_ALL: -            rgb_matrix_cycle_all(); -            break; -        case RGB_MATRIX_CYCLE_LEFT_RIGHT: -            rgb_matrix_cycle_left_right(); -            break; -        case RGB_MATRIX_CYCLE_UP_DOWN: -            rgb_matrix_cycle_up_down(); -            break; -        case RGB_MATRIX_RAINBOW_BEACON: -            rgb_matrix_rainbow_beacon(); -            break; -        case RGB_MATRIX_RAINBOW_PINWHEELS: -            rgb_matrix_rainbow_pinwheels(); -            break; -        case RGB_MATRIX_RAINBOW_MOVING_CHEVRON: -            rgb_matrix_rainbow_moving_chevron(); -            break; -        case RGB_MATRIX_JELLYBEAN_RAINDROPS: -            rgb_matrix_jellybean_raindrops( initialize ); -            break; -        #ifdef RGB_MATRIX_KEYPRESSES -            case RGB_MATRIX_SOLID_REACTIVE: -                rgb_matrix_solid_reactive(); +        #ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS +            case RGB_MATRIX_ALPHAS_MODS: +                rgb_matrix_alphas_mods(); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_DUAL_BEACON +            case RGB_MATRIX_DUAL_BEACON: +                rgb_matrix_dual_beacon(); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN +            case RGB_MATRIX_GRADIENT_UP_DOWN: +                rgb_matrix_gradient_up_down(); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_RAINDROPS +            case RGB_MATRIX_RAINDROPS: +                rgb_matrix_raindrops( initialize );                  break; -            case RGB_MATRIX_SPLASH: -                rgb_matrix_splash(); +        #endif +        #ifndef DISABLE_RGB_MATRIX_CYCLE_ALL +            case RGB_MATRIX_CYCLE_ALL: +                rgb_matrix_cycle_all(); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +            case RGB_MATRIX_CYCLE_LEFT_RIGHT: +                rgb_matrix_cycle_left_right(); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN +            case RGB_MATRIX_CYCLE_UP_DOWN: +                rgb_matrix_cycle_up_down();                  break; -            case RGB_MATRIX_MULTISPLASH: -                rgb_matrix_multisplash(); +        #endif +        #ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON +            case RGB_MATRIX_RAINBOW_BEACON: +                rgb_matrix_rainbow_beacon();                  break; -            case RGB_MATRIX_SOLID_SPLASH: -                rgb_matrix_solid_splash(); +        #endif +        #ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS +            case RGB_MATRIX_RAINBOW_PINWHEELS: +                rgb_matrix_rainbow_pinwheels();                  break; -            case RGB_MATRIX_SOLID_MULTISPLASH: -                rgb_matrix_solid_multisplash(); +        #endif +        #ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +            case RGB_MATRIX_RAINBOW_MOVING_CHEVRON: +                rgb_matrix_rainbow_moving_chevron();                  break;          #endif +        #ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +            case RGB_MATRIX_JELLYBEAN_RAINDROPS: +                rgb_matrix_jellybean_raindrops( initialize ); +                break; +        #endif +        #ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN +            case RGB_MATRIX_DIGITAL_RAIN: +                rgb_matrix_digital_rain( initialize ); +                break; +        #endif +        #ifdef RGB_MATRIX_KEYPRESSES +            #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE +                case RGB_MATRIX_SOLID_REACTIVE: +                    rgb_matrix_solid_reactive(); +                    break; +            #endif +            #ifndef DISABLE_RGB_MATRIX_SPLASH +                case RGB_MATRIX_SPLASH: +                    rgb_matrix_splash(); +                    break; +            #endif +            #ifndef DISABLE_RGB_MATRIX_MULTISPLASH +                case RGB_MATRIX_MULTISPLASH: +                    rgb_matrix_multisplash(); +                    break; +            #endif +            #ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH +                case RGB_MATRIX_SOLID_SPLASH: +                    rgb_matrix_solid_splash(); +                    break; +            #endif +            #ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH +                case RGB_MATRIX_SOLID_MULTISPLASH: +                    rgb_matrix_solid_multisplash(); +                    break; +            #endif +        #endif          default:              rgb_matrix_custom();              break; @@ -725,7 +817,7 @@ void rgb_matrix_indicators_user(void) {}  // }  void rgb_matrix_init(void) { -  rgb_matrix_setup_drivers(); +  rgb_matrix_driver.init();    // TODO: put the 1 second startup delay here? @@ -749,29 +841,14 @@ void rgb_matrix_init(void) {    eeconfig_debug_rgb_matrix(); // display current eeprom values  } -void rgb_matrix_setup_drivers(void) { -  // Initialize TWI -  i2c_init(); -  IS31FL3731_init( DRIVER_ADDR_1 ); -  IS31FL3731_init( DRIVER_ADDR_2 ); - -  for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) { -    bool enabled = true; -    // This only caches it for later -    IS31FL3731_set_led_control_register( index, enabled, enabled, enabled ); -  } -  // This actually updates the LED drivers -  IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); -} -  // Deals with the messy details of incrementing an integer -uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { +static uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {      int16_t new_value = value;      new_value += step;      return MIN( MAX( new_value, min ), max );  } -uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { +static uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {      int16_t new_value = value;      new_value -= step;      return MIN( MAX( new_value, min ), max ); @@ -806,88 +883,109 @@ uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {  //     }  // } -void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ) { -    for ( int i=0; i<DRIVER_LED_TOTAL; i++ ) -    { -        if ( i == index ) -        { -            IS31FL3731_set_led_control_register( i, red, green, blue ); -        } -        else -        { -            IS31FL3731_set_led_control_register( i, false, false, false ); -        } -    } -} -  uint32_t rgb_matrix_get_tick(void) {      return g_tick;  } -void rgblight_toggle(void) { +void rgb_matrix_toggle(void) {  	rgb_matrix_config.enable ^= 1;      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_step(void) { +void rgb_matrix_enable(void) { +	rgb_matrix_config.enable = 1; +    eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgb_matrix_enable_noeeprom(void) { +	rgb_matrix_config.enable = 1; +} + +void rgb_matrix_disable(void) { +	rgb_matrix_config.enable = 0; +    eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgb_matrix_disable_noeeprom(void) { +	rgb_matrix_config.enable = 0; +} + +void rgb_matrix_step(void) {      rgb_matrix_config.mode++;      if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX)          rgb_matrix_config.mode = 1;      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_step_reverse(void) { +void rgb_matrix_step_reverse(void) {      rgb_matrix_config.mode--;      if (rgb_matrix_config.mode < 1)          rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1;      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_increase_hue(void) { +void rgb_matrix_increase_hue(void) {      rgb_matrix_config.hue = increment( rgb_matrix_config.hue, 8, 0, 255 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_decrease_hue(void) { +void rgb_matrix_decrease_hue(void) {      rgb_matrix_config.hue = decrement( rgb_matrix_config.hue, 8, 0, 255 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_increase_sat(void) { +void rgb_matrix_increase_sat(void) {      rgb_matrix_config.sat = increment( rgb_matrix_config.sat, 8, 0, 255 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_decrease_sat(void) { +void rgb_matrix_decrease_sat(void) {      rgb_matrix_config.sat = decrement( rgb_matrix_config.sat, 8, 0, 255 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_increase_val(void) { +void rgb_matrix_increase_val(void) {      rgb_matrix_config.val = increment( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_decrease_val(void) { +void rgb_matrix_decrease_val(void) {      rgb_matrix_config.val = decrement( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -void rgblight_increase_speed(void) { +void rgb_matrix_increase_speed(void) {      rgb_matrix_config.speed = increment( rgb_matrix_config.speed, 1, 0, 3 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this  } -void rgblight_decrease_speed(void) { +void rgb_matrix_decrease_speed(void) {      rgb_matrix_config.speed = decrement( rgb_matrix_config.speed, 1, 0, 3 );      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this  } -void rgblight_mode(uint8_t mode) { +void rgb_matrix_mode(uint8_t mode) {      rgb_matrix_config.mode = mode;      eeconfig_update_rgb_matrix(rgb_matrix_config.raw);  } -uint32_t rgblight_get_mode(void) { +void rgb_matrix_mode_noeeprom(uint8_t mode) { +    rgb_matrix_config.mode = mode; +} + +uint8_t rgb_matrix_get_mode(void) {      return rgb_matrix_config.mode;  } + +void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { +  rgb_matrix_config.hue = hue; +  rgb_matrix_config.sat = sat; +  rgb_matrix_config.val = val; +  eeconfig_update_rgb_matrix(rgb_matrix_config.raw); +} + +void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { +  rgb_matrix_config.hue = hue; +  rgb_matrix_config.sat = sat; +  rgb_matrix_config.val = val; +} diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h index 5769314002..e43532d11e 100644 --- a/quantum/rgb_matrix.h +++ b/quantum/rgb_matrix.h @@ -1,5 +1,6 @@  /* Copyright 2017 Jason Williams   * Copyright 2017 Jack Humbert + * Copyright 2018 Yiancar   *   * 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 @@ -21,9 +22,14 @@  #include <stdint.h>  #include <stdbool.h>  #include "color.h" -#include "is31fl3731.h"  #include "quantum.h" +#ifdef IS31FL3731 +    #include "is31fl3731.h" +#elif defined (IS31FL3733) +    #include "is31fl3733.h" +#endif +  typedef struct Point {  	uint8_t x;  	uint8_t y; @@ -64,28 +70,64 @@ typedef union {  enum rgb_matrix_effects {  	RGB_MATRIX_SOLID_COLOR = 1, +#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS      RGB_MATRIX_ALPHAS_MODS, +#endif +#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON      RGB_MATRIX_DUAL_BEACON, +#endif +#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN      RGB_MATRIX_GRADIENT_UP_DOWN, +#endif +#ifndef DISABLE_RGB_MATRIX_RAINDROPS      RGB_MATRIX_RAINDROPS, +#endif +#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL      RGB_MATRIX_CYCLE_ALL, +#endif +#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT      RGB_MATRIX_CYCLE_LEFT_RIGHT, +#endif +#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN      RGB_MATRIX_CYCLE_UP_DOWN, +#endif +#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON      RGB_MATRIX_RAINBOW_BEACON, +#endif +#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS      RGB_MATRIX_RAINBOW_PINWHEELS, +#endif +#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON      RGB_MATRIX_RAINBOW_MOVING_CHEVRON, +#endif +#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS      RGB_MATRIX_JELLYBEAN_RAINDROPS, +#endif +#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN +    RGB_MATRIX_DIGITAL_RAIN, +#endif  #ifdef RGB_MATRIX_KEYPRESSES -    RGB_MATRIX_SOLID_REACTIVE, -    RGB_MATRIX_SPLASH, -    RGB_MATRIX_MULTISPLASH, -    RGB_MATRIX_SOLID_SPLASH, -    RGB_MATRIX_SOLID_MULTISPLASH, +   #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE +       RGB_MATRIX_SOLID_REACTIVE, +   #endif +   #ifndef DISABLE_RGB_MATRIX_SPLASH +       RGB_MATRIX_SPLASH, +   #endif +   #ifndef DISABLE_RGB_MATRIX_MULTISPLASH +       RGB_MATRIX_MULTISPLASH, +   #endif +   #ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH +       RGB_MATRIX_SOLID_SPLASH, +   #endif +   #ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH +       RGB_MATRIX_SOLID_MULTISPLASH, +   #endif  #endif      RGB_MATRIX_EFFECT_MAX  };  void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); +void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue );  // This runs after another backlight effect and replaces  // colors already set @@ -93,8 +135,6 @@ void rgb_matrix_indicators(void);  void rgb_matrix_indicators_kb(void);  void rgb_matrix_indicators_user(void); -void rgb_matrix_single_LED_test(void); -  void rgb_matrix_init(void);  void rgb_matrix_setup_drivers(void); @@ -119,21 +159,65 @@ void rgb_matrix_decrease(void);  // void backlight_get_key_color( uint8_t led, HSV *hsv );  // void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv ); -void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue );  uint32_t rgb_matrix_get_tick(void); -void rgblight_toggle(void); -void rgblight_step(void); -void rgblight_step_reverse(void); -void rgblight_increase_hue(void); -void rgblight_decrease_hue(void); -void rgblight_increase_sat(void); -void rgblight_decrease_sat(void); -void rgblight_increase_val(void); -void rgblight_decrease_val(void); -void rgblight_increase_speed(void); -void rgblight_decrease_speed(void); -void rgblight_mode(uint8_t mode); -uint32_t rgblight_get_mode(void); +void rgb_matrix_toggle(void); +void rgb_matrix_enable(void); +void rgb_matrix_enable_noeeprom(void); +void rgb_matrix_disable(void); +void rgb_matrix_disable_noeeprom(void); +void rgb_matrix_step(void); +void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val); +void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); +void rgb_matrix_step_reverse(void); +void rgb_matrix_increase_hue(void); +void rgb_matrix_decrease_hue(void); +void rgb_matrix_increase_sat(void); +void rgb_matrix_decrease_sat(void); +void rgb_matrix_increase_val(void); +void rgb_matrix_decrease_val(void); +void rgb_matrix_increase_speed(void); +void rgb_matrix_decrease_speed(void); +void rgb_matrix_mode(uint8_t mode); +void rgb_matrix_mode_noeeprom(uint8_t mode); +uint8_t rgb_matrix_get_mode(void); + +#ifndef RGBLIGHT_ENABLE +#define rgblight_toggle() rgb_matrix_toggle() +#define rgblight_enable() rgb_matrix_enable() +#define rgblight_enable_noeeprom() rgb_matrix_enable_noeeprom() +#define rgblight_disable() rgb_matrix_disable() +#define rgblight_disable_noeeprom() rgb_matrix_disable_noeeprom() +#define rgblight_step() rgb_matrix_step() +#define rgblight_sethsv(hue, sat, val) rgb_matrix_sethsv(hue, sat, val) +#define rgblight_sethsv_noeeprom(hue, sat, val) rgb_matrix_sethsv_noeeprom(hue, sat, val) +#define rgblight_step_reverse() rgb_matrix_step_reverse() +#define rgblight_increase_hue() rgb_matrix_increase_hue() +#define rgblight_decrease_hue() rgb_matrix_decrease_hue() +#define rgblight_increase_sat() rgb_matrix_increase_sat() +#define rgblight_decrease_sat() rgb_matrix_decrease_sat() +#define rgblight_increase_val() rgb_matrix_increase_val() +#define rgblight_decrease_val() rgb_matrix_decrease_val() +#define rgblight_increase_speed() rgb_matrix_increase_speed() +#define rgblight_decrease_speed() rgb_matrix_decrease_speed() +#define rgblight_mode(mode) rgb_matrix_mode(mode) +#define rgblight_mode_noeeprom(mode) rgb_matrix_mode_noeeprom(mode) +#define rgblight_get_mode() rgb_matrix_get_mode() + +#endif + +typedef struct { +    /* Perform any initialisation required for the other driver functions to work. */ +    void (*init)(void); + +    /* Set the colour of a single LED in the buffer. */ +    void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b); +    /* Set the colour of all LEDS on the keyboard in the buffer. */ +    void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b); +    /* Flush any buffered changes to the hardware. */ +    void (*flush)(void); +} rgb_matrix_driver_t; + +extern const rgb_matrix_driver_t rgb_matrix_driver;  #endif diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c new file mode 100644 index 0000000000..70b80293dd --- /dev/null +++ b/quantum/rgb_matrix_drivers.c @@ -0,0 +1,82 @@ +/* Copyright 2018 James Laird-Wah + * + * 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 "rgb_matrix.h" + +/* Each driver needs to define the struct + *    const rgb_matrix_driver_t rgb_matrix_driver; + * All members must be provided. + * Keyboard custom drivers can define this in their own files, it should only + * be here if shared between boards. + */ + +#if defined(IS31FL3731) || defined(IS31FL3733) + +#include "i2c_master.h" + +static void init( void ) +{ +    i2c_init(); +#ifdef IS31FL3731 +    IS31FL3731_init( DRIVER_ADDR_1 ); +    IS31FL3731_init( DRIVER_ADDR_2 ); +#else +    IS31FL3733_init( DRIVER_ADDR_1 ); +#endif +    for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) { +        bool enabled = true; +        // This only caches it for later +#ifdef IS31FL3731 +        IS31FL3731_set_led_control_register( index, enabled, enabled, enabled ); +#else +        IS31FL3733_set_led_control_register( index, enabled, enabled, enabled ); +#endif +    } +    // This actually updates the LED drivers +#ifdef IS31FL3731 +    IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +#else +    IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +#endif +} + +#ifdef IS31FL3731 +static void flush( void ) +{ +    IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +} + +const rgb_matrix_driver_t rgb_matrix_driver = { +    .init = init, +    .flush = flush, +    .set_color = IS31FL3731_set_color, +    .set_color_all = IS31FL3731_set_color_all, +}; +#else +static void flush( void ) +{ +    IS31FL3733_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +} + +const rgb_matrix_driver_t rgb_matrix_driver = { +    .init = init, +    .flush = flush, +    .set_color = IS31FL3733_set_color, +    .set_color_all = IS31FL3733_set_color_all, +}; +#endif + +#endif diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 4919ae4abf..23420ddd87 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -14,6 +14,7 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <math.h> +#include <string.h>  #ifdef __AVR__    #include <avr/eeprom.h>    #include <avr/interrupt.h> @@ -29,23 +30,27 @@  #define RGBLIGHT_LIMIT_VAL 255  #endif +#define _RGBM_SINGLE_STATIC(sym)   RGBLIGHT_MODE_ ## sym, +#define _RGBM_SINGLE_DYNAMIC(sym) +#define _RGBM_MULTI_STATIC(sym)    RGBLIGHT_MODE_ ## sym, +#define _RGBM_MULTI_DYNAMIC(sym) +#define _RGBM_TMP_STATIC(sym)      RGBLIGHT_MODE_ ## sym, +#define _RGBM_TMP_DYNAMIC(sym) +static uint8_t static_effect_table [] = { +#include "rgblight.h" +}; + +static inline int is_static_effect(uint8_t mode) { +    return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL; +} +  #define MIN(a,b) (((a)<(b))?(a):(b))  #define MAX(a,b) (((a)>(b))?(a):(b)) -__attribute__ ((weak)) -const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; -__attribute__ ((weak)) -const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; -__attribute__ ((weak)) -const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; -__attribute__ ((weak)) -const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; -__attribute__ ((weak)) -const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; +#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT  __attribute__ ((weak))  const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90}; -__attribute__ ((weak)) -const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024}; +#endif  rgblight_config_t rgblight_config; @@ -129,7 +134,7 @@ void eeconfig_update_rgblight(uint32_t val) {  void eeconfig_update_rgblight_default(void) {    //dprintf("eeconfig_update_rgblight_default\n");    rgblight_config.enable = 1; -  rgblight_config.mode = 1; +  rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;    rgblight_config.hue = 0;    rgblight_config.sat = 255;    rgblight_config.val = RGBLIGHT_LIMIT_VAL; @@ -163,9 +168,9 @@ void rgblight_init(void) {    }    eeconfig_debug_rgblight(); // display current eeprom values -  #ifdef RGBLIGHT_ANIMATIONS +#ifdef RGBLIGHT_USE_TIMER      rgblight_timer_init(); // setup the timer -  #endif +#endif    if (rgblight_config.enable) {      rgblight_mode_noeeprom(rgblight_config.mode); @@ -178,9 +183,9 @@ void rgblight_update_dword(uint32_t dword) {    if (rgblight_config.enable)      rgblight_mode(rgblight_config.mode);    else { -    #ifdef RGBLIGHT_ANIMATIONS +#ifdef RGBLIGHT_USE_TIMER        rgblight_timer_disable(); -    #endif +#endif        rgblight_set();    }  } @@ -195,29 +200,41 @@ void rgblight_increase(void) {  void rgblight_decrease(void) {    uint8_t mode = 0;    // Mode will never be < 1. If it ever is, eeprom needs to be initialized. -  if (rgblight_config.mode > 1) { +  if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) {      mode = rgblight_config.mode - 1;    }    rgblight_mode(mode);  } -void rgblight_step(void) { +void rgblight_step_helper(bool write_to_eeprom) {    uint8_t mode = 0;    mode = rgblight_config.mode + 1;    if (mode > RGBLIGHT_MODES) {      mode = 1;    } -  rgblight_mode(mode); +  rgblight_mode_eeprom_helper(mode, write_to_eeprom);  } -void rgblight_step_reverse(void) { +void rgblight_step_noeeprom(void) { +  rgblight_step_helper(false); +} +void rgblight_step(void) { +  rgblight_step_helper(true); +} +void rgblight_step_reverse_helper(bool write_to_eeprom) {    uint8_t mode = 0;    mode = rgblight_config.mode - 1;    if (mode < 1) {      mode = RGBLIGHT_MODES;    } -  rgblight_mode(mode); +  rgblight_mode_eeprom_helper(mode, write_to_eeprom); +} +void rgblight_step_reverse_noeeprom(void) { +  rgblight_step_reverse_helper(false); +} +void rgblight_step_reverse(void) { +  rgblight_step_reverse_helper(true);  } -uint32_t rgblight_get_mode(void) { +uint8_t rgblight_get_mode(void) {    if (!rgblight_config.enable) {      return false;    } @@ -229,8 +246,8 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {    if (!rgblight_config.enable) {      return;    } -  if (mode < 1) { -    rgblight_config.mode = 1; +  if (mode < RGBLIGHT_MODE_STATIC_LIGHT) { +    rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;    } else if (mode > RGBLIGHT_MODES) {      rgblight_config.mode = RGBLIGHT_MODES;    } else { @@ -242,30 +259,14 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {    } else {      xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);    } -  if (rgblight_config.mode == 1) { -    #ifdef RGBLIGHT_ANIMATIONS +  if( is_static_effect(rgblight_config.mode) ) { +#ifdef RGBLIGHT_USE_TIMER        rgblight_timer_disable(); -    #endif -  } else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) || -	     rgblight_config.mode == 35 || rgblight_config.mode == 36) { -    // MODE 2-5, breathing -    // MODE 6-8, rainbow mood -    // MODE 9-14, rainbow swirl -    // MODE 15-20, snake -    // MODE 21-23, knight -    // MODE 24, xmas -    // MODE 35  RGB test -    // MODE 36, alterating - -    #ifdef RGBLIGHT_ANIMATIONS +#endif +  } else { +#ifdef RGBLIGHT_USE_TIMER        rgblight_timer_enable(); -    #endif -  } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { -    // MODE 25-34, static gradient - -    #ifdef RGBLIGHT_ANIMATIONS -      rgblight_timer_disable(); -    #endif +#endif    }    rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);  } @@ -317,9 +318,9 @@ void rgblight_disable(void) {    rgblight_config.enable = 0;    eeconfig_update_rgblight(rgblight_config.raw);    xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); -  #ifdef RGBLIGHT_ANIMATIONS -    rgblight_timer_disable(); -  #endif +#ifdef RGBLIGHT_USE_TIMER +      rgblight_timer_disable(); +#endif    wait_ms(50);    rgblight_set();  } @@ -327,76 +328,112 @@ void rgblight_disable(void) {  void rgblight_disable_noeeprom(void) {    rgblight_config.enable = 0;    xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); -  #ifdef RGBLIGHT_ANIMATIONS +#ifdef RGBLIGHT_USE_TIMER      rgblight_timer_disable(); -  #endif +#endif    _delay_ms(50);    rgblight_set();  }  // Deals with the messy details of incrementing an integer -uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { +static uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {      int16_t new_value = value;      new_value += step;      return MIN( MAX( new_value, min ), max );  } -uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { +static uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {      int16_t new_value = value;      new_value -= step;      return MIN( MAX( new_value, min ), max );  } -void rgblight_increase_hue(void) { +void rgblight_increase_hue_helper(bool write_to_eeprom) {    uint16_t hue;    hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360; -  rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); +  rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);  } -void rgblight_decrease_hue(void) { +void rgblight_increase_hue_noeeprom(void) { +  rgblight_increase_hue_helper(false); +} +void rgblight_increase_hue(void) { +  rgblight_increase_hue_helper(true); +} +void rgblight_decrease_hue_helper(bool write_to_eeprom) {    uint16_t hue;    if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) {      hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360;    } else {      hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360;    } -  rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); +  rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);  } -void rgblight_increase_sat(void) { +void rgblight_decrease_hue_noeeprom(void) { +  rgblight_decrease_hue_helper(false); +} +void rgblight_decrease_hue(void) { +  rgblight_decrease_hue_helper(true); +} +void rgblight_increase_sat_helper(bool write_to_eeprom) {    uint8_t sat;    if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) {      sat = 255;    } else {      sat = rgblight_config.sat + RGBLIGHT_SAT_STEP;    } -  rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); +  rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);  } -void rgblight_decrease_sat(void) { +void rgblight_increase_sat_noeeprom(void) { +  rgblight_increase_sat_helper(false); +} +void rgblight_increase_sat(void) { +  rgblight_increase_sat_helper(true); +} +void rgblight_decrease_sat_helper(bool write_to_eeprom) {    uint8_t sat;    if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) {      sat = 0;    } else {      sat = rgblight_config.sat - RGBLIGHT_SAT_STEP;    } -  rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); +  rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);  } -void rgblight_increase_val(void) { +void rgblight_decrease_sat_noeeprom(void) { +  rgblight_decrease_sat_helper(false); +} +void rgblight_decrease_sat(void) { +  rgblight_decrease_sat_helper(true); +} +void rgblight_increase_val_helper(bool write_to_eeprom) {    uint8_t val;    if (rgblight_config.val + RGBLIGHT_VAL_STEP > RGBLIGHT_LIMIT_VAL) {      val = RGBLIGHT_LIMIT_VAL;    } else {      val = rgblight_config.val + RGBLIGHT_VAL_STEP;    } -  rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); +  rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);  } -void rgblight_decrease_val(void) { +void rgblight_increase_val_noeeprom(void) { +  rgblight_increase_val_helper(false); +} +void rgblight_increase_val(void) { +  rgblight_increase_val_helper(true); +} +void rgblight_decrease_val_helper(bool write_to_eeprom) {    uint8_t val;    if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) {      val = 0;    } else {      val = rgblight_config.val - RGBLIGHT_VAL_STEP;    } -  rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); +  rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom); +} +void rgblight_decrease_val_noeeprom(void) { +  rgblight_decrease_val_helper(false); +} +void rgblight_decrease_val(void) { +  rgblight_decrease_val_helper(true);  }  void rgblight_increase_speed(void) {      rgblight_config.speed = increment( rgblight_config.speed, 1, 0, 3 ); @@ -419,24 +456,43 @@ void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {  void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {    if (rgblight_config.enable) { -    if (rgblight_config.mode == 1) { +    if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {        // same static color        LED_TYPE tmp_led;        sethsv(hue, sat, val, &tmp_led);        rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);      } else {        // all LEDs in same color -      if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { +      if ( 1 == 0 ) { //dummy +      } +#ifdef RGBLIGHT_EFFECT_BREATHING +      else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING && +          rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {          // breathing mode, ignore the change of val, use in memory value instead          val = rgblight_config.val; -      } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { -        // rainbow mood and rainbow swirl, ignore the change of hue +      } +#endif +#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD +      else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD && +                  rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) { +        // rainbow mood, ignore the change of hue          hue = rgblight_config.hue; -      } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { +      } +#endif +#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL +      else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL && +               rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) { +        // rainbow swirl, ignore the change of hue +        hue = rgblight_config.hue; +      } +#endif +#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT +      else if (rgblight_config.mode >= RGBLIGHT_MODE_STATIC_GRADIENT && +               rgblight_config.mode <= RGBLIGHT_MODE_STATIC_GRADIENT_end) {          // static gradient          uint16_t _hue; -        int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1; -        uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]); +        int8_t direction = ((rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) % 2) ? -1 : 1; +        uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) / 2]);          for (uint8_t i = 0; i < RGBLED_NUM; i++) {            _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;            dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range); @@ -444,6 +500,7 @@ void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool          }          rgblight_set();        } +#endif      }      rgblight_config.hue = hue;      rgblight_config.sat = sat; @@ -528,7 +585,7 @@ void rgblight_set(void) {  }  #endif -#ifdef RGBLIGHT_ANIMATIONS +#ifdef RGBLIGHT_USE_TIMER  // Animation timer -- AVR Timer3  void rgblight_timer_init(void) { @@ -564,41 +621,77 @@ void rgblight_timer_toggle(void) {  void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {    rgblight_enable(); -  rgblight_mode(1); +  rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);    rgblight_setrgb(r, g, b);  }  void rgblight_task(void) {    if (rgblight_timer_enabled) { -    // mode = 1, static light, do nothing here -    if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { -      // mode = 2 to 5, breathing mode -      rgblight_effect_breathing(rgblight_config.mode - 2); -    } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { -      // mode = 6 to 8, rainbow mood mod -      rgblight_effect_rainbow_mood(rgblight_config.mode - 6); -    } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { -      // mode = 9 to 14, rainbow swirl mode -      rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); -    } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { -      // mode = 15 to 20, snake mode -      rgblight_effect_snake(rgblight_config.mode - 15); -    } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { -      // mode = 21 to 23, knight mode -      rgblight_effect_knight(rgblight_config.mode - 21); -    } else if (rgblight_config.mode == 24) { -      // mode = 24, christmas mode +    // static light mode, do nothing here +    if ( 1 == 0 ) { //dummy +    } +#ifdef RGBLIGHT_EFFECT_BREATHING +    else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING  && +        rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) { +      // breathing mode +      rgblight_effect_breathing(rgblight_config.mode - RGBLIGHT_MODE_BREATHING ); +    } +#endif +#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD +    else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD && +               rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) { +      // rainbow mood mode +      rgblight_effect_rainbow_mood(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_MOOD); +    } +#endif +#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL +    else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL && +               rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) { +      // rainbow swirl mode +      rgblight_effect_rainbow_swirl(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_SWIRL); +    } +#endif +#ifdef RGBLIGHT_EFFECT_SNAKE +    else if (rgblight_config.mode >= RGBLIGHT_MODE_SNAKE && +               rgblight_config.mode <= RGBLIGHT_MODE_SNAKE_end) { +      // snake mode +      rgblight_effect_snake(rgblight_config.mode - RGBLIGHT_MODE_SNAKE); +    } +#endif +#ifdef RGBLIGHT_EFFECT_KNIGHT +    else if (rgblight_config.mode >= RGBLIGHT_MODE_KNIGHT && +               rgblight_config.mode <= RGBLIGHT_MODE_KNIGHT_end) { +      // knight mode +      rgblight_effect_knight(rgblight_config.mode - RGBLIGHT_MODE_KNIGHT); +    } +#endif +#ifdef RGBLIGHT_EFFECT_CHRISTMAS +    else if (rgblight_config.mode == RGBLIGHT_MODE_CHRISTMAS) { +      // christmas mode        rgblight_effect_christmas(); -    } else if (rgblight_config.mode == 35) { -      // mode = 35, RGB test +    } +#endif +#ifdef RGBLIGHT_EFFECT_RGB_TEST +    else if (rgblight_config.mode == RGBLIGHT_MODE_RGB_TEST) { +      // RGB test mode        rgblight_effect_rgbtest(); -    } else if (rgblight_config.mode == 36){ +    } +#endif +#ifdef RGBLIGHT_EFFECT_ALTERNATING +    else if (rgblight_config.mode == RGBLIGHT_MODE_ALTERNATING){        rgblight_effect_alternating();      } +#endif    }  } +#endif /* RGBLIGHT_USE_TIMER */ +  // Effects +#ifdef RGBLIGHT_EFFECT_BREATHING +__attribute__ ((weak)) +const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; +  void rgblight_effect_breathing(uint8_t interval) {    static uint8_t pos = 0;    static uint16_t last_timer = 0; @@ -609,12 +702,17 @@ void rgblight_effect_breathing(uint8_t interval) {    }    last_timer = timer_read(); -    // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/    val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));    rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);    pos = (pos + 1) % 256;  } +#endif + +#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD +__attribute__ ((weak)) +const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; +  void rgblight_effect_rainbow_mood(uint8_t interval) {    static uint16_t current_hue = 0;    static uint16_t last_timer = 0; @@ -626,6 +724,16 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {    rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val);    current_hue = (current_hue + 1) % 360;  } +#endif + +#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL +#ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE +  #define RGBLIGHT_RAINBOW_SWIRL_RANGE 360 +#endif + +__attribute__ ((weak)) +const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; +  void rgblight_effect_rainbow_swirl(uint8_t interval) {    static uint16_t current_hue = 0;    static uint16_t last_timer = 0; @@ -636,7 +744,7 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {    }    last_timer = timer_read();    for (i = 0; i < RGBLED_NUM; i++) { -    hue = (360 / RGBLED_NUM * i + current_hue) % 360; +    hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + current_hue) % 360;      sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);    }    rgblight_set(); @@ -651,6 +759,12 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {      }    }  } +#endif + +#ifdef RGBLIGHT_EFFECT_SNAKE +__attribute__ ((weak)) +const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; +  void rgblight_effect_snake(uint8_t interval) {    static uint8_t pos = 0;    static uint16_t last_timer = 0; @@ -689,6 +803,12 @@ void rgblight_effect_snake(uint8_t interval) {      pos = (pos + 1) % RGBLED_NUM;    }  } +#endif + +#ifdef RGBLIGHT_EFFECT_KNIGHT +__attribute__ ((weak)) +const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; +  void rgblight_effect_knight(uint8_t interval) {    static uint16_t last_timer = 0;    if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { @@ -730,8 +850,9 @@ void rgblight_effect_knight(uint8_t interval) {      increment = -increment;    }  } +#endif - +#ifdef RGBLIGHT_EFFECT_CHRISTMAS  void rgblight_effect_christmas(void) {    static uint16_t current_offset = 0;    static uint16_t last_timer = 0; @@ -748,6 +869,11 @@ void rgblight_effect_christmas(void) {    }    rgblight_set();  } +#endif + +#ifdef RGBLIGHT_EFFECT_RGB_TEST +__attribute__ ((weak)) +const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};  void rgblight_effect_rgbtest(void) {    static uint8_t pos = 0; @@ -774,7 +900,9 @@ void rgblight_effect_rgbtest(void) {    rgblight_setrgb(r, g, b);    pos = (pos + 1) % 3;  } +#endif +#ifdef RGBLIGHT_EFFECT_ALTERNATING  void rgblight_effect_alternating(void){    static uint16_t last_timer = 0;    static uint16_t pos = 0; @@ -784,16 +912,15 @@ void rgblight_effect_alternating(void){    last_timer = timer_read();    for(int i = 0; i<RGBLED_NUM; i++){ -		  if(i<RGBLED_NUM/2 && pos){ -			  rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i); -		  }else if (i>=RGBLED_NUM/2 && !pos){ -			  rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i); -		  }else{ -			  rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, 0, i); -		  } +      if(i<RGBLED_NUM/2 && pos){ +          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); +      }else if (i>=RGBLED_NUM/2 && !pos){ +          sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); +      }else{ +          sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]); +      }    }    rgblight_set();    pos = (pos + 1) % 2;  } - -#endif /* RGBLIGHT_ANIMATIONS */ +#endif diff --git a/quantum/rgblight.h b/quantum/rgblight.h index ba010dfae3..65dda3f521 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -16,11 +16,69 @@  #ifndef RGBLIGHT_H  #define RGBLIGHT_H -#ifdef RGBLIGHT_ANIMATIONS -	#define RGBLIGHT_MODES 36 -#else -	#define RGBLIGHT_MODES 1 -#endif +#include "rgblight_reconfig.h" + +/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) **** + + old mode number (before 0.6.117) to new mode name table + +|-----------------|-----------------------------------| +| old mode number | new mode name                     | +|-----------------|-----------------------------------| +|        1        | RGBLIGHT_MODE_STATIC_LIGHT        | +|        2        | RGBLIGHT_MODE_BREATHING           | +|        3        | RGBLIGHT_MODE_BREATHING + 1       | +|        4        | RGBLIGHT_MODE_BREATHING + 2       | +|        5        | RGBLIGHT_MODE_BREATHING + 3       | +|        6        | RGBLIGHT_MODE_RAINBOW_MOOD        | +|        7        | RGBLIGHT_MODE_RAINBOW_MOOD + 1    | +|        8        | RGBLIGHT_MODE_RAINBOW_MOOD + 2    | +|        9        | RGBLIGHT_MODE_RAINBOW_SWIRL       | +|       10        | RGBLIGHT_MODE_RAINBOW_SWIRL + 1   | +|       11        | RGBLIGHT_MODE_RAINBOW_SWIRL + 2   | +|       12        | RGBLIGHT_MODE_RAINBOW_SWIRL + 3   | +|       13        | RGBLIGHT_MODE_RAINBOW_SWIRL + 4   | +|       14        | RGBLIGHT_MODE_RAINBOW_SWIRL + 5   | +|       15        | RGBLIGHT_MODE_SNAKE               | +|       16        | RGBLIGHT_MODE_SNAKE + 1           | +|       17        | RGBLIGHT_MODE_SNAKE + 2           | +|       18        | RGBLIGHT_MODE_SNAKE + 3           | +|       19        | RGBLIGHT_MODE_SNAKE + 4           | +|       20        | RGBLIGHT_MODE_SNAKE + 5           | +|       21        | RGBLIGHT_MODE_KNIGHT              | +|       22        | RGBLIGHT_MODE_KNIGHT + 1          | +|       23        | RGBLIGHT_MODE_KNIGHT + 2          | +|       24        | RGBLIGHT_MODE_CHRISTMAS           | +|       25        | RGBLIGHT_MODE_STATIC_GRADIENT     | +|       26        | RGBLIGHT_MODE_STATIC_GRADIENT + 1 | +|       27        | RGBLIGHT_MODE_STATIC_GRADIENT + 2 | +|       28        | RGBLIGHT_MODE_STATIC_GRADIENT + 3 | +|       29        | RGBLIGHT_MODE_STATIC_GRADIENT + 4 | +|       30        | RGBLIGHT_MODE_STATIC_GRADIENT + 5 | +|       31        | RGBLIGHT_MODE_STATIC_GRADIENT + 6 | +|       32        | RGBLIGHT_MODE_STATIC_GRADIENT + 7 | +|       33        | RGBLIGHT_MODE_STATIC_GRADIENT + 8 | +|       34        | RGBLIGHT_MODE_STATIC_GRADIENT + 9 | +|       35        | RGBLIGHT_MODE_RGB_TEST            | +|       36        | RGBLIGHT_MODE_ALTERNATING         | +|-----------------|-----------------------------------| + *****/ + +#define _RGBM_SINGLE_STATIC(sym)   RGBLIGHT_MODE_ ## sym, +#define _RGBM_SINGLE_DYNAMIC(sym)  RGBLIGHT_MODE_ ## sym, +#define _RGBM_MULTI_STATIC(sym)    RGBLIGHT_MODE_ ## sym, +#define _RGBM_MULTI_DYNAMIC(sym)   RGBLIGHT_MODE_ ## sym, +#define _RGBM_TMP_STATIC(sym)      RGBLIGHT_MODE_ ## sym, +#define _RGBM_TMP_DYNAMIC(sym)     RGBLIGHT_MODE_ ## sym, +enum RGBLIGHT_EFFECT_MODE { +    RGBLIGHT_MODE_zero = 0, +#include "rgblight.h" +    RGBLIGHT_MODE_last +}; + +#ifndef RGBLIGHT_H_DUMMY_DEFINE + +#define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1)  #ifndef RGBLIGHT_EFFECT_BREATHE_CENTER  #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85  // 1-2.7 @@ -109,7 +167,7 @@ void rgblight_enable(void);  void rgblight_disable(void);  void rgblight_step(void);  void rgblight_step_reverse(void); -uint32_t rgblight_get_mode(void); +uint8_t rgblight_get_mode(void);  void rgblight_mode(uint8_t mode);  void rgblight_set(void);  void rgblight_update_dword(uint32_t dword); @@ -145,6 +203,14 @@ void rgblight_mode_noeeprom(uint8_t mode);  void rgblight_toggle_noeeprom(void);  void rgblight_enable_noeeprom(void);  void rgblight_disable_noeeprom(void); +void rgblight_step_noeeprom(void); +void rgblight_step_reverse_noeeprom(void); +void rgblight_increase_hue_noeeprom(void); +void rgblight_decrease_hue_noeeprom(void); +void rgblight_increase_sat_noeeprom(void); +void rgblight_decrease_sat_noeeprom(void); +void rgblight_increase_val_noeeprom(void); +void rgblight_decrease_val_noeeprom(void);  void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);  void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); @@ -168,4 +234,73 @@ void rgblight_effect_christmas(void);  void rgblight_effect_rgbtest(void);  void rgblight_effect_alternating(void); +#endif // #ifndef RGBLIGHT_H_DUMMY_DEFINE +#endif // RGBLIGHT_H + +#ifdef _RGBM_SINGLE_STATIC +  _RGBM_SINGLE_STATIC( STATIC_LIGHT ) +  #ifdef RGBLIGHT_EFFECT_BREATHING +    _RGBM_MULTI_DYNAMIC( BREATHING ) +    _RGBM_TMP_DYNAMIC( breathing_3 ) +    _RGBM_TMP_DYNAMIC( breathing_4 ) +    _RGBM_TMP_DYNAMIC( BREATHING_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD +    _RGBM_MULTI_DYNAMIC( RAINBOW_MOOD ) +    _RGBM_TMP_DYNAMIC( rainbow_mood_7 ) +    _RGBM_TMP_DYNAMIC( RAINBOW_MOOD_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL +    _RGBM_MULTI_DYNAMIC( RAINBOW_SWIRL ) +    _RGBM_TMP_DYNAMIC( rainbow_swirl_10 ) +    _RGBM_TMP_DYNAMIC( rainbow_swirl_11 ) +    _RGBM_TMP_DYNAMIC( rainbow_swirl_12 ) +    _RGBM_TMP_DYNAMIC( rainbow_swirl_13 ) +    _RGBM_TMP_DYNAMIC( RAINBOW_SWIRL_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_SNAKE +    _RGBM_MULTI_DYNAMIC( SNAKE ) +    _RGBM_TMP_DYNAMIC( snake_16 ) +    _RGBM_TMP_DYNAMIC( snake_17 ) +    _RGBM_TMP_DYNAMIC( snake_18 ) +    _RGBM_TMP_DYNAMIC( snake_19 ) +    _RGBM_TMP_DYNAMIC( SNAKE_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_KNIGHT +    _RGBM_MULTI_DYNAMIC( KNIGHT ) +    _RGBM_TMP_DYNAMIC( knight_22 ) +    _RGBM_TMP_DYNAMIC( KNIGHT_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_CHRISTMAS +    _RGBM_SINGLE_DYNAMIC( CHRISTMAS ) +  #endif +  #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT +    _RGBM_MULTI_STATIC( STATIC_GRADIENT ) +    _RGBM_TMP_STATIC( static_gradient_26 ) +    _RGBM_TMP_STATIC( static_gradient_27 ) +    _RGBM_TMP_STATIC( static_gradient_28 ) +    _RGBM_TMP_STATIC( static_gradient_29 ) +    _RGBM_TMP_STATIC( static_gradient_30 ) +    _RGBM_TMP_STATIC( static_gradient_31 ) +    _RGBM_TMP_STATIC( static_gradient_32 ) +    _RGBM_TMP_STATIC( static_gradient_33 ) +    _RGBM_TMP_STATIC( STATIC_GRADIENT_end ) +  #endif +  #ifdef RGBLIGHT_EFFECT_RGB_TEST +    _RGBM_SINGLE_DYNAMIC( RGB_TEST ) +  #endif +  #ifdef RGBLIGHT_EFFECT_ALTERNATING +    _RGBM_SINGLE_DYNAMIC( ALTERNATING ) +  #endif +  ////  Add a new mode here. +  // #ifdef RGBLIGHT_EFFECT_<name> +  //    _RGBM_<SINGLE|MULTI>_<STATIC|DYNAMIC>( <name> ) +  // #endif  #endif + +#undef _RGBM_SINGLE_STATIC +#undef _RGBM_SINGLE_DYNAMIC +#undef _RGBM_MULTI_STATIC +#undef _RGBM_MULTI_DYNAMIC +#undef _RGBM_TMP_STATIC +#undef _RGBM_TMP_DYNAMIC diff --git a/quantum/rgblight_reconfig.h b/quantum/rgblight_reconfig.h new file mode 100644 index 0000000000..11bd4fd118 --- /dev/null +++ b/quantum/rgblight_reconfig.h @@ -0,0 +1,36 @@ +#ifndef RGBLIGHT_RECONFIG_H +#define RGBLIGHT_RECONFIG_H + +#ifdef RGBLIGHT_ANIMATIONS +   // for backward compatibility +   #define RGBLIGHT_EFFECT_BREATHING +   #define RGBLIGHT_EFFECT_RAINBOW_MOOD +   #define RGBLIGHT_EFFECT_RAINBOW_SWIRL +   #define RGBLIGHT_EFFECT_SNAKE +   #define RGBLIGHT_EFFECT_KNIGHT +   #define RGBLIGHT_EFFECT_CHRISTMAS +   #define RGBLIGHT_EFFECT_STATIC_GRADIENT +   #define RGBLIGHT_EFFECT_RGB_TEST +   #define RGBLIGHT_EFFECT_ALTERNATING +#endif + +#ifdef RGBLIGHT_STATIC_PATTERNS +   #define RGBLIGHT_EFFECT_STATIC_GRADIENT +#endif + +// check dynamic animation effects chose ? +#if defined(RGBLIGHT_EFFECT_BREATHING) || \ +    defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || \ +    defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) ||	\ +    defined(RGBLIGHT_EFFECT_SNAKE) ||		\ +    defined(RGBLIGHT_EFFECT_KNIGHT) ||		\ +    defined(RGBLIGHT_EFFECT_CHRISTMAS) ||	\ +    defined(RGBLIGHT_EFFECT_RGB_TEST) ||	\ +    defined(RGBLIGHT_EFFECT_ALTERNATING) +  #define RGBLIGHT_USE_TIMER +  #ifndef RGBLIGHT_ANIMATIONS +    #define RGBLIGHT_ANIMATIONS  // for backward compatibility +  #endif +#endif + +#endif // RGBLIGHT_RECONFIG_H diff --git a/quantum/split_common/i2c.c b/quantum/split_common/i2c.c index b3d7fcc681..45e958b395 100644 --- a/quantum/split_common/i2c.c +++ b/quantum/split_common/i2c.c @@ -7,8 +7,6 @@  #include "i2c.h"  #include "split_flags.h" -#if defined(USE_I2C) || defined(EH) -  // Limits the amount of we wait for any one i2c transaction.  // Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is  // 9 bits, a single transaction will take around 90μs to complete. @@ -184,4 +182,3 @@ ISR(TWI_vect) {    // Reset everything, so we are ready for the next TWI interrupt    TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);  } -#endif diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 0a79e42566..2c37053f88 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -20,21 +20,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <stdint.h>  #include <stdbool.h> -#include <avr/io.h>  #include "wait.h" -#include "print.h" -#include "debug.h"  #include "util.h"  #include "matrix.h"  #include "split_util.h" -#include "pro_micro.h"  #include "config.h"  #include "timer.h"  #include "split_flags.h" +#include "quantum.h" -#ifdef RGBLIGHT_ENABLE -#   include "rgblight.h" -#endif  #ifdef BACKLIGHT_ENABLE  #   include "backlight.h"      extern backlight_config_t backlight_config; @@ -55,6 +49,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.      static bool debouncing = false;  #endif +#if defined(USE_I2C) || defined(EH) +  #if (MATRIX_COLS <= 8)  #    define print_matrix_header()  print("\nr/c 01234567\n")  #    define print_matrix_row(row)  print_bin_reverse8(matrix_get_row(row)) @@ -63,6 +59,27 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #else  #    error "Currently only supports 8 COLS"  #endif + +#else // USE_SERIAL + +#if (MATRIX_COLS <= 8) +#    define print_matrix_header()  print("\nr/c 01234567\n") +#    define print_matrix_row(row)  print_bin_reverse8(matrix_get_row(row)) +#    define matrix_bitpop(i)       bitpop(matrix[i]) +#    define ROW_SHIFTER ((uint8_t)1) +#elif (MATRIX_COLS <= 16) +#    define print_matrix_header()  print("\nr/c 0123456789ABCDEF\n") +#    define print_matrix_row(row)  print_bin_reverse16(matrix_get_row(row)) +#    define matrix_bitpop(i)       bitpop16(matrix[i]) +#    define ROW_SHIFTER ((uint16_t)1) +#elif (MATRIX_COLS <= 32) +#    define print_matrix_header()  print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") +#    define print_matrix_row(row)  print_bin_reverse32(matrix_get_row(row)) +#    define matrix_bitpop(i)       bitpop32(matrix[i]) +#    define ROW_SHIFTER  ((uint32_t)1) +#endif + +#endif  static matrix_row_t matrix_debouncing[MATRIX_ROWS];  #define ERROR_DISCONNECT_COUNT 5 @@ -71,8 +88,8 @@ static matrix_row_t matrix_debouncing[MATRIX_ROWS];  static uint8_t error_count = 0; -static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;  /* matrix state(1:on, 0:off) */  static matrix_row_t matrix[MATRIX_ROWS]; @@ -128,15 +145,24 @@ uint8_t matrix_cols(void)  void matrix_init(void)  { -#ifdef DISABLE_JTAG -  // JTAG disable for PORT F. write JTD bit twice within four cycles. -  MCUCR |= (1<<JTD); -  MCUCR |= (1<<JTD); -#endif -      debug_enable = true;      debug_matrix = true;      debug_mouse = true; + +    // Set pinout for right half if pinout for that half is defined +    if (!isLeftHand) { +#ifdef MATRIX_ROW_PINS_RIGHT +        const uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT; +        for (uint8_t i = 0; i < MATRIX_ROWS; i++) +            row_pins[i] = row_pins_right[i]; +#endif +#ifdef MATRIX_COL_PINS_RIGHT +        const uint8_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT; +        for (uint8_t i = 0; i < MATRIX_COLS; i++) +            col_pins[i] = col_pins_right[i]; +#endif +    } +      // initialize row and col  #if (DIODE_DIRECTION == COL2ROW)      unselect_rows(); @@ -277,24 +303,48 @@ i2c_error: // the cable is disconnceted, or something else went wrong  #else // USE_SERIAL + +typedef struct _Serial_s2m_buffer_t { +    // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack +    matrix_row_t smatrix[ROWS_PER_HAND]; +} Serial_s2m_buffer_t; + +volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; +volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; +uint8_t volatile status0 = 0; + +SSTD_t transactions[] = { +    { (uint8_t *)&status0, +      sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer, +      sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer +  } +}; + +void serial_master_init(void) +{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } + +void serial_slave_init(void) +{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); } +  int serial_transaction(void) {      int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; -    if (serial_update_buffers()) { +    if (soft_serial_transaction()) {          return 1;      } +    // TODO:  if MATRIX_COLS > 8 change to unpack()      for (int i = 0; i < ROWS_PER_HAND; ++i) { -        matrix[slaveOffset+i] = serial_slave_buffer[i]; +        matrix[slaveOffset+i] = serial_s2m_buffer.smatrix[i];      } -    #ifdef RGBLIGHT_ENABLE +    #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)          // Code to send RGB over serial goes here (not implemented yet)      #endif      #ifdef BACKLIGHT_ENABLE          // Write backlight level for slave to read -        serial_master_buffer[SERIAL_BACKLIT_START] = backlight_config.enable ? backlight_config.level : 0; +        serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;      #endif      return 0; @@ -337,8 +387,9 @@ void matrix_slave_scan(void) {          i2c_slave_buffer[I2C_KEYMAP_START+i] = matrix[offset+i];      }     #else // USE_SERIAL +    // TODO: if MATRIX_COLS > 8 change to pack()      for (int i = 0; i < ROWS_PER_HAND; ++i) { -        serial_slave_buffer[i] = matrix[offset+i]; +        serial_s2m_buffer.smatrix[i] = matrix[offset+i];      }  #endif      matrix_slave_scan_user(); @@ -386,9 +437,7 @@ uint8_t matrix_key_count(void)  static void init_cols(void)  {      for(uint8_t x = 0; x < MATRIX_COLS; x++) { -        uint8_t pin = col_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(col_pins[x]);      }  } @@ -406,13 +455,8 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)      // For each col...      for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { - -        // Select the col pin to read (active low) -        uint8_t pin = col_pins[col_index]; -        uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)); -          // Populate the matrix row with the state of the col pin -        current_matrix[current_row] |=  pin_state ? 0 : (ROW_SHIFTER << col_index); +        current_matrix[current_row] |=  readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);      }      // Unselect row @@ -423,24 +467,19 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)  static void select_row(uint8_t row)  { -    uint8_t pin = row_pins[row]; -    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT -    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +    writePinLow(row_pins[row]); +    setPinOutput(row_pins[row]);  }  static void unselect_row(uint8_t row)  { -    uint8_t pin = row_pins[row]; -    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +    setPinInputHigh(row_pins[row]);  }  static void unselect_rows(void)  {      for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { -        uint8_t pin = row_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(row_pins[x]);      }  } @@ -449,9 +488,7 @@ static void unselect_rows(void)  static void init_rows(void)  {      for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { -        uint8_t pin = row_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(row_pins[x]);      }  } @@ -471,15 +508,15 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)          matrix_row_t last_row_value = current_matrix[row_index];          // Check row pin state -        if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) +        if (readPin(row_pins[row_index]))          { -            // Pin LO, set col bit -            current_matrix[row_index] |= (ROW_SHIFTER << current_col); +            // Pin HI, clear col bit +            current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);          }          else          { -            // Pin HI, clear col bit -            current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); +            // Pin LO, set col bit +            current_matrix[row_index] |= (ROW_SHIFTER << current_col);          }          // Determine if the matrix changed state @@ -497,24 +534,19 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)  static void select_col(uint8_t col)  { -    uint8_t pin = col_pins[col]; -    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT -    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +    writePinLow(col_pins[col]); +    setPinOutput(col_pins[col]);  }  static void unselect_col(uint8_t col)  { -    uint8_t pin = col_pins[col]; -    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +    setPinInputHigh(col_pins[col]);  }  static void unselect_cols(void)  {      for(uint8_t x = 0; x < MATRIX_COLS; x++) { -        uint8_t pin = col_pins[x]; -        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN -        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI +        setPinInputHigh(col_pins[x]);      }  } diff --git a/quantum/split_common/matrix.h b/quantum/split_common/matrix.h new file mode 100644 index 0000000000..b5cb45baed --- /dev/null +++ b/quantum/split_common/matrix.h @@ -0,0 +1,31 @@ +#ifndef SPLIT_COMMON_MATRIX_H +#define SPLIT_COMMON_MATRIX_H + +#include <common/matrix.h> + +#ifdef RGBLIGHT_ENABLE +#   include "rgblight.h" +#endif + +typedef struct _Serial_m2s_buffer_t { +#ifdef BACKLIGHT_ENABLE +    uint8_t backlight_level; +#endif +#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) +    rgblight_config_t rgblight_config; //not yet use +    // +    // When MCUs on both sides drive their respective RGB LED chains, +    // it is necessary to synchronize, so it is necessary to communicate RGB information. +    // In that case, define the RGBLIGHT_SPLIT macro. +    // +    // Otherwise, if the master side MCU drives both sides RGB LED chains, +    // there is no need to communicate. +#endif +} Serial_m2s_buffer_t; + +extern volatile Serial_m2s_buffer_t serial_m2s_buffer; + +void serial_master_init(void); +void serial_slave_init(void); + +#endif diff --git a/quantum/split_common/serial.c b/quantum/split_common/serial.c index 74bcbb6bf6..1315377a34 100644 --- a/quantum/split_common/serial.c +++ b/quantum/split_common/serial.c @@ -1,5 +1,10 @@  /*   * 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 @@ -9,220 +14,533 @@  #include <avr/io.h>  #include <avr/interrupt.h>  #include <util/delay.h> +#include <stddef.h>  #include <stdbool.h>  #include "serial.h" +//#include <pro_micro.h> + +#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 -#ifndef USE_I2C +#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 -// Serial pulse period in microseconds. Its probably a bad idea to lower this -// value. -#define SERIAL_DELAY 24 +#if __GNUC__ < 6 +  #define TID_SEND_ADJUST 14 +#else +  #define TID_SEND_ADJUST 2 +#endif -uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; -uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; +#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_MULTI_TRANSACTION +  #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY +#else +  #define SLAVE_INT_ACK_WIDTH_UNIT 2 +  #define SLAVE_INT_ACK_WIDTH 4 +#endif -#define SLAVE_DATA_CORRUPT (1<<0) -volatile uint8_t status = 0; +static SSTD_t *Transaction_table = NULL; +static uint8_t Transaction_table_size = 0; +inline static void serial_delay(void) ALWAYS_INLINE;  inline static  void serial_delay(void) {    _delay_us(SERIAL_DELAY);  } +inline static void serial_delay_half1(void) ALWAYS_INLINE; +inline static +void serial_delay_half1(void) { +  _delay_us(SERIAL_DELAY_HALF1); +} + +inline static void serial_delay_half2(void) ALWAYS_INLINE; +inline static +void serial_delay_half2(void) { +  _delay_us(SERIAL_DELAY_HALF2); +} + +inline static void serial_output(void) ALWAYS_INLINE;  inline static  void serial_output(void) {    SERIAL_PIN_DDR |= SERIAL_PIN_MASK;  }  // make the serial pin an input with pull-up resistor +inline static void serial_input_with_pullup(void) ALWAYS_INLINE;  inline static -void serial_input(void) { +void serial_input_with_pullup(void) {    SERIAL_PIN_DDR  &= ~SERIAL_PIN_MASK;    SERIAL_PIN_PORT |= SERIAL_PIN_MASK;  } +inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;  inline static  uint8_t serial_read_pin(void) {    return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);  } +inline static void serial_low(void) ALWAYS_INLINE;  inline static  void serial_low(void) {    SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;  } +inline static void serial_high(void) ALWAYS_INLINE;  inline static  void serial_high(void) {    SERIAL_PIN_PORT |= SERIAL_PIN_MASK;  } -void serial_master_init(void) { -  serial_output(); -  serial_high(); +void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) +{ +    Transaction_table = sstd_table; +    Transaction_table_size = (uint8_t)sstd_table_size; +    serial_output(); +    serial_high();  } -void serial_slave_init(void) { -  serial_input(); - -  // Enable INT0 -  EIMSK |= _BV(INT0); -  // Trigger on falling edge of INT0 -  EICRA &= ~(_BV(ISC00) | _BV(ISC01)); +void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) +{ +    Transaction_table = sstd_table; +    Transaction_table_size = (uint8_t)sstd_table_size; +    serial_input_with_pullup(); + +    // Enable INT0-INT3,INT6 +    EIMSK |= EIMSK_BIT; +#if SERIAL_PIN_MASK == _BV(PE6) +    // Trigger on falling edge of INT6 +    EICRB &= EICRx_BIT; +#else +    // Trigger on falling edge of INT0-INT3 +    EICRA &= EICRx_BIT; +#endif  } -// Used by the master to synchronize timing with the slave. +// Used by the sender to synchronize timing with the reciver. +static void sync_recv(void) NO_INLINE;  static  void sync_recv(void) { -  serial_input(); -  // This shouldn't hang if the slave disconnects because the -  // serial line will float to high if the slave does disconnect. +  for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { +  } +  // This shouldn't hang if the target disconnects because the +  // serial line will float to high if the target does disconnect.    while (!serial_read_pin()); -  serial_delay();  } -// Used by the slave to send a synchronization signal to the master. +// Used by the reciver to send a synchronization signal to the sender. +static void sync_send(void) NO_INLINE;  static  void sync_send(void) { -  serial_output(); -    serial_low();    serial_delay(); -    serial_high();  }  // Reads a byte from the serial line -static -uint8_t serial_read_byte(void) { -  uint8_t byte = 0; -  serial_input(); -  for ( uint8_t i = 0; i < 8; ++i) { -    byte = (byte << 1) | serial_read_pin(); -    serial_delay(); -    _delay_us(1); +static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE; +static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { +    uint8_t byte, i, p, pb; + +  _delay_sub_us(READ_WRITE_START_ADJUST); +  for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) { +      serial_delay_half1();   // read the middle of pulses +      if( serial_read_pin() ) { +          byte = (byte << 1) | 1; p ^= 1; +      } else { +          byte = (byte << 1) | 0; p ^= 0; +      } +      _delay_sub_us(READ_WRITE_WIDTH_ADJUST); +      serial_delay_half2();    } +  /* recive parity bit */ +  serial_delay_half1();   // read the middle of pulses +  pb = serial_read_pin(); +  _delay_sub_us(READ_WRITE_WIDTH_ADJUST); +  serial_delay_half2(); + +  *pterrcount += (p != pb)? 1 : 0;    return byte;  }  // Sends a byte with MSB ordering -static -void serial_write_byte(uint8_t data) { -  uint8_t b = 8; -  serial_output(); -  while( b-- ) { -    if(data & (1 << b)) { -      serial_high(); -    } else { -      serial_low(); +void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; +void serial_write_chunk(uint8_t data, uint8_t bit) { +    uint8_t b, p; +    for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) { +        if(data & b) { +            serial_high(); p ^= 1; +        } else { +            serial_low();  p ^= 0; +        } +        serial_delay();      } +    /* send parity bit */ +    if(p & 1) { serial_high(); } +    else      { serial_low(); }      serial_delay(); -  } -} -// interrupt handle to be used by the slave device -ISR(SERIAL_PIN_INTERRUPT) { -  sync_send(); +    serial_low(); // sync_send() / senc_recv() need raise edge +} -  uint8_t checksum = 0; -  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { -    serial_write_byte(serial_slave_buffer[i]); +static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; +static +void serial_send_packet(uint8_t *buffer, uint8_t size) { +  for (uint8_t i = 0; i < size; ++i) { +    uint8_t data; +    data = buffer[i];      sync_send(); -    checksum += serial_slave_buffer[i]; +    serial_write_chunk(data,8);    } -  serial_write_byte(checksum); -  sync_send(); +} -  // wait for the sync to finish sending -  serial_delay(); +static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE; +static +uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { +  uint8_t pecount = 0; +  for (uint8_t i = 0; i < size; ++i) { +    uint8_t data; +    sync_recv(); +    data = serial_read_chunk(&pecount, 8); +    buffer[i] = data; +  } +  return pecount == 0; +} -  // read the middle of pulses -  _delay_us(SERIAL_DELAY/2); +inline static +void change_sender2reciver(void) { +    sync_send();          //0 +    serial_delay_half1(); //1 +    serial_low();         //2 +    serial_input_with_pullup(); //2 +    serial_delay_half1(); //3 +} -  uint8_t checksum_computed = 0; -  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { -    serial_master_buffer[i] = serial_read_byte(); -    sync_send(); -    checksum_computed += serial_master_buffer[i]; +inline static +void change_reciver2sender(void) { +    sync_recv();     //0 +    serial_delay();  //1 +    serial_low();    //3 +    serial_output(); //3 +    serial_delay_half1(); //4 +} + +static inline uint8_t nibble_bits_count(uint8_t bits) +{ +    bits = (bits & 0x5) + (bits >> 1 & 0x5); +    bits = (bits & 0x3) + (bits >> 2 & 0x3); +    return bits; +} + +// interrupt handle to be used by the target device +ISR(SERIAL_PIN_INTERRUPT) { + +#ifndef SERIAL_USE_MULTI_TRANSACTION +  serial_low(); +  serial_output(); +  SSTD_t *trans = Transaction_table; +#else +  // recive transaction table index +  uint8_t tid, bits; +  uint8_t pecount = 0; +  sync_recv(); +  bits = serial_read_chunk(&pecount,7); +  tid = bits>>3; +  bits = (bits&7) != nibble_bits_count(tid); +  if( bits || pecount> 0 || tid > Transaction_table_size ) { +      return;    } -  uint8_t checksum_received = serial_read_byte(); -  sync_send(); +  serial_delay_half1(); -  serial_input(); // end transaction +  serial_high(); // response step1 low->high +  serial_output(); +  _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH); +  SSTD_t *trans = &Transaction_table[tid]; +  serial_low(); // response step2 ack high->low +#endif -  if ( checksum_computed != checksum_received ) { -    status |= SLAVE_DATA_CORRUPT; +  // target send phase +  if( trans->target2initiator_buffer_size > 0 ) +      serial_send_packet((uint8_t *)trans->target2initiator_buffer, +                         trans->target2initiator_buffer_size); +  // target switch to input +  change_sender2reciver(); + +  // target recive phase +  if( trans->initiator2target_buffer_size > 0 ) { +      if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, +                               trans->initiator2target_buffer_size) ) { +          *trans->status = TRANSACTION_ACCEPTED; +      } else { +          *trans->status = TRANSACTION_DATA_ERROR; +      }    } else { -    status &= ~SLAVE_DATA_CORRUPT; +      *trans->status = TRANSACTION_ACCEPTED;    } -} -inline -bool serial_slave_DATA_CORRUPT(void) { -  return status & SLAVE_DATA_CORRUPT; +  sync_recv(); //weit initiator output to high  } -// Copies the serial_slave_buffer to the master and sends the -// serial_master_buffer to the slave. +///////// +//  start transaction by initiator +// +// int  soft_serial_transaction(int sstd_index)  //  // Returns: -// 0 => no error -// 1 => slave did not respond -int serial_update_buffers(void) { -  // this code is very time dependent, so we need to disable interrupts +//    TRANSACTION_END +//    TRANSACTION_NO_RESPONSE +//    TRANSACTION_DATA_ERROR +// this code is very time dependent, so we need to disable interrupts +#ifndef SERIAL_USE_MULTI_TRANSACTION +int  soft_serial_transaction(void) { +  SSTD_t *trans = Transaction_table; +#else +int  soft_serial_transaction(int sstd_index) { +  if( sstd_index > Transaction_table_size ) +      return TRANSACTION_TYPE_ERROR; +  SSTD_t *trans = &Transaction_table[sstd_index]; +#endif    cli(); -  // signal to the slave that we want to start a transaction +  // signal to the target that we want to start a transaction    serial_output();    serial_low(); -  _delay_us(1); +  _delay_us(SLAVE_INT_WIDTH_US); -  // wait for the slaves response -  serial_input(); -  serial_high(); -  _delay_us(SERIAL_DELAY); +#ifndef SERIAL_USE_MULTI_TRANSACTION +  // wait for the target response +  serial_input_with_pullup(); +  _delay_us(SLAVE_INT_RESPONSE_TIME); -  // check if the slave is present +  // check if the target is present    if (serial_read_pin()) { -    // slave failed to pull the line low, assume not present +    // target failed to pull the line low, assume not present +    serial_output(); +    serial_high(); +    *trans->status = TRANSACTION_NO_RESPONSE;      sei(); -    return 1; +    return TRANSACTION_NO_RESPONSE;    } -  // if the slave is present syncronize with it -  sync_recv(); - -  uint8_t checksum_computed = 0; -  // receive data from the slave -  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { -    serial_slave_buffer[i] = serial_read_byte(); -    sync_recv(); -    checksum_computed += serial_slave_buffer[i]; +#else +  // send transaction table index +  int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index)); +  sync_send(); +  _delay_sub_us(TID_SEND_ADJUST); +  serial_write_chunk(tid, 7); +  serial_delay_half1(); + +  // wait for the target response (step1 low->high) +  serial_input_with_pullup(); +  while( !serial_read_pin() ) { +      _delay_sub_us(2);    } -  uint8_t checksum_received = serial_read_byte(); -  sync_recv(); -  if (checksum_computed != checksum_received) { -    sei(); -    return 1; +  // check if the target is present (step2 high->low) +  for( int i = 0; serial_read_pin(); i++ ) { +      if (i > SLAVE_INT_ACK_WIDTH + 1) { +          // slave failed to pull the line low, assume not present +          serial_output(); +          serial_high(); +          *trans->status = TRANSACTION_NO_RESPONSE; +          sei(); +          return TRANSACTION_NO_RESPONSE; +      } +      _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);    } +#endif -  uint8_t checksum = 0; -  // send data to the slave -  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { -    serial_write_byte(serial_master_buffer[i]); -    sync_recv(); -    checksum += serial_master_buffer[i]; +  // initiator recive phase +  // if the target is present syncronize with it +  if( trans->target2initiator_buffer_size > 0 ) { +      if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, +                                trans->target2initiator_buffer_size) ) { +          serial_output(); +          serial_high(); +          *trans->status = TRANSACTION_DATA_ERROR; +          sei(); +          return TRANSACTION_DATA_ERROR; +      } +   } + +  // initiator switch to output +  change_reciver2sender(); + +  // initiator send phase +  if( trans->initiator2target_buffer_size > 0 ) { +      serial_send_packet((uint8_t *)trans->initiator2target_buffer, +                         trans->initiator2target_buffer_size);    } -  serial_write_byte(checksum); -  sync_recv();    // always, release the line when not in use -  serial_output(); -  serial_high(); +  sync_send(); +  *trans->status = TRANSACTION_END;    sei(); -  return 0; +  return TRANSACTION_END;  } +#ifdef SERIAL_USE_MULTI_TRANSACTION +int soft_serial_get_and_clean_status(int sstd_index) { +    SSTD_t *trans = &Transaction_table[sstd_index]; +    cli(); +    int retval = *trans->status; +    *trans->status = 0;; +    sei(); +    return retval; +} +#endif +  #endif + +// Helix serial.c history +//   2018-1-29 fork from let's split and add PD2, modify sync_recv() (#2308, bceffdefc) +//   2018-6-28 bug fix master to slave comm and speed up (#3255, 1038bbef4) +//             (adjusted with avr-gcc 4.9.2) +//   2018-7-13 remove USE_SERIAL_PD2 macro (#3374, f30d6dd78) +//             (adjusted with avr-gcc 4.9.2) +//   2018-8-11 add support multi-type transaction (#3608, feb5e4aae) +//             (adjusted with avr-gcc 4.9.2) +//   2018-10-21 fix serial and RGB animation conflict (#4191, 4665e4fff) +//             (adjusted with avr-gcc 7.3.0) +//   2018-10-28 re-adjust compiler depend value of delay (#4269, 8517f8a66) +//             (adjusted with avr-gcc 5.4.0, 7.3.0) +//   2018-12-17 copy to TOP/quantum/split_common/ and remove backward compatibility code (#4669) diff --git a/quantum/split_common/serial.h b/quantum/split_common/serial.h index e566eb8a06..b6638b3bde 100644 --- a/quantum/split_common/serial.h +++ b/quantum/split_common/serial.h @@ -1,29 +1,65 @@ -#ifndef MY_SERIAL_H -#define MY_SERIAL_H +#ifndef SOFT_SERIAL_H +#define SOFT_SERIAL_H -#include "config.h"  #include <stdbool.h> -/* TODO:  some defines for interrupt setup */ -#define SERIAL_PIN_DDR DDRD -#define SERIAL_PIN_PORT PORTD -#define SERIAL_PIN_INPUT PIND -#define SERIAL_PIN_MASK _BV(PD0) -#define SERIAL_PIN_INTERRUPT INT0_vect +// ///////////////////////////////////////////////////////////////// +// Need Soft Serial defines in config.h +// ///////////////////////////////////////////////////////////////// +// ex. +//  #define SOFT_SERIAL_PIN ??   // ?? = D0,D1,D2,D3,E6 +//  OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5 +//                                               //  1: about 137kbps (default) +//                                               //  2: about 75kbps +//                                               //  3: about 39kbps +//                                               //  4: about 26kbps +//                                               //  5: about 20kbps +// +// //// USE simple API (using signle-type transaction function) +//   /* nothing */ +// //// USE flexible API (using multi-type transaction function) +//   #define SERIAL_USE_MULTI_TRANSACTION +// +// ///////////////////////////////////////////////////////////////// -#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 -#define SERIAL_MASTER_BUFFER_LENGTH 1 +// Soft Serial Transaction Descriptor +typedef struct _SSTD_t  { +    uint8_t *status; +    uint8_t initiator2target_buffer_size; +    uint8_t *initiator2target_buffer; +    uint8_t target2initiator_buffer_size; +    uint8_t *target2initiator_buffer; +} SSTD_t; +#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t)) -// Address location defines  -#define SERIAL_BACKLIT_START   0x00 +// initiator is transaction start side +void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size); +// target is interrupt accept side +void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size); -// Buffers for master - slave communication -extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; -extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; - -void serial_master_init(void); -void serial_slave_init(void); -int serial_update_buffers(void); -bool serial_slave_data_corrupt(void); +// initiator resullt +#define TRANSACTION_END 0 +#define TRANSACTION_NO_RESPONSE 0x1 +#define TRANSACTION_DATA_ERROR  0x2 +#define TRANSACTION_TYPE_ERROR  0x4 +#ifndef SERIAL_USE_MULTI_TRANSACTION +int  soft_serial_transaction(void); +#else +int  soft_serial_transaction(int sstd_index); +#endif +// target status +// *SSTD_t.status has +//   initiator: +//       TRANSACTION_END +//    or TRANSACTION_NO_RESPONSE +//    or TRANSACTION_DATA_ERROR +//   target: +//       TRANSACTION_DATA_ERROR +//    or TRANSACTION_ACCEPTED +#define TRANSACTION_ACCEPTED 0x8 +#ifdef SERIAL_USE_MULTI_TRANSACTION +int  soft_serial_get_and_clean_status(int sstd_index);  #endif + +#endif /* SOFT_SERIAL_H */ diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 13b09d5b81..e41b6f6386 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -1,31 +1,21 @@ -#include <avr/io.h> -#include <avr/wdt.h> -#include <avr/power.h> -#include <avr/interrupt.h> -#include <util/delay.h> -#include <avr/eeprom.h>  #include "split_util.h"  #include "matrix.h"  #include "keyboard.h"  #include "config.h"  #include "timer.h"  #include "split_flags.h" +#include "quantum.h" -#ifdef RGBLIGHT_ENABLE -#   include "rgblight.h" +#ifdef EE_HANDS +#   include "tmk_core/common/eeprom.h"  #endif +  #ifdef BACKLIGHT_ENABLE  #   include "backlight.h"  #endif -#ifdef SPLIT_HAND_PIN -#   include "pincontrol.h" -#endif -  #if defined(USE_I2C) || defined(EH)  #  include "i2c.h" -#else -#  include "serial.h"  #endif  volatile bool isLeftHand = true; @@ -35,14 +25,13 @@ volatile uint8_t setTries = 0;  static void setup_handedness(void) {    #ifdef SPLIT_HAND_PIN      // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand -    pinMode(SPLIT_HAND_PIN, PinDirectionInput); -    isLeftHand = digitalRead(SPLIT_HAND_PIN); +    setPinInput(SPLIT_HAND_PIN); +    isLeftHand = readPin(SPLIT_HAND_PIN);    #else      #ifdef EE_HANDS        isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);      #else -      // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c -      #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT) +      #ifdef MASTER_RIGHT          isLeftHand = !has_usb();        #else          isLeftHand = has_usb(); @@ -94,7 +83,7 @@ void split_keyboard_setup(void) {  void keyboard_slave_loop(void) {     matrix_init(); -    +     //Init RGB     #ifdef RGBLIGHT_ENABLE        rgblight_init(); @@ -103,17 +92,17 @@ void keyboard_slave_loop(void) {     while (1) {      // Matrix Slave Scan      matrix_slave_scan(); -     +      // Read Backlight Info      #ifdef BACKLIGHT_ENABLE -        if (BACKLIT_DIRTY) { -            #ifdef USE_I2C +        #ifdef USE_I2C +            if (BACKLIT_DIRTY) {                  backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]); -            #else // USE_SERIAL -                backlight_set(serial_master_buffer[SERIAL_BACKLIT_START]); -            #endif -            BACKLIT_DIRTY = false; -        } +                BACKLIT_DIRTY = false; +            } +        #else // USE_SERIAL +            backlight_set(serial_m2s_buffer.backlight_level); +        #endif      #endif      // Read RGB Info      #ifdef RGBLIGHT_ENABLE @@ -122,14 +111,14 @@ void keyboard_slave_loop(void) {                  // Disable interupts (RGB data is big)                  cli();                  // Create new DWORD for RGB data -                uint32_t dword;  -                 +                uint32_t dword; +                  // Fill the new DWORD with the data that was sent over                  uint8_t *dword_dat = (uint8_t *)(&dword);                  for (int i = 0; i < 4; i++) {                      dword_dat[i] = i2c_slave_buffer[I2C_RGB_START+i];                  } -                 +                  // Update the RGB now with the new data and set RGB_DIRTY to false                  rgblight_update_dword(dword);                  RGB_DIRTY = false; @@ -137,7 +126,9 @@ void keyboard_slave_loop(void) {                  sei();              }          #else // USE_SERIAL +          #ifdef RGBLIGHT_SPLIT              // Add serial implementation for RGB here +          #endif          #endif      #endif     } diff --git a/quantum/template/avr/config.h b/quantum/template/avr/config.h index caa72af0c2..eed50e5c04 100644 --- a/quantum/template/avr/config.h +++ b/quantum/template/avr/config.h @@ -48,17 +48,35 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  /* COL2ROW, ROW2COL, or CUSTOM_MATRIX */  #define DIODE_DIRECTION COL2ROW +/* + * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. + */ +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 +  // #define BACKLIGHT_PIN B7  // #define BACKLIGHT_BREATHING  // #define BACKLIGHT_LEVELS 3  // #define RGB_DI_PIN E2  // #ifdef RGB_DI_PIN -// #define RGBLIGHT_ANIMATIONS -// #define RGBLED_NUM 16 -// #define RGBLIGHT_HUE_STEP 8 -// #define RGBLIGHT_SAT_STEP 8 -// #define RGBLIGHT_VAL_STEP 8 +//   #define RGBLED_NUM 16 +//   #define RGBLIGHT_HUE_STEP 8 +//   #define RGBLIGHT_SAT_STEP 8 +//   #define RGBLIGHT_VAL_STEP 8 +//   #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ +//   #define RGBLIGHT_SLEEP  /* If defined, the RGB lighting will be switched off when the host goes to sleep */ +// /*== all animations enable ==*/ +//   #define RGBLIGHT_ANIMATIONS +// /*== or choose animations ==*/ +//   #define RGBLIGHT_EFFECT_BREATHING +//   #define RGBLIGHT_EFFECT_RAINBOW_MOOD +//   #define RGBLIGHT_EFFECT_RAINBOW_SWIRL +//   #define RGBLIGHT_EFFECT_SNAKE +//   #define RGBLIGHT_EFFECT_KNIGHT +//   #define RGBLIGHT_EFFECT_CHRISTMAS +//   #define RGBLIGHT_EFFECT_STATIC_GRADIENT +//   #define RGBLIGHT_EFFECT_RGB_TEST +//   #define RGBLIGHT_EFFECT_ALTERNATING  // #endif  /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ @@ -222,3 +240,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #endif  */ +/* Bootmagic Lite key configuration */ +// #define BOOTMAGIC_LITE_ROW 0 +// #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/quantum/template/base/readme.md b/quantum/template/avr/readme.md index d9349811d0..d243c66a94 100644 --- a/quantum/template/base/readme.md +++ b/quantum/template/avr/readme.md @@ -12,4 +12,4 @@ Make example for this keyboard (after setting up your build environment):      make %KEYBOARD%:default -See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
\ No newline at end of file +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/quantum/template/avr/rules.mk b/quantum/template/avr/rules.mk index 92f3a03a92..383a3594b4 100644 --- a/quantum/template/avr/rules.mk +++ b/quantum/template/avr/rules.mk @@ -39,13 +39,24 @@ F_USB = $(F_CPU)  OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT -# Boot Section Size in *bytes* -#   Teensy halfKay   512 -#   Teensy++ halfKay 1024 -#   Atmel DFU loader 4096 -#   LUFA bootloader  4096 -#   USBaspLoader     2048 -OPT_DEFS += -DBOOTLOADER_SIZE=4096 +# Bootloader selection +#   Teensy       halfkay +#   Pro Micro    caterina +#   Atmel DFU    atmel-dfu +#   LUFA DFU     lufa-dfu +#   QMK DFU      qmk-dfu +#   atmega32a    bootloadHID +BOOTLOADER = atmel-dfu + + +# If you don't know the bootloader type, then you can specify the +# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line +#   Teensy halfKay      512 +#   Teensy++ halfKay    1024 +#   Atmel DFU loader    4096 +#   LUFA bootloader     4096 +#   USBaspLoader        2048 +# OPT_DEFS += -DBOOTLOADER_SIZE=4096  # Build Options diff --git a/quantum/template/avr/template.h b/quantum/template/avr/template.h index 031efc9529..0d626ed50b 100644 --- a/quantum/template/avr/template.h +++ b/quantum/template/avr/template.h @@ -18,12 +18,14 @@  #include "quantum.h" -// This a shortcut to help you visually see your layout. -// The following is an example using the Planck MIT layout -// The first section contains all of the arguments representing the physical -// layout of the board and position of the keys -// The second converts the arguments into a two-dimensional array which  -// represents the switch matrix.  +/* This a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */  #define LAYOUT( \      K00, K01, K02, \        K10,  K11   \ diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c index 14a8bc0f28..5f0730c8a9 100644 --- a/quantum/template/base/keymaps/default/keymap.c +++ b/quantum/template/base/keymaps/default/keymap.c @@ -15,32 +15,40 @@   */  #include QMK_KEYBOARD_H -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { -[0] = LAYOUT( /* Base */ -  KC_A,  KC_1,  KC_H, \ -    KC_TAB,  KC_SPC   \ -), +// Defines the keycodes used by our macros in process_record_user +enum custom_keycodes { +  QMKBEST = SAFE_RANGE, +  QMKURL  }; -const uint16_t PROGMEM fn_actions[] = { - +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +  [0] = LAYOUT( /* Base */ +    KC_A,  KC_1,  KC_H, \ +      KC_TAB,  KC_SPC   \ +  ),  }; -const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) -{ -  // MACRODOWN only works in this function -      switch(id) { -        case 0: -          if (record->event.pressed) { -            register_code(KC_RSFT); -          } else { -            unregister_code(KC_RSFT); -          } -        break; +bool process_record_user(uint16_t keycode, keyrecord_t *record) { +  switch (keycode) { +    case QMKBEST: +      if (record->event.pressed) { +        // when keycode QMKBEST is pressed +        SEND_STRING("QMK is the best thing ever!"); +      } else { +        // when keycode QMKBEST is released        } -    return MACRO_NONE; -}; - +      break; +    case QMKURL: +      if (record->event.pressed) { +        // when keycode QMKURL is pressed +        SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER)); +      } else { +        // when keycode QMKURL is released +      } +      break; +  } +  return true; +}  void matrix_init_user(void) { @@ -50,10 +58,6 @@ void matrix_scan_user(void) {  } -bool process_record_user(uint16_t keycode, keyrecord_t *record) { -  return true; -} -  void led_set_user(uint8_t usb_led) {  } diff --git a/quantum/template/ps2avrgb/config.h b/quantum/template/ps2avrgb/config.h index d2c83781fa..4ff3513bc7 100644 --- a/quantum/template/ps2avrgb/config.h +++ b/quantum/template/ps2avrgb/config.h @@ -44,3 +44,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  /* key combination for command */  #define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) + +/* Bootmagic Lite key configuration */ +// #define BOOTMAGIC_LITE_ROW 0 +// #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/quantum/template/ps2avrgb/readme.md b/quantum/template/ps2avrgb/readme.md new file mode 100644 index 0000000000..feec722a52 --- /dev/null +++ b/quantum/template/ps2avrgb/readme.md @@ -0,0 +1,44 @@ +# %KEYBOARD% + + + +A short description of the keyboard/project + +Keyboard Maintainer: [You](https://github.com/yourusername)   +Hardware Supported: The PCBs, controllers supported   +Hardware Availability: links to where you can find this hardware + +Make example for this keyboard (after setting up your build environment): + +    make %KEYBOARD%:default + +Flashing + +ps2avr(GB) boards use an atmega32a microcontroller and a different bootloader. It is not flashable using the regular QMK methods.  + +Windows:  +1. Download [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash). +2. Place your keyboard into reset.  +3. Press the `Find Device` button and ensure that your keyboard is found. +4. Press the `Open .hex File` button and locate the `.hex` file you created. +5. Press the `Flash Device` button and wait for the process to complete.  + +macOS: +1. Install homebrew by typing the following:    +    ``` +    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +    ``` +2. Install `crosspack-avr`.   +    ``` +    brew cask install crosspack-avr +    ``` +3. Install the following packages: +    ``` +    brew install python +    brew install pyusb +    brew install --HEAD`https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb + +4. Place your keyboard into reset.  +5. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file.  + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/quantum/template/ps2avrgb/rules.mk b/quantum/template/ps2avrgb/rules.mk index 68d50aec67..85603f955c 100644 --- a/quantum/template/ps2avrgb/rules.mk +++ b/quantum/template/ps2avrgb/rules.mk @@ -31,8 +31,8 @@ F_CPU = 12000000  BOOTLOADER = bootloadHID  # build options -BOOTMAGIC_ENABLE = yes -MOUSEKEY_ENABLE = yes +BOOTMAGIC_ENABLE = full +MOUSEKEY_ENABLE = no  EXTRAKEY_ENABLE = yes  CONSOLE_ENABLE = yes  COMMAND_ENABLE = yes diff --git a/quantum/template/ps2avrgb/template.h b/quantum/template/ps2avrgb/template.h index c3924ee71f..b4d6f46624 100644 --- a/quantum/template/ps2avrgb/template.h +++ b/quantum/template/ps2avrgb/template.h @@ -18,10 +18,14 @@  #include "quantum.h" -// This a shortcut to help you visually see your layout. -// The following is an example using the Planck MIT layout -// The first section contains all of the arguments -// The second converts the arguments into a two-dimensional array +/* This a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */  #define LAYOUT( \      k00, k01, k02, \        k10,  k11   \  | 
