Mechanical keyboard for teletype?

@xenus_dad we can try a couple of things, i’ll pm you with a test firmware. just to test a theory for now, i will need to read up on how HID is implemented, specifically for keyboards as i’m not familiar with that area.

I also have key drop issues on my Vortex Race 3. I’d be willing to help test!

teletype.hex (549.4 KB)
teletype.zip (162.2 KB)

can you give this version a try? this is 3.0 RC5 but with increased frequency of polling for keyboard updates.

6 Likes

I’ll give this a shot today/tomorrow as well. I have the Race 3 and also have key drops.
Should have come here before ordering a different mech keyboard LOL

1 Like

For me, this is better. I still drop some keys, but they drop less frequently.

Do you mind sharing what you adjusted? Does it have other potential performance impacts?

Thanks again for taking a look at this!

1 Like

so what i changed was how frequently it checks for HID events, this line:

in the version i posted above i changed to 20 (so it will pull for HID updates every 20ms instead of every 47ms).

while this particular timer callback doesn’t do much (unless there was a key press or release) i’m reluctant to increase the frequency as it can potentially affect performance. also the fact that the issue only seems to happen with that particular keyboard… i have a feeling something else is going on.

it would be interesting to play with the frequency though, since you have the toolchain set up try reducing the number further and see if at some point you don’t get dropped keys at all.

i have another idea to try, i’ll post another version today or tomorrow.

1 Like

Indeed, I’ll play with this and report if it helps the problem at hand (totally understand about performance and that this would be strictly diagnostic).

2 Likes

there is just a fundamental race condition here. we only store the most recent HID frame and we read that frame value at a limited rate. we can increase that rate but will always be able to drop frames if they come in fast enough.

it’s entirely possible that the Race 3 sends multiple HID frames on every keypress to avoid ghosting (or something.) this might be most easily diagnosed by using hexdump or evtest with the device on linux.

the only solution would be to maintain a queue of incoming HID data, instead of a single value and dirty-flag.

i know mechanical keyboards are cool and all, but honestly this system (HID driver libavr32) was never designed to handle rapid typing - it was added to aleph codebase almost as an afterthought.

if it sends multiple frames wouldn’t they be identical? looking at hid.c it looks like it will only raise dirty flag if the new frame is different.

my other thought was related to this line:

i assume a frame can contain multiple key presses. the above loop will process every key in a frame - except when there is a key release in which case it breaks out of the loop. my thought was - if the same frame contains a key release and another key press then is it possible that the latter might get dropped?

2 Likes

Thats also possible. I was thinking like maybe it sends the entire keyboard state every time (more than 32b), or something. I don’t know a lot about fancy keyboards so this is just a random guess. Should be easy to find out though.

I use a WASD CODE which I think has some “high bandwidth” mode switch. will take a look in case is revealing

Anyway current polling approach in libavr32 has fundamental issues regardless of the exact form that the race condition takes

1 Like

(or for that matter, in my case I could be compiling development-of-scripts firmware for myself with faster polling so I can type correctly and performance firmware that restores normal polling at the expense of dropped keys. Long live FOSS.

That said really appreciate that you’re taking any time to look at this at all. Thank you!)

2 Likes

Found some time to test this today. 20ms is better for me than the default 47, but I still drop keys. 15 and 10 are both very usable, though I still drop the occasional key. 5 actually seemed worse to me than 10, though my testing wasn’t exactly scientific.

I may just do custom firmware builds for myself of whatever is the current firmware so I can use the keyboard. The mechanical is nice, and since I’ve paid for it I’d like to use it, but being able to use Dvorak with Teletype is a real win for me personally (my keyboard has Dvorak/Colemak modes settable via DIP switch).

1 Like

omg typing Colemak on Teletype would be nice, so it doesn’t interfere with my muscle memory… maybe I’ll look into this

1 Like

It’s a bit confusing because right now my Teletype muscle memory is hunt and peck Qwerty and I have to unlearn that now :slight_smile:

1 Like

thanks for testing this! i’ll send you another version to try (with the fix i described above).

1 Like

can you give this version a try? including modified main.c as well so you can see the change.

main.c (28.7 KB)
teletype.hex (549.4 KB)

2 Likes

ah this makes sense! It did seem like there were times where if I pressed the keys really fast multiple key strokes would populate the screen at the same time.

In other words, ASDF typed in super quick succession would sometimes populate the screen visually as A…S…DF.

I’m assuming that the buffer is appended to, and processed first-in, first-out, right? Only thing I can think of that I didn’t test very thoroughly is that the keys come in the order they are pressed.

keyboard HID protocol is a bit weird. updates gets sent in frames, iirc for keyboard a frame always consists of 8 bytes, byte 0 is a bitmask for modifiers (alt/shift/ctrl), byte 1 is reserved and the rest is for key presses / releases. for presses you know what key was pressed but for releases it’s just 0, so you have to compare to the previous frame to know which key was released. also i don’t remember if the order within a frame is guaranteed (i imagine it’s maintained though, otherwise it’d be really weird…)

word, sounds good, I can keep a check on it and see if I ever get any out of order-ness or any sort of weird behavior and let you know!

Would it be possible to build this fix and rebase off of 3.0.0 (or is this build basically that and there’s no real reason to)?

1 Like

pretty sure it should have everything from 3.0 but i’ll make a new build tonight just in case and will post it here.

1 Like