~ruther/qmk_firmware

d5eb673426230a87be229219127c2f553c7fd8f2 — Hugues Morisset 4 years ago 20589fb
[Keyboard] Interlace matrix scan for performance on Moonlander (#13625)

1 files changed, 82 insertions(+), 76 deletions(-)

M keyboards/moonlander/matrix.c
M keyboards/moonlander/matrix.c => keyboards/moonlander/matrix.c +82 -76
@@ 129,10 129,29 @@ void matrix_init(void) {
uint8_t matrix_scan(void) {
    bool changed = false;

    // Try to re-init right side
    if (!mcp23018_initd) {
        if (++mcp23018_reset_loop == 0) {
            // if (++mcp23018_reset_loop >= 1300) {
            // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
            // this will be approx bit more frequent than once per second
            print("trying to reset mcp23018\n");
            mcp23018_init();
            if (!mcp23018_initd) {
                print("left side not responding\n");
            } else {
                print("left side attached\n");
#ifdef RGB_MATRIX_ENABLE
                rgb_matrix_init();
#endif
            }
        }
    }

    matrix_row_t data = 0;
    // actual matrix
    for (uint8_t row = 0; row < ROWS_PER_HAND; row++) {
        // strobe row
    for (uint8_t row = 0; row <= ROWS_PER_HAND; row++) {
       // strobe row
        switch (row) {
            case 0: writePinHigh(B10); break;
            case 1: writePinHigh(B11); break;


@@ 140,94 159,81 @@ uint8_t matrix_scan(void) {
            case 3: writePinHigh(B13); break;
            case 4: writePinHigh(B14); break;
            case 5: writePinHigh(B15); break;
            case 6: break; // Left hand has 6 rows
        }

        // need wait to settle pin state
        matrix_io_delay();

        // read col data
        data = (
            (readPin(A0) << 0 ) |
            (readPin(A1) << 1 ) |
            (readPin(A2) << 2 ) |
            (readPin(A3) << 3 ) |
            (readPin(A6) << 4 ) |
            (readPin(A7) << 5 ) |
            (readPin(B0) << 6 )
        );

        // unstrobe  row
        switch (row) {
            case 0: writePinLow(B10); break;
            case 1: writePinLow(B11); break;
            case 2: writePinLow(B12); break;
            case 3: writePinLow(B13); break;
            case 4: writePinLow(B14); break;
            case 5: writePinLow(B15); break;
        }

        if (matrix_debouncing[row] != data) {
            matrix_debouncing[row] = data;
            debouncing             = true;
            debouncing_time        = timer_read();
            changed                = true;
        }
    }

    for (uint8_t row = 0; row <= ROWS_PER_HAND; row++) {
        // right side

        if (!mcp23018_initd) {
            if (++mcp23018_reset_loop == 0) {
                // if (++mcp23018_reset_loop >= 1300) {
                // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
                // this will be approx bit more frequent than once per second
                print("trying to reset mcp23018\n");
                mcp23018_init();
                if (!mcp23018_initd) {
                    print("left side not responding\n");
                } else {
                    print("left side attached\n");
#ifdef RGB_MATRIX_ENABLE
                    rgb_matrix_init();
#endif
                }
        if (mcp23018_initd) {
            // #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 }       outputs
            // #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 } inputs

            // select row
            mcp23018_tx[0] = 0x12;                                                                   // GPIOA
            mcp23018_tx[1] = (0b01111111 & ~(1 << (row))) | ((uint8_t)!mcp23018_leds[2] << 7);       // activate row
            mcp23018_tx[2] = ((uint8_t)!mcp23018_leds[1] << 6) | ((uint8_t)!mcp23018_leds[0] << 7);  // activate row

            if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, I2C_TIMEOUT)) {
                dprintf("error hori\n");
                mcp23018_initd = false;
            }
        }

        // #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 }       outputs
        // #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 } inputs
            // read col

        // select row

        mcp23018_tx[0] = 0x12;                                                                   // GPIOA
        mcp23018_tx[1] = (0b01111111 & ~(1 << (row))) | ((uint8_t)!mcp23018_leds[2] << 7);       // activate row
        mcp23018_tx[2] = ((uint8_t)!mcp23018_leds[1] << 6) | ((uint8_t)!mcp23018_leds[0] << 7);  // activate row

        if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, I2C_TIMEOUT)) {
            dprintf("error hori\n");
            mcp23018_initd = false;
        }
            mcp23018_tx[0] = 0x13;  // GPIOB
            if (MSG_OK != i2c_readReg(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx[0], &mcp23018_rx[0], 1, I2C_TIMEOUT)) {
                dprintf("error vert\n");
                mcp23018_initd = false;
            }

        // read col
            data = ~(mcp23018_rx[0] & 0b00111111);
            // data = 0x01;

        mcp23018_tx[0] = 0x13;  // GPIOB
        if (MSG_OK != i2c_readReg(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx[0], &mcp23018_rx[0], 1, I2C_TIMEOUT)) {
            dprintf("error vert\n");
            mcp23018_initd = false;
            if (matrix_debouncing_right[row] != data) {
                matrix_debouncing_right[row] = data;
                debouncing_right             = true;
                debouncing_time_right        = timer_read();
                changed                      = true;
            }
        }

        data = ~(mcp23018_rx[0] & 0b00111111);
        // data = 0x01;
        // left side
        if (row < ROWS_PER_HAND) {
            // i2c comm incur enough wait time
            if (!mcp23018_initd) {
                // need wait to settle pin state
                matrix_io_delay();
            }
            // read col data
            data = (
                (readPin(A0) << 0 ) |
                (readPin(A1) << 1 ) |
                (readPin(A2) << 2 ) |
                (readPin(A3) << 3 ) |
                (readPin(A6) << 4 ) |
                (readPin(A7) << 5 ) |
                (readPin(B0) << 6 )
            );
            // unstrobe  row
            switch (row) {
                case 0: writePinLow(B10); break;
                case 1: writePinLow(B11); break;
                case 2: writePinLow(B12); break;
                case 3: writePinLow(B13); break;
                case 4: writePinLow(B14); break;
                case 5: writePinLow(B15); break;
                case 6: break;
            }

        if (matrix_debouncing_right[row] != data) {
            matrix_debouncing_right[row] = data;
            debouncing_right             = true;
            debouncing_time_right        = timer_read();
            changed                      = true;
            if (matrix_debouncing[row] != data) {
                matrix_debouncing[row] = data;
                debouncing             = true;
                debouncing_time        = timer_read();
                changed                = true;
            }
        }
    }

    // Debounce both hands
    if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
        for (int row = 0; row < ROWS_PER_HAND; row++) {
            matrix[row] = matrix_debouncing[row];