Skip to content

Commit

Permalink
Work on inter-keyboard comunicatiom
Browse files Browse the repository at this point in the history
  • Loading branch information
TheZoq2 committed Mar 20, 2017
1 parent 83a2bd2 commit 6cbff28
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 45 deletions.
42 changes: 25 additions & 17 deletions board.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand All @@ -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<WIDTH, HEIGHT>(ROW_PINS, COL_PINS);
Expand All @@ -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<WIDTH * HEIGHT>(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<WIDTH, HEIGHT>(default_layout);

auto translated = translate_coordinates<WIDTH, HEIGHT>(read_keys, keymap);
auto translated = translate_coordinates<WIDTH, HEIGHT>(other_read_keys, keymap);

auto keytypes = keycodes_to_keytypes<WIDTH * HEIGHT>(translated);

auto packet = keytypes_to_packet<WIDTH*HEIGHT>(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
}
}
2 changes: 1 addition & 1 deletion constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

#include <stdint.h>

const uint8_t KEY_MESSAGE_START = 0xFE;
const uint8_t KEY_MESSAGE_START = 0b10111101;
const uint8_t KEY_MESSAGE_END = 0xFF;
#endif
30 changes: 12 additions & 18 deletions keyboard_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ void init_pins(
const BoundedArray<uint8_t, WIDTH> col_pins
)
{
digitalWrite(13, HIGH);
for(uint8_t y = 0; y < HEIGHT; ++y)
{
pinMode(row_pins[y], OUTPUT);
Expand All @@ -23,8 +22,6 @@ void init_pins(
pinMode(col_pins[x], INPUT_PULLUP);
}
}

digitalWrite(13, HIGH);
}


Expand Down Expand Up @@ -60,24 +57,18 @@ BoundedArray<KeyCoordinate, WIDTH*HEIGHT> read_pressed_keys(
void set_key(const uint8_t index, const uint16_t key);
void send_packet(const KeyPacket packet);

template<size_t KEY_AMOUNT>
void send_coordinates(const BoundedArray<KeyCoordinate, KEY_AMOUNT> coords)
template<size_t BYTE_AMOUNT>
void send_uart_bytes(const BoundedArray<uint8_t, BYTE_AMOUNT> 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();
}


Expand All @@ -90,16 +81,19 @@ void send_coordinates(const BoundedArray<KeyCoordinate, KEY_AMOUNT> coords)
template<size_t MAX_RECEIVED_BYTES>
BoundedArray<uint8_t, MAX_RECEIVED_BYTES> read_uart_byte_stream()
{
auto received_bytes = BoundedArray<KeyCoordinate, MAX_RECEIVED_BYTES>();
auto received_bytes = BoundedArray<uint8_t, MAX_RECEIVED_BYTES>();

bool done = false;
bool is_reading_keys = false;

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();

Expand Down
64 changes: 55 additions & 9 deletions keyboard_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]));
}
Expand All @@ -167,7 +167,7 @@ namespace Z
)
{
auto result = BoundedArray<Keycode, WIDTH*HEIGHT>();
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]);
}
Expand Down Expand Up @@ -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<size_t KEY_AMOUNT>
BoundedArray<uint8_t, KEY_AMOUNT * 2 + 1> coords_to_bytes(
BoundedArray<KeyCoordinate, KEY_AMOUNT> coords
)
{
auto result = BoundedArray<uint8_t, KEY_AMOUNT * 2 + 1>();
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<size_t KEY_AMOUNT>
struct FromBytesResult
struct CoordsFromBytesResult
{
BoundedArray<KeyCoordinate, KEY_AMOUNT> keys;
CoordsFromBytesError error;

FromBytesResult(CoordsFromBytesError error)
CoordsFromBytesResult(CoordsFromBytesError error)
{
this->error = error;
}
FromBytesResult(BoundedArray<KeyCoordinate, KEY_AMOUNT> keys)
CoordsFromBytesResult(BoundedArray<KeyCoordinate, KEY_AMOUNT> keys)
{
this->keys = keys;
this->error = CoordsFromBytesError::SUCCESS;
}
};

/*
Converts a stream of keyboard bytes into coordinates
*/
template<size_t KEY_AMOUNT>
FromBytesResult<KEY_AMOUNT> decode_coordinates_from_bytes(
CoordsFromBytesResult<KEY_AMOUNT> decode_coordinates_from_bytes(
BoundedArray<uint8_t, KEY_AMOUNT * 2 + 1> bytes
)
{
auto result = BoundedArray<KeyCoordinate, KEY_AMOUNT>();

if(bytes.size() % 2 != 1)
{
FromBytesResult<KEY_AMOUNT>(CoordsFromBytesError::INVALID_AMOUNT_OF_BYTES);
return CoordsFromBytesResult<KEY_AMOUNT>(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<KEY_AMOUNT>(CoordsFromBytesError::INVALID_CHECKSUM);
}

return result;
}
}

Expand Down
52 changes: 52 additions & 0 deletions unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t, 3>(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<KeyCoordinate, 3>();
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]);
}
}

0 comments on commit 6cbff28

Please sign in to comment.