~ruther/qmk_firmware

0137b0231957c0b2fde80ac0e2a769ba4cbd60e7 — zvecr 6 years ago dc570b0
Port DIRECT_PINS from split_common/matrix.c to matrix.c (#5091)

* Port DIRECT_PINS from split_common/matrix.c to matrix.c

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c

* Refactor nano to use DIRECT_PINS

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c

* Add DIRECT_PINS documentation

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c - fix logic from inherited from split_common

* Add DIRECT_PINS documentation - review comments
M docs/config_options.md => docs/config_options.md +2 -0
@@ 59,6 59,8 @@ This is a C header file that is one of the first things included, and will persi
  * define is matrix has ghost (unlikely)
* `#define DIODE_DIRECTION COL2ROW`
  * COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows.
* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
  * pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground.
* `#define AUDIO_VOICES`
  * turns on the alternate audio voices (to cycle through)
* `#define C4_AUDIO`

M docs/hardware_avr.md => docs/hardware_avr.md +18 -0
@@ 93,6 93,24 @@ Finally, you can specify the direction your diodes point. This can be `COL2ROW` 
#define DIODE_DIRECTION COL2ROW
```

#### Direct Pin Matrix
To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`.

```c
// #define MATRIX_ROW_PINS { D0, D5 }
// #define MATRIX_COL_PINS { F1, F0, B0 }
#define DIRECT_PINS { \
    { F1, E6, B0, B2, B3 }, \
    { F5, F0, B1, B7, D2 }, \
    { F6, F7, C7, D5, D3 }, \
    { B5, C6, B6, NO_PIN, NO_PIN } \
}
#define UNUSED_PINS

/* COL2ROW, ROW2COL */
//#define DIODE_DIRECTION
```

### Backlight Configuration

By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are using one of those you can simply enable it here. For more details see the [Backlight Documentation](feature_backlight.md).

M docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md => docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md +2 -0
@@ 22,6 22,8 @@ The `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` are the pins your MCU uses on each r

For the `DIODE_DIRECTION`, most hand-wiring guides will instruct you to wire the diodes in the `COL2ROW` position, but it's possible that they are in the other - people coming from EasyAVR often use `ROW2COL`. Nothing will function if this is incorrect.

To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`.

`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. Currently only B5, B6, and B7 are supported.

`BACKLIGHT_BREATHING` is a fancier backlight feature that adds breathing/pulsing/fading effects to the backlight. It uses the same timer as the normal backlight. These breathing effects must be called by code in your keymap.

M keyboards/40percentclub/nano/config.h => keyboards/40percentclub/nano/config.h +22 -5
@@ 31,12 31,29 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_ROWS 2
#define MATRIX_COLS 4

/*
 * Keyboard Matrix Assignments
 *
 * Change this to how you wired your keyboard
 * COLS: AVR pins used for columns, left to right
 * ROWS: AVR pins used for rows, top to bottom
 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
 *                  ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
 *                  NO_DIODE = switches are directly connected to AVR pins
 *
*/
// #define MATRIX_ROW_PINS { D0, D5 }
// #define MATRIX_COL_PINS { F1, F0, B0 }
#define DIRECT_PINS {   \
    { F4, F5, F6, F7 }, \
    { D1, D0, D4, C6 }, \
}
#define UNUSED_PINS

/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
//#define DIODE_DIRECTION CUSTOM_MATRIX

/* ws2812 RGB LED */
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 6    // Number of LEDs

/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW

#define TAPPING_TERM 200

D keyboards/40percentclub/nano/matrix.c => keyboards/40percentclub/nano/matrix.c +0 -159
@@ 1,159 0,0 @@
/*

Note for ErgoDox EZ customizers: Here be dragons!
This is not a file you want to be messing with.
All of the interesting stuff for you is under keymaps/ :)
Love, Erez

Copyright 2013 Oleg Kostyuk <cub.uanic@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/>.
*/

