diff --git a/StenoFW.ino b/StenoFW.ino old mode 100755 new mode 100644 index b5b8166..ebb4201 --- a/StenoFW.ino +++ b/StenoFW.ino @@ -45,6 +45,11 @@ unsigned long debouncingMicros[ROWS][COLS]; // Other state variables int ledIntensity = 1; // Min 0 - Max 255 +// Protocol state +#define GEMINI 0 +#define TXBOLT 1 +int protocol = GEMINI; + // This is called when the keyboard is connected void setup() { Serial.begin(9600); @@ -152,27 +157,12 @@ void readKeys() { digitalWrite(rowPins[i], HIGH); } } - -// Send current chord over serial using the Gemini protocol. If there are fn keys -// pressed, delegate to the corresponding function instead. -// In future versions, there should also be a way to handle fn keys presses before -// they are released, eg. for mouse emulation functionality or custom key presses. -void sendChord() { + +// Send current chord over serial using the Gemini protocol. +void sendChordGemini() { // Initialize chord bytes byte chordBytes[] = {B10000000, B0, B0, B0, B0, B0}; - // If fn keys have been pressed, delegate to corresponding method and return - if (currentChord[0][5] && currentChord[1][5]) { - fn1fn2(); - return; - } else if (currentChord[0][5]) { - fn1(); - return; - } else if (currentChord[1][5]) { - fn2(); - return; - } - // Byte 0 if (currentChord[2][4]) { chordBytes[0] = B10000001; @@ -260,14 +250,117 @@ void sendChord() { } } +void sendChordTxBolt() { + byte chordBytes[] = {B0, B0, B0, B0, B0}; + int index = 0; + + // TX Bolt uses a variable length packet. Only those bytes that have active + // keys are sent. The header bytes indicate which keys are being sent. They + // must be sent in order. It is a good idea to send a zero after every packet. + // 00XXXXXX 01XXXXXX 10XXXXXX 110XXXXX + // HWPKTS UE*OAR GLBPRF #ZDST + + // byte 1 + // S- + if (currentChord[0][0] || currentChord[1][0]) chordBytes[0] += B00000001; + // T- + if (currentChord[0][1]) chordBytes[index] += B00000010; + // K- + if (currentChord[1][1]) chordBytes[index] += B00000100; + // P- + if (currentChord[0][2]) chordBytes[index] += B00001000; + // W- + if (currentChord[1][2]) chordBytes[index] += B00010000; + // H- + if (currentChord[0][3]) chordBytes[index] += B00100000; + // Increment the index if the current byte has any keys set. + if (chordBytes[index]) index++; + + // byte 2 + // R- + if (currentChord[1][3]) chordBytes[index] += B01000001; + // A + if (currentChord[2][0]) chordBytes[index] += B01000010; + // O + if (currentChord[2][1]) chordBytes[index] += B01000100; + // * + if (currentChord[0][4] || currentChord[1][4]) chordBytes[index] += B01001000; + // E + if (currentChord[2][2]) chordBytes[index] += B01010000; + // U + if (currentChord[2][3]) chordBytes[index] += B01100000; + // Increment the index if the current byte has any keys set. + if (chordBytes[index]) index++; + + // byte 3 + // -F + if (currentChord[3][0]) chordBytes[index] += B10000001; + // -R + if (currentChord[4][0]) chordBytes[index] += B10000010; + // -P + if (currentChord[3][1]) chordBytes[index] += B10000100; + // -B + if (currentChord[4][1]) chordBytes[index] += B10001000; + // -L + if (currentChord[3][2]) chordBytes[index] += B10010000; + // -G + if (currentChord[4][2]) chordBytes[index] += B10100000; + // Increment the index if the current byte has any keys set. + if (chordBytes[index]) index++; + + // byte 4 + // -T + if (currentChord[3][3]) chordBytes[index] += B11000001; + // -S + if (currentChord[4][3]) chordBytes[index] += B11000010; + // -D + if (currentChord[3][4]) chordBytes[index] += B11000100; + // -Z + if (currentChord[4][3]) chordBytes[index] += B11001000; + // # + if (currentChord[2][4]) chordBytes[index] += B11010000; + // Increment the index if the current byte has any keys set. + if (chordBytes[index]) index++; + + // Now we have index bytes followed by a zero byte where 0 < index <= 4. + index++; // Increment index to include the trailing zero byte. + for (int i = 0; i < index; i++) { + Serial.write(chordBytes[i]); + } +} + +// Send the chord using the current protocol. If there are fn keys +// pressed, delegate to the corresponding function instead. +// In future versions, there should also be a way to handle fn keys presses before +// they are released, eg. for mouse emulation functionality or custom key presses. +void sendChord() { + // If fn keys have been pressed, delegate to corresponding method and return + if (currentChord[0][5] && currentChord[1][5]) { + fn1fn2(); + return; + } else if (currentChord[0][5]) { + fn1(); + return; + } else if (currentChord[1][5]) { + fn2(); + return; + } + + if (protocol == GEMINI) { + sendChordGemini(); + } else { + sendChordTxBolt(); + } +} + // This function is called when only "fn1" key has been pressed. void fn1() { - + protocol = GEMINI; } // This function is called when only "fn2" key has been pressed. void fn2() { - + protocol = TXBOLT; } // This function is called when both "fn1" and "fn1" key has been pressed.