diff options
Diffstat (limited to 'quantum/split_common')
| -rw-r--r-- | quantum/split_common/matrix.c | 44 | ||||
| -rw-r--r-- | quantum/split_common/transport.c | 101 | 
2 files changed, 128 insertions, 17 deletions
| diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 51bf8b1095..bad762b493 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -114,9 +114,9 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)      // Start with a clear matrix row      matrix_row_t current_row_value = 0; -    // Select row and wait for row selecton to stabilize +    // Select row      select_row(current_row); -    matrix_io_delay(); +    matrix_output_select_delay();      // For each col...      for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { @@ -129,6 +129,9 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)      // Unselect row      unselect_row(current_row); +    if (current_row + 1 < MATRIX_ROWS) { +        matrix_output_unselect_delay();  // wait for row signal to go HIGH +    }      // If the row has changed, store the row and return the changed flag.      if (current_matrix[current_row] != current_row_value) { @@ -160,9 +163,9 @@ static void init_pins(void) {  static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {      bool matrix_changed = false; -    // Select col and wait for col selecton to stabilize +    // Select col      select_col(current_col); -    matrix_io_delay(); +    matrix_output_select_delay();      // For each row...      for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { @@ -188,6 +191,9 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)      // Unselect col      unselect_col(current_col); +    if (current_col + 1 < MATRIX_COLS) { +        matrix_output_unselect_delay();  // wait for col signal to go HIGH +    }      return matrix_changed;  } @@ -245,21 +251,33 @@ void matrix_init(void) {      split_post_init();  } -void matrix_post_scan(void) { +bool matrix_post_scan(void) { +    bool changed = false;      if (is_keyboard_master()) {          static uint8_t error_count; -        if (!transport_master(matrix + thatHand)) { +        matrix_row_t slave_matrix[ROWS_PER_HAND] = {0}; +        if (!transport_master(slave_matrix)) {              error_count++;              if (error_count > ERROR_DISCONNECT_COUNT) {                  // reset other half if disconnected                  for (int i = 0; i < ROWS_PER_HAND; ++i) {                      matrix[thatHand + i] = 0; +                    slave_matrix[i]      = 0;                  } + +                changed = true;              }          } else {              error_count = 0; + +            for (int i = 0; i < ROWS_PER_HAND; ++i) { +                if (matrix[thatHand + i] != slave_matrix[i]) { +                    matrix[thatHand + i] = slave_matrix[i]; +                    changed              = true; +                } +            }          }          matrix_scan_quantum(); @@ -268,25 +286,27 @@ void matrix_post_scan(void) {          matrix_slave_scan_user();      } + +    return changed;  }  uint8_t matrix_scan(void) { -    bool changed = false; +    bool local_changed = false;  #if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)      // Set row, read cols      for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { -        changed |= read_cols_on_row(raw_matrix, current_row); +        local_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); +        local_changed |= read_rows_on_col(raw_matrix, current_col);      }  #endif -    debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); +    debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed); -    matrix_post_scan(); -    return (uint8_t)changed; +    bool remote_changed = matrix_post_scan(); +    return (uint8_t)(local_changed || remote_changed);  } diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 467ff81a97..b45ba92c3b 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -6,6 +6,7 @@  #include "quantum.h"  #define ROWS_PER_HAND (MATRIX_ROWS / 2) +#define SYNC_TIMER_OFFSET 2  #ifdef RGBLIGHT_ENABLE  #    include "rgblight.h" @@ -27,8 +28,20 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;  #    include "i2c_slave.h"  typedef struct _I2C_slave_buffer_t { +#    ifndef DISABLE_SYNC_TIMER +    uint32_t sync_timer; +#    endif      matrix_row_t smatrix[ROWS_PER_HAND]; -    uint8_t      backlight_level; +#    ifdef SPLIT_MODS_ENABLE +    uint8_t real_mods; +    uint8_t weak_mods; +#        ifndef NO_ACTION_ONESHOT +    uint8_t oneshot_mods; +#        endif +#    endif +#    ifdef BACKLIGHT_ENABLE +    uint8_t backlight_level; +#    endif  #    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)      rgblight_syncinfo_t rgblight_sync;  #    endif @@ -42,9 +55,13 @@ typedef struct _I2C_slave_buffer_t {  static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; +#    define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer) +#    define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix) +#    define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods) +#    define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods) +#    define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)  #    define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)  #    define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) -#    define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)  #    define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)  #    define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) @@ -91,10 +108,43 @@ bool transport_master(matrix_row_t matrix[]) {          }      }  #    endif + +#    ifdef SPLIT_MODS_ENABLE +    uint8_t real_mods = get_mods(); +    if (real_mods != i2c_buffer->real_mods) { +        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) { +            i2c_buffer->real_mods = real_mods; +        } +    } + +    uint8_t weak_mods = get_weak_mods(); +    if (weak_mods != i2c_buffer->weak_mods) { +        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) { +            i2c_buffer->weak_mods = weak_mods; +        } +    } + +#        ifndef NO_ACTION_ONESHOT +    uint8_t oneshot_mods = get_oneshot_mods(); +    if (oneshot_mods != i2c_buffer->oneshot_mods) { +        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) { +            i2c_buffer->oneshot_mods = oneshot_mods; +        } +    } +#        endif +#    endif + +#    ifndef DISABLE_SYNC_TIMER +    i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; +    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT); +#    endif      return true;  }  void transport_slave(matrix_row_t matrix[]) { +#    ifndef DISABLE_SYNC_TIMER +    sync_timer_update(i2c_buffer->sync_timer); +#    endif      // Copy matrix to I2C buffer      memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix)); @@ -118,6 +168,14 @@ void transport_slave(matrix_row_t matrix[]) {  #    ifdef WPM_ENABLE      set_current_wpm(i2c_buffer->current_wpm);  #    endif + +#    ifdef SPLIT_MODS_ENABLE +    set_mods(i2c_buffer->real_mods); +    set_weak_mods(i2c_buffer->weak_mods); +#        ifndef NO_ACTION_ONESHOT +    set_oneshot_mods(i2c_buffer->oneshot_mods); +#        endif +#    endif  }  void transport_master_init(void) { i2c_init(); } @@ -139,11 +197,21 @@ typedef struct _Serial_s2m_buffer_t {  } Serial_s2m_buffer_t;  typedef struct _Serial_m2s_buffer_t { +#    ifdef SPLIT_MODS_ENABLE +    uint8_t  real_mods; +    uint8_t  weak_mods; +#        ifndef NO_ACTION_ONESHOT +    uint8_t  oneshot_mods; +#        endif +#    endif +#    ifndef DISABLE_SYNC_TIMER +    uint32_t sync_timer; +#    endif  #    ifdef BACKLIGHT_ENABLE -    uint8_t backlight_level; +    uint8_t  backlight_level;  #    endif  #    ifdef WPM_ENABLE -    uint8_t current_wpm; +    uint8_t  current_wpm;  #    endif  } Serial_m2s_buffer_t; @@ -249,13 +317,28 @@ bool transport_master(matrix_row_t matrix[]) {  #    ifdef WPM_ENABLE      // Write wpm to slave -    serial_m2s_buffer.current_wpm = get_current_wpm(); +    serial_m2s_buffer.current_wpm  = get_current_wpm(); +#    endif + +#    ifdef SPLIT_MODS_ENABLE +    serial_m2s_buffer.real_mods    = get_mods(); +    serial_m2s_buffer.weak_mods    = get_weak_mods(); +#        ifndef NO_ACTION_ONESHOT +    serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); +#        endif +#    endif +#    ifndef DISABLE_SYNC_TIMER +    serial_m2s_buffer.sync_timer   = sync_timer_read32() + SYNC_TIMER_OFFSET;  #    endif      return true;  }  void transport_slave(matrix_row_t matrix[]) {      transport_rgblight_slave(); +#    ifndef DISABLE_SYNC_TIMER +    sync_timer_update(serial_m2s_buffer.sync_timer); +#    endif +      // TODO: if MATRIX_COLS > 8 change to pack()      for (int i = 0; i < ROWS_PER_HAND; ++i) {          serial_s2m_buffer.smatrix[i] = matrix[i]; @@ -271,6 +354,14 @@ void transport_slave(matrix_row_t matrix[]) {  #    ifdef WPM_ENABLE      set_current_wpm(serial_m2s_buffer.current_wpm);  #    endif + +#    ifdef SPLIT_MODS_ENABLE +    set_mods(serial_m2s_buffer.real_mods); +    set_weak_mods(serial_m2s_buffer.weak_mods); +#        ifndef NO_ACTION_ONESHOT +    set_oneshot_mods(serial_m2s_buffer.oneshot_mods); +#        endif +#    endif  }  #endif | 
