271 lines
5.5 KiB
C
271 lines
5.5 KiB
C
#include "quantum.h"
|
|
#include "print.h"
|
|
|
|
/*
|
|
- A & B chooses which demux to use
|
|
- C, D & E are used for choosing column
|
|
|
|
SN54LS139AN
|
|
|
|
2G = always low (enabled)
|
|
A B -> H G F
|
|
0 0 0 1 1
|
|
0 1 1 0 1
|
|
1 0 1 1 0
|
|
1 1 1 1 1
|
|
|
|
1G = F (high disables)
|
|
D E -> K J I
|
|
0 0 0 1 1
|
|
0 1 1 0 1
|
|
1 0 1 1 0
|
|
1 1 1 1 1
|
|
|
|
SN54LS139AN feeds 215N_A (G) and 215N_B (H)
|
|
|
|
215N_A (G high disables)
|
|
|
|
G C D E -> S R Q P O N M L
|
|
0 0 0 0 0 1 1 1 1 1 1 1
|
|
0 0 0 1 1 0 1 1 1 1 1 1
|
|
0 0 1 0 1 1 0 1 1 1 1 1
|
|
0 0 1 1 1 1 1 0 1 1 1 1
|
|
0 1 0 0 1 1 1 1 0 1 1 1
|
|
0 1 0 1 1 1 1 1 1 0 1 1
|
|
0 1 1 0 1 1 1 1 1 1 0 1
|
|
0 1 1 1 1 1 1 1 1 1 1 0
|
|
1 X X X 1 1 1 1 1 1 1 1
|
|
|
|
215N_B (H high disables)
|
|
|
|
H C D E -> Ö Ä Å Z Y V U T
|
|
0 0 0 0 0 1 1 1 1 1 1 1
|
|
0 0 0 1 1 0 1 1 1 1 1 1
|
|
0 0 1 0 1 1 0 1 1 1 1 1
|
|
0 0 1 1 1 1 1 0 1 1 1 1
|
|
0 1 0 0 1 1 1 1 0 1 1 1
|
|
0 1 0 1 1 1 1 1 1 0 1 1
|
|
0 1 1 0 1 1 1 1 1 1 0 1
|
|
0 1 1 1 1 1 1 1 1 1 1 0
|
|
1 X X X 1 1 1 1 1 1 1 1
|
|
*/
|
|
|
|
// Column selection pins
|
|
#define COL_A F7
|
|
#define COL_B F6
|
|
#define COL_C F5
|
|
#define COL_D F4
|
|
#define COL_E F1
|
|
|
|
// Read pins
|
|
#define RD_A C6
|
|
#define RD_B D7
|
|
#define RD_C E6
|
|
#define RD_D B4
|
|
#define RD_E B5
|
|
#define RD_F B6
|
|
#define RD_G B7
|
|
#define RD_H D6
|
|
|
|
#define D139_START 0
|
|
#define D139_PINS 3
|
|
|
|
#define D215_A_START D139_PINS
|
|
#define D215_A_PINS 8
|
|
#define D215_B_START D215_A_START + D215_A_PINS
|
|
#define D215_B_PINS 8
|
|
|
|
enum Demux {
|
|
// SN54LS139AN
|
|
D139,
|
|
// SN74LS145N (first)
|
|
D215_A,
|
|
// SN74LS145N (second)
|
|
D215_B,
|
|
// All scanned
|
|
END
|
|
};
|
|
|
|
static uint8_t current_col[MATRIX_ROWS];
|
|
|
|
enum Demux next_demux(enum Demux current_demux) {
|
|
switch (current_demux) {
|
|
case D139: return D215_A;
|
|
case D215_A: return D215_B;
|
|
default: return END;
|
|
}
|
|
}
|
|
|
|
void select_demux(enum Demux demux) {
|
|
switch (demux) {
|
|
case D139:
|
|
writePinHigh(COL_A);
|
|
writePinLow(COL_B);
|
|
break;
|
|
case D215_A:
|
|
writePinLow(COL_A);
|
|
writePinHigh(COL_B);
|
|
break;
|
|
case D215_B:
|
|
writePinLow(COL_A);
|
|
writePinLow(COL_B);
|
|
default:
|
|
// This will never happen, trust me bro
|
|
return;
|
|
}
|
|
}
|
|
|
|
uint8_t readMatrixPin(pin_t pin) {
|
|
return (readPin(pin) == 0) ? 0 : 1;
|
|
}
|
|
|
|
void readPins(uint8_t out[]) {
|
|
out[0] = readMatrixPin(RD_A);
|
|
out[1] = readMatrixPin(RD_B) << 1;
|
|
out[2] = readMatrixPin(RD_C) << 2;
|
|
out[3] = readMatrixPin(RD_D) << 3;
|
|
out[4] = readMatrixPin(RD_E) << 4;
|
|
out[5] = readMatrixPin(RD_F) << 5;
|
|
out[6] = readMatrixPin(RD_G) << 6;
|
|
out[7] = readMatrixPin(RD_H) << 7;
|
|
}
|
|
|
|
bool readColumn(matrix_row_t current_matrix[], uint8_t col) {
|
|
bool changed = false;
|
|
|
|
readPins(current_col);
|
|
for (uint8_t r = 0; r < MATRIX_ROWS; ++r) {
|
|
uint8_t old_val = (current_matrix[r] >> col) & 0x1;
|
|
uint8_t new_val = current_col[r];
|
|
|
|
if (old_val != new_val) {
|
|
changed = true;
|
|
if (new_val == 1) {
|
|
current_matrix[r] |= (1U << col);
|
|
} else {
|
|
current_matrix[r] &= ~(1U << col);
|
|
}
|
|
}
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
bool scan_d139(matrix_row_t current_matrix[]) {
|
|
bool changed = false;
|
|
|
|
for (uint8_t i = D139_START; i < D139_PINS; ++i) {
|
|
if (i == 0) {
|
|
writePinLow(COL_D);
|
|
writePinLow(COL_E);
|
|
} else if (i == 1) {
|
|
writePinLow(COL_D);
|
|
writePinHigh(COL_E);
|
|
} else {
|
|
writePinHigh(COL_D);
|
|
writePinLow(COL_E);
|
|
}
|
|
|
|
wait_us(5);
|
|
changed = readColumn(current_matrix, i) || changed;
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
bool scan_d215(matrix_row_t current_matrix[], uint8_t col_start, uint8_t pins) {
|
|
bool changed = false;
|
|
|
|
for (uint8_t i = col_start; i < pins; ++i) {
|
|
uint8_t local_i = i - col_start;
|
|
|
|
if (local_i & 0x1) {
|
|
writePinHigh(COL_E);
|
|
} else {
|
|
writePinLow(COL_E);
|
|
}
|
|
|
|
if (local_i & 0x2) {
|
|
writePinHigh(COL_D);
|
|
} else {
|
|
writePinLow(COL_D);
|
|
}
|
|
|
|
if (local_i & 0x4) {
|
|
writePinHigh(COL_C);
|
|
} else {
|
|
writePinLow(COL_C);
|
|
}
|
|
|
|
wait_us(5);
|
|
changed = readColumn(current_matrix, i) || changed;
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
bool scan_d215_a(matrix_row_t current_matrix[]) {
|
|
return scan_d215(current_matrix, D215_A_START, D215_A_PINS);
|
|
}
|
|
|
|
bool scan_d215_b(matrix_row_t current_matrix[]) {
|
|
return scan_d215(current_matrix, D215_B_START, D215_B_PINS);
|
|
}
|
|
|
|
bool scan_demux(matrix_row_t current_matrix[], enum Demux demux) {
|
|
switch (demux) {
|
|
case D139: return scan_d139(current_matrix);
|
|
case D215_A: return scan_d215_a(current_matrix);
|
|
case D215_B: return scan_d215_b(current_matrix);
|
|
default: return false;
|
|
}
|
|
}
|
|
|
|
void matrix_init_custom(void) {
|
|
setPinInputHigh(RD_A);
|
|
setPinInputHigh(RD_B);
|
|
setPinInputHigh(RD_C);
|
|
setPinInputHigh(RD_D);
|
|
setPinInputHigh(RD_E);
|
|
setPinInputHigh(RD_F);
|
|
setPinInputHigh(RD_G);
|
|
setPinInputHigh(RD_H);
|
|
|
|
setPinOutput(COL_A);
|
|
setPinOutput(COL_B);
|
|
setPinOutput(COL_C);
|
|
setPinOutput(COL_D);
|
|
setPinOutput(COL_E);
|
|
|
|
writePinLow(COL_A);
|
|
writePinLow(COL_B);
|
|
writePinLow(COL_C);
|
|
writePinLow(COL_D);
|
|
writePinLow(COL_E);
|
|
|
|
wait_us(20);
|
|
print("Init finished\n");
|
|
}
|
|
|
|
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
|
|
static uint16_t counter = 0;
|
|
bool matrix_has_changed = false;
|
|
|
|
enum Demux active_demux = D139;
|
|
|
|
++counter;
|
|
|
|
do {
|
|
select_demux(active_demux);
|
|
matrix_has_changed = scan_demux(current_matrix, active_demux) || matrix_has_changed;
|
|
|
|
if (counter % 1000 == 0) {
|
|
printf("Checking demux %d, %i\n", active_demux, matrix_has_changed);
|
|
counter = 0;
|
|
}
|
|
|
|
active_demux = next_demux(active_demux);
|
|
} while (active_demux != END);
|
|
|
|
return matrix_has_changed;
|
|
}
|