/*
 * scan matrix
 */
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "action_layer.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "nano.h"
#include <string.h>

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_stage[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

static uint16_t debouncing_time;
static bool debouncing = false;

__attribute__ ((weak))
void matrix_init_kb(void) {
    matrix_init_user();
}

__attribute__ ((weak))
void matrix_scan_kb(void) {
    matrix_scan_user();
}

__attribute__ ((weak))
void matrix_init_user(void) {
}

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

void matrix_init(void)
{

    DDRF  &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
    PORTF |=  (1<<4 | 1<<5 | 1<<6 | 1<<7);
    DDRC  &= ~(1<<6);
    PORTC |=  (1<<6);
    DDRD  &= ~(1<<0 | 1<<1 | 1<<4);
    PORTD |=  (1<<0 | 1<<1 | 1<<4);

    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        matrix[i] = 0;
        matrix_debouncing[i] = 0;
        matrix_stage[i] = 0;
    }

    matrix_init_quantum();

}

uint8_t matrix_scan(void)
{
    matrix_stage[0] =
        (PINF&(1<<4) ? 0 : (1<<0)) |
        (PINF&(1<<5) ? 0 : (1<<1)) |
        (PINF&(1<<6) ? 0 : (1<<2)) |
        (PINF&(1<<7) ? 0 : (1<<3));
    matrix_stage[1] =
        (PIND&(1<<1) ? 0 : (1<<0)) |
        (PIND&(1<<0) ? 0 : (1<<1)) |
        (PIND&(1<<4) ? 0 : (1<<2)) |
        (PINC&(1<<6) ? 0 : (1<<3));

    if (memcmp(matrix_debouncing, matrix_stage, sizeof(matrix)) != 0) {
        debouncing = true;
        debouncing_time = timer_read();
    }

    matrix_debouncing[0] = matrix_stage[0];
    matrix_debouncing[1] = matrix_stage[1];

    if (debouncing && (timer_elapsed(debouncing_time) > 20)) {
        for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
            matrix[i] = matrix_debouncing[i];
        }
        debouncing = false;
    }

    matrix_scan_quantum();

    return 1;
}

bool matrix_is_modified(void)
{
    return true;
}

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

uint8_t matrix_key_count(void)
{
    uint8_t count = 0;
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        count += bitpop16(matrix[i]);
    }
    return count;
}


M keyboards/40percentclub/nano/nano.h => keyboards/40percentclub/nano/nano.h +3 -1
@@ 2,10 2,12 @@

#include "quantum.h"

#define LAYOUT( \
#define LAYOUT_ortho_2x4( \
    k01, k02, k03, k04, \
    k05, k06, k07, k08  \
  ) { \
    { k01, k02, k03, k04 }, \
    { k05, k06, k07, k08 } \
}

#define LAYOUT LAYOUT_ortho_2x4 

M keyboards/40percentclub/nano/rules.mk => keyboards/40percentclub/nano/rules.mk +0 -4
@@ 76,7 76,3 @@ RGBLIGHT_ENABLE = yes       # Enable WS2812 RGB underlight.

# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend

# custom matrix setup
SRC = matrix.c
CUSTOM_MATRIX = yes

M quantum/matrix.c => quantum/matrix.c +99 -90
@@ 45,7 45,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
    extern const matrix_row_t matrix_mask[];
#endif

#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
#ifdef DIRECT_PINS
static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
#endif


@@ 54,20 56,6 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
static matrix_row_t matrix[MATRIX_ROWS]; //debounced values

#if (DIODE_DIRECTION == COL2ROW)
    static void init_cols(void);
    static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
    static void unselect_rows(void);
    static void select_row(uint8_t row);
    static void unselect_row(uint8_t row);
#elif (DIODE_DIRECTION == ROW2COL)
    static void init_rows(void);
    static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
    static void unselect_cols(void);
    static void unselect_col(uint8_t col);
    static void select_col(uint8_t col);
#endif

__attribute__ ((weak))
void matrix_init_quantum(void) {
    matrix_init_kb();


@@ 106,49 94,6 @@ uint8_t matrix_cols(void) {
    return MATRIX_COLS;
}

void matrix_init(void) {

    // initialize row and col
#if (DIODE_DIRECTION == COL2ROW)
    unselect_rows();
    init_cols();
#elif (DIODE_DIRECTION == ROW2COL)
    unselect_cols();
    init_rows();
#endif

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        raw_matrix[i] = 0;
        matrix[i] = 0;
    }
    debounce_init(MATRIX_ROWS);

    matrix_init_quantum();
}

uint8_t matrix_scan(void)
{
  bool changed = false;

#if (DIODE_DIRECTION == COL2ROW)
  // Set row, read cols
  for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
    changed |= read_cols_on_row(raw_matrix, current_row);
  }
