diff --git a/board.ino b/board.ino index 2322323..17e9cf8 100644 --- a/board.ino +++ b/board.ino @@ -12,6 +12,7 @@ const int dummy = 0; const int ledPin = 13; const uint8_t WIDTH = 6; +const uint8_t FULL_WIDTH = WIDTH * 2; const uint8_t HEIGHT = 4; @@ -26,11 +27,12 @@ void setup() { // initialize the digital pin as an output. pinMode(ledPin, OUTPUT); - digitalWrite(ledPin, HIGH); + digitalWrite(ledPin, LOW); Serial.begin(115200); Serial3.setTX(20); - Serial3.begin(115200); + Serial3.setRX(7); + Serial3.begin(9600); //keyboard.setup(); init_pins(ROW_PINS, COL_PINS); @@ -44,29 +46,35 @@ void loop() while(true) { auto read_keys = read_pressed_keys(ROW_PINS, COL_PINS); +#define IS_SLAVE +#ifdef IS_SLAVE + auto bytes = coords_to_bytes(read_keys); + send_uart_bytes(bytes); + digitalWrite(ledPin, HIGH); + delay(10); +#else + //auto read_keys = read_pressed_keys(ROW_PINS, COL_PINS); + auto read_bytes = read_uart_byte_stream<(WIDTH * HEIGHT)*2 + 1>(); + auto decode_result = decode_coordinates_from_bytes(read_bytes); + if(decode_result.error != CoordsFromBytesError::SUCCESS) + { + Serial.println("Got invalid bytes"); + continue; + } + digitalWrite(ledPin, HIGH); + Serial.println("Doing loop stuff"); + auto other_read_keys = decode_result.keys; auto keymap = init_keymap(default_layout); - auto translated = translate_coordinates(read_keys, keymap); + auto translated = translate_coordinates(other_read_keys, keymap); auto keytypes = keycodes_to_keytypes(translated); auto packet = keytypes_to_packet(keytypes, old_packet); old_packet = packet; - //for(uint8_t i = 0; i < packet.keys.size(); ++i) - //{ - // set_key(i, packet.keys[i]); - //} - //for(uint8_t i = packet.keys.size(); i < KEYS_PER_PACKET; ++i) - //{ - // set_key(i, 0); - //} - //Keyboard.set_modifier(packet.modifiers); - //Keyboard.send_now(); - - //send_packet(packet); - - send_coordinates(read_keys); + send_packet(packet); +#endif } } diff --git a/constants.h b/constants.h index d278fc0..8f3f1c2 100644 --- a/constants.h +++ b/constants.h @@ -3,6 +3,6 @@ #include -const uint8_t KEY_MESSAGE_START = 0xFE; +const uint8_t KEY_MESSAGE_START = 0b10111101; const uint8_t KEY_MESSAGE_END = 0xFF; #endif diff --git a/keyboard_arduino.h b/keyboard_arduino.h index c9db900..abd3215 100644 --- a/keyboard_arduino.h +++ b/keyboard_arduino.h @@ -14,7 +14,6 @@ void init_pins( const BoundedArray col_pins ) { - digitalWrite(13, HIGH); for(uint8_t y = 0; y < HEIGHT; ++y) { pinMode(row_pins[y], OUTPUT); @@ -23,8 +22,6 @@ void init_pins( pinMode(col_pins[x], INPUT_PULLUP); } } - - digitalWrite(13, HIGH); } @@ -60,24 +57,18 @@ BoundedArray read_pressed_keys( void set_key(const uint8_t index, const uint16_t key); void send_packet(const KeyPacket packet); -template -void send_coordinates(const BoundedArray coords) +template +void send_uart_bytes(const BoundedArray bytes) { - //send the start byte + //Write the start byte Serial3.write(KEY_MESSAGE_START); - uint8_t checksum = 0; - - for(size_t i = 0; i < coords.size(); ++i) + for(size_t i = 0; i < bytes.size(); ++i) { - checksum += coords[i].x + coords[i].y; - Serial3.write(coords[i].x); - Serial3.write(coords[i].y); + Serial3.write(bytes[i]); } - //Write the checksum - Serial3.write(checksum); - //Write an end byte Serial3.write(KEY_MESSAGE_END); + Serial3.flush(); } @@ -90,7 +81,7 @@ void send_coordinates(const BoundedArray coords) template BoundedArray read_uart_byte_stream() { - auto received_bytes = BoundedArray(); + auto received_bytes = BoundedArray(); bool done = false; bool is_reading_keys = false; @@ -98,8 +89,11 @@ BoundedArray read_uart_byte_stream() while(!done) { uint8_t new_byte; - while(!Serial3.available()) - {} + while(Serial3.available() < 1) + { + //Serial.println("Waiting for uart"); + } + Serial.println("After loop"); new_byte = Serial3.read(); diff --git a/keyboard_functional.h b/keyboard_functional.h index 12cee0a..beebc4c 100644 --- a/keyboard_functional.h +++ b/keyboard_functional.h @@ -148,7 +148,7 @@ namespace Z result.push(array1[i]); } - for(size_t i = 0; i < array2.size(); i++) + for(size_t i = 0; i < array2.size(); ++i) { result.push(function(array2[i])); } @@ -167,7 +167,7 @@ namespace Z ) { auto result = BoundedArray(); - for(size_t i = 0; i < coordinates.size(); i++) + for(size_t i = 0; i < coordinates.size(); ++i) { result.push(map[coordinates[i].x][coordinates[i].y]); } @@ -268,42 +268,88 @@ namespace Z } + + /* + Translates a list of keyboard coordinates into a list of bytes that can + be sent over UART and decoded by the decode_coordinates_from_bytes function + */ + template + BoundedArray coords_to_bytes( + BoundedArray coords + ) + { + auto result = BoundedArray(); + uint8_t checksum = 0; + for(size_t i = 0; i < coords.size(); ++i) + { + result.push(coords[i].x); + result.push(coords[i].y); + + checksum += coords[i].x + coords[i].y; + } + result.push(checksum); + return result; + } + + + /* + Different things that can go wrong when translating bytes to coordinates + */ enum class CoordsFromBytesError { SUCCESS, INVALID_AMOUNT_OF_BYTES, INVALID_CHECKSUM }; + /* + Result type that is returned when translating bytes to coordinates + */ template - struct FromBytesResult + struct CoordsFromBytesResult { BoundedArray keys; CoordsFromBytesError error; - FromBytesResult(CoordsFromBytesError error) + CoordsFromBytesResult(CoordsFromBytesError error) { this->error = error; } - FromBytesResult(BoundedArray keys) + CoordsFromBytesResult(BoundedArray keys) { this->keys = keys; this->error = CoordsFromBytesError::SUCCESS; } }; + /* + Converts a stream of keyboard bytes into coordinates + */ template - FromBytesResult decode_coordinates_from_bytes( + CoordsFromBytesResult decode_coordinates_from_bytes( BoundedArray bytes ) { + auto result = BoundedArray(); + if(bytes.size() % 2 != 1) { - FromBytesResult(CoordsFromBytesError::INVALID_AMOUNT_OF_BYTES); + return CoordsFromBytesResult(CoordsFromBytesError::INVALID_AMOUNT_OF_BYTES); + } + + uint8_t checksum = 0; + for(uint8_t i = 0; i < (bytes.size() - 1) / 2; ++i) + { + uint8_t index = i * 2; + result.push(KeyCoordinate(bytes[index], bytes[index+1])); + checksum += bytes[index] + bytes[index+1]; } - for(uint8_t i = 0; i < bytes.size() / 2; i++) + + if(checksum != bytes[bytes.size() - 1]) { - + return CoordsFromBytesResult(CoordsFromBytesError::INVALID_CHECKSUM); } + + return result; } } diff --git a/unit.cpp b/unit.cpp index a0dc299..9e231ac 100644 --- a/unit.cpp +++ b/unit.cpp @@ -243,9 +243,61 @@ TEST_CASE("Key message decode", "[key transmission]") auto decoded = decode_coordinates_from_bytes<5>(bytes); + REQUIRE(decoded.error == CoordsFromBytesError::SUCCESS); REQUIRE(decoded.keys.contains(KeyCoordinate(0,0))); REQUIRE(decoded.keys.contains(KeyCoordinate(2,0))); REQUIRE(decoded.keys.contains(KeyCoordinate(0,2))); REQUIRE(decoded.keys.contains(KeyCoordinate(1,1))); REQUIRE(decoded.keys.contains(KeyCoordinate(1,2))); + + //Fewer coordinates than the maximum allowed amount + bytes.reset(); + checksum = 2; + bytes.push(1); + bytes.push(1); + bytes.push(checksum); + + decoded = decode_coordinates_from_bytes<5>(bytes); + + REQUIRE(decoded.error == CoordsFromBytesError::SUCCESS); + REQUIRE(decoded.keys.contains(KeyCoordinate(1,1))); +} + +TEST_CASE("Malformed message decode", "[key transmission]") +{ + { + //Invalid checksum + uint8_t checksum = 1; //should be 2 + uint8_t bytes_raw[3] = {1,1, checksum}; + + auto bytes = BoundedArray(bytes_raw); + auto decoded = decode_coordinates_from_bytes<1>(bytes); + + REQUIRE(decoded.error == CoordsFromBytesError::INVALID_CHECKSUM); + + //Missing checksum + bytes.reset(); + bytes.push(1); + bytes.push(1); + decoded = decode_coordinates_from_bytes<1>(bytes); + REQUIRE(decoded.error == CoordsFromBytesError::INVALID_AMOUNT_OF_BYTES); + } +} + + + +TEST_CASE("Key message encode", "[key transmission]") +{ + auto original_coordinates = BoundedArray(); + original_coordinates.push(KeyCoordinate(3,2)); + original_coordinates.push(KeyCoordinate(3,2)); + //Leaving one empty to test that + + auto decoded = decode_coordinates_from_bytes<3>(coords_to_bytes(original_coordinates)); + + REQUIRE(decoded.error == CoordsFromBytesError::SUCCESS); + for(int i = 0; i < 2; ++i) + { + REQUIRE(original_coordinates[i] == decoded.keys[i]); + } }