Well, I did the following before reading suicidal_orange's post. Turns out it worked!
@suicidal_orange: Arduinos are fast enough to do this if you do it right, as I describe below. Also I have a hot air reflow iron, I'm not taking a flame to this board when I eventually take the cypress chip off.
STM32 boards won't usually work for this as they aren't 5V tolerant.
I did originally want to do this with my Arduino mega 2560, but something's gone funky with it and I don't feel like wasting time figuring it out. I can program it with Atmel Studio and an Atmel ICE programmer through ICSP and/or JTAG, and I tested loopback on the onboard usb-serial chip and that works. Basic IO stuff like setting pins high and low works. However, whenever I try to set up any of the USART peripherals, it doesn't work. Setting one of the USART settings registers makes it hardfault, and I can't figure out why. Maybe the guy who had this thing before me managed to blow up only a tiny part of the chip without frying the rest of it. Instead I did this in two stages with an ordinary arduino.
First, I connected the row bodge wires to the arduino and ran this program I wrote, to report through serial which row was pushed when I held down a key:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
}
bool keypushed = false;
void loop() {
//rows - 5V normally, go down to 0V when triggered
if(!digitalRead(4)){
Serial.println("8");
keypushed = true;
}
else if(!digitalRead(5)){
Serial.println("9");
keypushed = true;
}
else if(!digitalRead(6)){
Serial.println("10");
keypushed = true;
}
else if(!digitalRead(8)){
Serial.println("39");
keypushed = true;
}
else if(!digitalRead(9)){
Serial.println("40");
keypushed = true;
}
else if(!digitalRead(10)){
Serial.println("41");
keypushed = true;
}
else if(!digitalRead(11)){
Serial.println("42");
keypushed = true;
}
else if(!digitalRead(3)){
Serial.println("7");
keypushed = true;
}
if(keypushed == true){
digitalWrite(13, HIGH);
delay(250);
digitalWrite(13, LOW);
keypushed = false;
}
}
Using python, I generated a list of keys, and using the serial interface, recorded which key corresponded to which row. The program prompts me to push a key (eg: "KC_ESC") then listens for which row pin is triggered on the arduino, and records the reported row.
keydf = pd.read_csv('keylist.csv')
coltemp = []
for index, value in keydf['key list'].items():
print(value)
ser.flushInput()
val = int(ser.readline().rstrip())
print(val)
coltemp.append(val)
keydf['column'] = coltemp
keydf.to_csv('keylist_columns.csv', index=False)
Then I disconnected the row lines, connected the column lines, uploaded the following code to the arduino, and ran the following python bit to figure out the column numbers:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//Serial.println("hi");
pinMode(13, OUTPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
}
bool keypushed = false;
void loop() {
//columns - 5V normally, go down to 0V when triggered
if(digitalRead(2)){
Serial.println("35");
keypushed = true;
}
else if(digitalRead(4)){
Serial.println("12");
keypushed = true;
}
else if(digitalRead(5)){
Serial.println("37");
keypushed = true;
}
else if(digitalRead(6)){
Serial.println("18");
keypushed = true;
}
else if(digitalRead(7)){
Serial.println("17");
keypushed = true;
}
else if(digitalRead(8)){
Serial.println("29");
keypushed = true;
}
else if(digitalRead(9)){
Serial.println("31");
keypushed = true;
}
else if(digitalRead(10)){
Serial.println("19");
keypushed = true;
}
else if(digitalRead(11)){
Serial.println("30");
keypushed = true;
}
else if(digitalRead(12)){
Serial.println("20");
keypushed = true;
}
else if(digitalRead(A0)){
Serial.println("14");
keypushed = true;
}
else if(digitalRead(A1)){
Serial.println("32");
keypushed = true;
}
else if(digitalRead(A2)){
Serial.println("38");
keypushed = true;
}
else if(digitalRead(A3)){
Serial.println("36");
keypushed = true;
}
else if(digitalRead(A4)){
Serial.println("13");
keypushed = true;
}
else if(digitalRead(A5)){
Serial.println("11");
keypushed = true;
}
if(keypushed == true){
digitalWrite(13, HIGH);
delay(250);
digitalWrite(13, LOW);
keypushed = false;
}
}
keydf = pd.read_csv('keylist_columns.csv')
rowtemp = []
for index, value in keydf['key list'].items():
print(value)
ser.flushInput();
val = int(ser.readline().rstrip())
print(val)
rowtemp.append(val)
keydf['row'] = rowtemp
keydf.to_csv('keylist_both.csv', index=False)
Now I have a list of what key codes correspond to what row and column lines (in terms of pin numbers on the Cypress chip). See:
https://pastebin.com/raw/k45zsZxTThis needs to be translated to 0->7 rows and 0->15 columns.
keydf = pd.read_csv('keylist_both.csv')
rows = [7,8,9,10,39,40,41,42]
for i,elem in enumerate(rows):
keydf['row'].replace(elem, i, inplace=True)
columns = [11,12,13,14,17,18,19,20,29,30,31,32,35,36,37,38]
for i, elem in enumerate(columns):
keydf['column'].replace(elem, i, inplace=True)
keydf.to_csv('keylist_renumbered.csv', index=False)
This can be converted to a "key grid" that can be easily formed into a QMK-compatible keyboard format:
#convert from key list to key grid
keydf = pd.read_csv('keylist_renumbered.csv')
matrix = np.empty((8,16), dtype=object)
for index, elem in keydf.iterrows():
i = elem['row']
j = elem['column']
matrix[i][j] = elem['key list']
#add KC_NO
matrix[matrix == None] = 'KC_NO'
#export
a = pd.DataFrame(matrix)
a.to_csv('qmk_matrix.csv', index=False, header=False)
Now we have a QMK-style key matrix that works with the ridiculously convoluted routing on the stock PCB. You can find it at:
https://pastebin.com/raw/1mWe4GfA