#elif (DIODE_DIRECTION == ROW2COL)
  // Set col, read rows
  for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    changed |= read_rows_on_col(raw_matrix, current_col);
  }
#endif

  debounce(raw_matrix, matrix, MATRIX_ROWS, changed);

  matrix_scan_quantum();
  return 1;
}

//Deprecated.
bool matrix_is_modified(void)
{


@@ 195,16 140,60 @@ uint8_t matrix_key_count(void)
}


#ifdef DIRECT_PINS

static void init_pins(void) {
  for (int row = 0; row < MATRIX_ROWS; row++) {
    for (int col = 0; col < MATRIX_COLS; col++) {
      pin_t pin = direct_pins[row][col];
      if (pin != NO_PIN) {
        setPinInputHigh(pin);
      }
    }
  }
}

#if (DIODE_DIRECTION == COL2ROW)
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
  matrix_row_t last_row_value = current_matrix[current_row];
  current_matrix[current_row] = 0;

static void init_cols(void)
  for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
    pin_t pin = direct_pins[current_row][col_index];
    if (pin != NO_PIN) {
      current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
    }
  }

  return (last_row_value != current_matrix[current_row]);
}

#elif (DIODE_DIRECTION == COL2ROW)

static void select_row(uint8_t row)
{
    for(uint8_t x = 0; x < MATRIX_COLS; x++) {
        setPinInputHigh(col_pins[x]);
    setPinOutput(row_pins[row]);
    writePinLow(row_pins[row]);
}

static void unselect_row(uint8_t row)
{
    setPinInputHigh(row_pins[row]);
}

static void unselect_rows(void)
{
    for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
        setPinInput(row_pins[x]);
    }
}

static void init_pins(void) {
  unselect_rows();
  for (uint8_t x = 0; x < MATRIX_COLS; x++) {
    setPinInputHigh(col_pins[x]);
  }
}

static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
{
    // Store last value of row prior to reading


@@ 233,31 222,31 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
    return (last_row_value != current_matrix[current_row]);
}

static void select_row(uint8_t row)
#elif (DIODE_DIRECTION == ROW2COL)

static void select_col(uint8_t col)
{
    setPinOutput(row_pins[row]);
    writePinLow(row_pins[row]);
    setPinOutput(col_pins[col]);
    writePinLow(col_pins[col]);
}

static void unselect_row(uint8_t row)
static void unselect_col(uint8_t col)
{
    setPinInputHigh(row_pins[row]);
    setPinInputHigh(col_pins[col]);
}

static void unselect_rows(void)
static void unselect_cols(void)
{
    for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
        setPinInput(row_pins[x]);
    for(uint8_t x = 0; x < MATRIX_COLS; x++) {
        setPinInputHigh(col_pins[x]);
    }
}

#elif (DIODE_DIRECTION == ROW2COL)

static void init_rows(void)
{
    for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
        setPinInputHigh(row_pins[x]);
    }
static void init_pins(void) {
  unselect_cols();
  for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
    setPinInputHigh(row_pins[x]);
  }
}

static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)


@@ 300,22 289,42 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
    return matrix_changed;
}

static void select_col(uint8_t col)
{
    setPinOutput(col_pins[col]);
    writePinLow(col_pins[col]);
}
#endif

static void unselect_col(uint8_t col)
{
    setPinInputHigh(col_pins[col]);
}
void matrix_init(void) {

static void unselect_cols(void)
{
    for(uint8_t x = 0; x < MATRIX_COLS; x++) {
        setPinInputHigh(col_pins[x]);
    // initialize key pins
    init_pins();

    // initialize matrix state: all keys off
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
        raw_matrix[i] = 0;
        matrix[i] = 0;
    }

    debounce_init(MATRIX_ROWS);

    matrix_init_quantum();
}

uint8_t matrix_scan(void)
{
  bool changed = false;

#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
  // Set row, read cols
  for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
    changed |= read_cols_on_row(raw_matrix, current_row);
  }
#elif (DIODE_DIRECTION == ROW2COL)
  // Set col, read rows
  for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    changed |= read_rows_on_col(raw_matrix, current_col);
  }
#endif

  debounce(raw_matrix, matrix, MATRIX_ROWS, changed);

  matrix_scan_quantum();
  return 1;
}