diff options
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/keycode_config.h | 2 | ||||
| -rw-r--r-- | quantum/keymap.h | 11 | ||||
| -rw-r--r-- | quantum/keymap_common.c (renamed from quantum/keymap.c) | 10 | ||||
| -rw-r--r-- | quantum/matrix.c | 294 | ||||
| -rw-r--r-- | quantum/quantum.c | 2 | ||||
| -rw-r--r-- | quantum/quantum.h | 8 | 
6 files changed, 187 insertions, 140 deletions
| diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index c41c08706c..6216eefc90 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -18,4 +18,4 @@ typedef union {      };  } keymap_config_t; -keymap_config_t keymap_config;
\ No newline at end of file +extern keymap_config_t keymap_config; diff --git a/quantum/keymap.h b/quantum/keymap.h index a994f4f2e5..73f99f8211 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -21,7 +21,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include <stdint.h>  #include <stdbool.h>  #include "action.h" +#if defined(__AVR__)  #include <avr/pgmspace.h> +#endif  #include "keycode.h"  #include "action_macro.h"  #include "report.h" @@ -30,12 +32,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "debug.h"  #include "keycode_config.h" +// ChibiOS uses RESET in its FlagStatus enumeration +// Therefore define it as QK_RESET here, to avoid name collision +#if defined(PROTOCOL_CHIBIOS) +#define RESET QK_RESET +#endif +  /* translates key to keycode */  uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); -/* translates Fn keycode to action */ -action_t keymap_fn_to_action(uint16_t keycode); -  extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];  extern const uint16_t fn_actions[]; diff --git a/quantum/keymap.c b/quantum/keymap_common.c index 74fd518c9b..76872ac592 100644 --- a/quantum/keymap.c +++ b/quantum/keymap_common.c @@ -19,7 +19,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "report.h"  #include "keycode.h"  #include "action_layer.h" +#if defined(__AVR__)  #include <util/delay.h> +#include <stdio.h> +#endif  #include "action.h"  #include "action_macro.h"  #include "debug.h" @@ -32,7 +35,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  extern keymap_config_t keymap_config; -#include <stdio.h>  #include <inttypes.h>  /* converts key to action */ @@ -46,10 +48,12 @@ action_t action_for_key(uint8_t layer, keypos_t key)      action_t action;      uint8_t action_layer, when, mod; +    // The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason +    const uint16_t* actions = fn_actions;      switch (keycode) {          case KC_FN0 ... KC_FN31: -            action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]); +            action.code = pgm_read_word(&actions[FN_INDEX(keycode)]);              break;          case KC_A ... KC_EXSEL:          case KC_LCTRL ... KC_RGUI: @@ -75,7 +79,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)          case QK_FUNCTION ... QK_FUNCTION_MAX: ;              // Is a shortcut for function action_layer, pull last 12bits              // This means we have 4,096 FN macros at our disposal -            action.code = pgm_read_word(&fn_actions[(int)keycode & 0xFFF]); +            action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]);              break;          case QK_MACRO ... QK_MACRO_MAX:              action.code = ACTION_MACRO(keycode & 0xFF); diff --git a/quantum/matrix.c b/quantum/matrix.c index f5744658cf..0949170255 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -17,39 +17,55 @@ 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" -#ifdef MATRIX_HAS_GHOST -#   error "The universal matrix.c file cannot be used for this keyboard." -#endif +/* Set 0 if debouncing isn't needed */ +/* + * This constant define not debouncing time in msecs, but amount of matrix + * scan loops which should be made to get stable debounced results. + * + * On Ergodox matrix scan rate is relatively low, because of slow I2C. + * Now it's only 317 scans/second, or about 3.15 msec/scan. + * According to Cherry specs, debouncing time is 5 msec. + * + * And so, there is no sense to have DEBOUNCE higher than 2. + */  #ifndef DEBOUNCING_DELAY  #   define DEBOUNCING_DELAY 5  #endif +static uint8_t debouncing = DEBOUNCING_DELAY;  static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;  static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -/* matrix state */ -#if DIODE_DIRECTION == COL2ROW + +/* matrix state(1:on, 0:off) */  static matrix_row_t matrix[MATRIX_ROWS]; -#else -static matrix_col_t matrix[MATRIX_COLS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +#if DIODE_DIRECTION == ROW2COL +    static matrix_row_t matrix_reversed[MATRIX_COLS]; +    static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS];  #endif -static int8_t debouncing_delay = -1; -#if DIODE_DIRECTION == COL2ROW -static void toggle_row(uint8_t row); -static matrix_row_t read_cols(void); +#if MATRIX_COLS > 16 +    #define SHIFTER 1UL  #else -static void toggle_col(uint8_t col); -static matrix_col_t read_rows(void); +    #define SHIFTER 1  #endif +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); +  __attribute__ ((weak))  void matrix_init_quantum(void) {      matrix_init_kb(); @@ -78,10 +94,12 @@ __attribute__ ((weak))  void matrix_scan_user(void) {  } +inline  uint8_t matrix_rows(void) {      return MATRIX_ROWS;  } +inline  uint8_t matrix_cols(void) {      return MATRIX_COLS;  } @@ -111,161 +129,179 @@ uint8_t matrix_cols(void) {  // }  void matrix_init(void) { -    /* frees PORTF by setting the JTD bit twice within four cycles */ +    // To use PORTF disable JTAG with writing JTD bit twice within four cycles.      #ifdef __AVR_ATmega32U4__          MCUCR |= _BV(JTD);          MCUCR |= _BV(JTD);      #endif -    /* initializes the I/O pins */ -#if DIODE_DIRECTION == COL2ROW -    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -        /* DDRxn */ -        _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); -        toggle_row(r); -    } -    for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -        /* PORTxn */ -        _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); -    } -#else -    for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -        /* DDRxn */ -        _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); -        toggle_col(c); -    } -    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -        /* PORTxn */ -        _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); + +    // initialize row and col +    unselect_rows(); +    init_cols(); + +    // initialize matrix state: all keys off +    for (uint8_t i=0; i < MATRIX_ROWS; i++) { +        matrix[i] = 0; +        matrix_debouncing[i] = 0;      } -#endif +      matrix_init_quantum();  } +uint8_t matrix_scan(void) +{ +  #if DIODE_DIRECTION == COL2ROW -uint8_t matrix_scan(void) { -    static matrix_row_t debouncing_matrix[MATRIX_ROWS]; -    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -        toggle_row(r); -        matrix_row_t state = read_cols(); -        if (debouncing_matrix[r] != state) { -            debouncing_matrix[r] = state; -            debouncing_delay = DEBOUNCING_DELAY; -        } -        toggle_row(r); -    } -    if (debouncing_delay >= 0) { -        dprintf("Debouncing delay remaining: %X\n", debouncing_delay); -        --debouncing_delay; -        if (debouncing_delay >= 0) { -            wait_ms(1); -        } -        else { -            for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -                matrix[r] = debouncing_matrix[r]; +    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { +        select_row(i); +        wait_us(30);  // without this wait read unstable value. +        matrix_row_t cols = read_cols(); +        if (matrix_debouncing[i] != cols) { +            matrix_debouncing[i] = cols; +            if (debouncing) { +                debug("bounce!: "); debug_hex(debouncing); debug("\n");              } +            debouncing = DEBOUNCING_DELAY;          } +        unselect_rows();      } -    matrix_scan_quantum(); -    return 1; -} - -static void toggle_row(uint8_t row) { -    /* PINxn */ -    _SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF); -} -static matrix_row_t read_cols(void) { -    matrix_row_t state = 0; -    for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -        /* PINxn */ -        if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) { -            state |= (matrix_row_t)1 << c; +    if (debouncing) { +        if (--debouncing) { +            wait_us(1); +        } else { +            for (uint8_t i = 0; i < MATRIX_ROWS; i++) { +                matrix[i] = matrix_debouncing[i]; +            }          }      } -    return state; -} - -matrix_row_t matrix_get_row(uint8_t row) { -    return matrix[row]; -} -  #else -uint8_t matrix_scan(void) { -    static matrix_col_t debouncing_matrix[MATRIX_COLS]; -    for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -        toggle_col(c); -        matrix_col_t state = read_rows(); -        if (debouncing_matrix[c] != state) { -            debouncing_matrix[c] = state; -            debouncing_delay = DEBOUNCING_DELAY; +    for (uint8_t i = 0; i < MATRIX_COLS; i++) { +        select_row(i); +        wait_us(30);  // without this wait read unstable value. +        matrix_row_t rows = read_cols(); +        if (matrix_reversed_debouncing[i] != rows) { +            matrix_reversed_debouncing[i] = rows; +            if (debouncing) { +                debug("bounce!: "); debug_hex(debouncing); debug("\n"); +            } +            debouncing = DEBOUNCING_DELAY;          } -        toggle_col(c); +        unselect_rows();      } -    if (debouncing_delay >= 0) { -        dprintf("Debouncing delay remaining: %X\n", debouncing_delay); -        --debouncing_delay; -        if (debouncing_delay >= 0) { -            wait_ms(1); -        } -        else { -            for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -                matrix[c] = debouncing_matrix[c]; + +    if (debouncing) { +        if (--debouncing) { +            wait_us(1); +        } else { +            for (uint8_t i = 0; i < MATRIX_COLS; i++) { +                matrix_reversed[i] = matrix_reversed_debouncing[i];              }          }      } +    for (uint8_t y = 0; y < MATRIX_ROWS; y++) { +        matrix_row_t row = 0; +        for (uint8_t x = 0; x < MATRIX_COLS; x++) { +            row |= ((matrix_reversed[x] & (1<<y)) >> y) << x; +        } +        matrix[y] = row; +    } +#endif +      matrix_scan_quantum(); +      return 1;  } -static void toggle_col(uint8_t col) { -    /* PINxn */ -    _SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF); +bool matrix_is_modified(void) +{ +    if (debouncing) return false; +    return true;  } -static matrix_col_t read_rows(void) { -    matrix_col_t state = 0; -    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -        /* PINxn */ -        if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) { -            state |= (matrix_col_t)1 << r; -        } +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ +    return (matrix[row] & ((matrix_row_t)1<col)); +} + +inline +matrix_row_t matrix_get_row(uint8_t row) +{ +    return matrix[row]; +} + +void matrix_print(void) +{ +    print("\nr/c 0123456789ABCDEF\n"); +    for (uint8_t row = 0; row < MATRIX_ROWS; row++) { +        phex(row); print(": "); +        pbin_reverse16(matrix_get_row(row)); +        print("\n");      } -    return state;  } -matrix_row_t matrix_get_row(uint8_t row) { -    matrix_row_t state = 0; -    matrix_col_t mask = (matrix_col_t)1 << row; -    for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { -        if (matrix[c] & mask) { -            state |= (matrix_row_t)1 << c; -        } +uint8_t matrix_key_count(void) +{ +    uint8_t count = 0; +    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { +        count += bitpop16(matrix[i]);      } -    return state; +    return count;  } +static void init_cols(void) +{ +#if DIODE_DIRECTION == COL2ROW +    for(int x = 0; x < MATRIX_COLS; x++) { +        int pin = col_pins[x]; +#else +    for(int x = 0; x < MATRIX_ROWS; x++) { +        int pin = row_pins[x];  #endif - -bool matrix_is_modified(void) { -    if (debouncing_delay >= 0) return false; -    return true; +        _SFR_IO8((pin >> 4) + 1) &=  ~_BV(pin & 0xF); +        _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); +    }  } -bool matrix_is_on(uint8_t row, uint8_t col) { -    return matrix_get_row(row) & (matrix_row_t)1 << col; -} +static matrix_row_t read_cols(void) +{ +    matrix_row_t result = 0; -void matrix_print(void) { -    dprintln("Human-readable matrix state:"); -    for (uint8_t r = 0; r < MATRIX_ROWS; r++) { -        dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); +#if DIODE_DIRECTION == COL2ROW +    for(int x = 0; x < MATRIX_COLS; x++) {      +        int pin = col_pins[x]; +#else +    for(int x = 0; x < MATRIX_ROWS; x++) { +        int pin = row_pins[x]; +#endif +        result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x);      } +    return result;  } -uint8_t matrix_key_count(void) { -    uint8_t count = 0; -    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { -        count += bitpop16(matrix_get_row(r)); +static void unselect_rows(void) +{ +#if DIODE_DIRECTION == COL2ROW +    for(int x = 0; x < MATRIX_ROWS; x++) {  +        int pin = row_pins[x]; +#else +    for(int x = 0; x < MATRIX_COLS; x++) {  +        int pin = col_pins[x]; +#endif +        _SFR_IO8((pin >> 4) + 1) &=  ~_BV(pin & 0xF); +        _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);      } -    return count; +} + +static void select_row(uint8_t row) +{ + +#if DIODE_DIRECTION == COL2ROW +    int pin = row_pins[row]; +#else +    int pin = col_pins[row]; +#endif +    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); +    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF);  } diff --git a/quantum/quantum.c b/quantum/quantum.c index 270b976e36..d59bd5a3f8 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -88,7 +88,7 @@ bool process_record_quantum(keyrecord_t *record) {            stop_all_notes();            shutdown_user();          #endif -        _delay_ms(250); +        wait_ms(250);          #ifdef ATREUS_ASTAR              *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific          #endif diff --git a/quantum/quantum.h b/quantum/quantum.h index 9b5d310bd4..3a0b742028 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -1,7 +1,12 @@  #ifndef QUANTUM_H  #define QUANTUM_H +#if defined(__AVR__)  #include <avr/pgmspace.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#endif +#include "wait.h"  #include "matrix.h"  #include "keymap.h"  #ifdef BACKLIGHT_ENABLE @@ -14,12 +19,9 @@  #include "action_layer.h"  #include "eeconfig.h"  #include <stddef.h> -#include <avr/io.h> -#include <util/delay.h>  #include "bootloader.h"  #include "timer.h"  #include "config_common.h" -#include <avr/interrupt.h>  #include "led.h"  #include "action_util.h"  #include <stdlib.h> | 
