Close

Keyboard scanning code working

A project log for Scraptop

Laptop made out of scrap - Combined with a FairPhone2 a possible step in the journey toward a fair laptop.

RonaldRonald 11/01/2017 at 20:500 Comments

tthi liinee i  ttypeed ith the nyhkbd

New zip file

So, we improved a bit, looking to the sentence above. :-) Still not all wires connected. New zip file containing the source code is uploaded. No proper license is in place yet, but please consider it GPL for now.

Key repeat challenges

Speed is well now, however, some keys still repeat. I need to investigate why. It seems that in USB HID, the keyboard is responsible for managing long key presses. If I don't send a '0'-report, the computer sometimes thinks the key keeps on repeating. If I don't send a '0'-report very quickly after sending the initial key report, I get multiple keys. So if I want 'standard' behaviour (long press does: for about the first half a second 1 key report, then continuous key reports until key unpressed. Of course all debounced).

I think I implemented code for the first part (1 key report, then stop). However, this works well for the u, y, h, and not for the tttttttttt, iii, ffffffff, for example. Needs some further investigation...

Code generation

For speed purposes I didn't create a for loop with complex logic for the scanning code, but multiple blocks of almost similar code. Because typing this is a bad idea, I created a code generation tool. As seen in an earlier blog I started out on Python. However, I didn't realize that after working for 364 days as a professional Java developer, my Java is much better than my Python nowadays. So I switched. Still don't know a lot about java's weird class path thingies while running from the command line, but I created a run.sh file in the zip that works.

Furthermore, the key table is automatically converted to HID codes. So from:

,"B4","B5","C0","C1","C2","C3","C4","C5"
"D3","Fn","LeftShift","LeftControl","Left GUI","RightShift","LeftAlt","RightAlt","RightControl"
"D0","ESCAPE","F12","`","Tab","Caps Lock","A",,1
"D1","F3","F2",2,"W","S","X","Z","Q"
"D4","F6",6,5,"R","G","F","V","T"
"D5","F5","F4",4,"E","D","C",,3
"D6","F7",8,7,"Y","H","N","B","U"
"B0","F9","F8","I","K","M",",","Spacebar","J"
"B1","F10",9,"O","L",";",".",,"P"
"B2","F11","F12",0,"[","'","/",,"-"
"C6","Scroll Lock","Pause","=",,,,,"]"
"B3","Delete","Insert","Backspace","ENTER","\","PageDown","DownArrow","RightArrow"

to:

char key_matrix[11][8] = 
{
    { 0x00,0xE1,0xE0,0xE3,0xE5,0xE2,0xE6,0xE4},
    { 0x29,0x45,0x35,0x2B,0x39,0x04,0x00,0x1E},
    { 0x3C,0x3B,0x1F,0x1A,0x16,0x1B,0x1D,0x14},
    { 0x3F,0x23,0x22,0x15,0x0A,0x09,0x19,0x17},
    { 0x3E,0x3D,0x21,0x08,0x07,0x06,0x00,0x20},
    { 0x40,0x25,0x24,0x1C,0x0B,0x11,0x05,0x18},
    { 0x42,0x41,0x0C,0x0E,0x10,0x00,0x2C,0x0D},
    { 0x43,0x26,0x12,0x0F,0x33,0x37,0x00,0x13},
    { 0x44,0x45,0x27,0x2F,0x34,0x38,0x00,0x2D},
    { 0x47,0x48,0x2E,0x00,0x00,0x00,0x00,0x30},
    { 0x00,0x49,0x2A,0x28,0x31,0x4E,0x51,0x4F},
};

The scanning code is also generated from the keyboard matrix (the port/pin numbers are being read from the first row / first column of the input file). The scanning code looks like:

char scan() {
    DDRD |= (1 << 3); // set as output
    pins = read_pins();
    if (pins != 8) {
        return key_matrix[0][pins];
    }
    DDRD &= ~(1 << 3); // set as input again

(...)

    DDRB |= (1 << 3); // set as output
    pins = read_pins();
    if (pins != 8) {
        return key_matrix[10][pins];
    }
    DDRB &= ~(1 << 3); // set as input again

    return 0;
}

The generated code is just sent to stdout, but that's good enough for now.

Will keep you posted!

BTW, in an earlier blog I mentioned "I also still have to find out if I used the correct bit fiddling operators, but I think I have it right." Of course I was wrong, it's never first time right. I made all pins output instead of input, and some other small things. Oh well...

Discussions