summaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/config_common.h9
-rw-r--r--quantum/process_keycode/process_tap_dance.c5
-rw-r--r--quantum/process_keycode/process_unicode.c4
-rw-r--r--quantum/process_keycode/process_unicode.h1
-rw-r--r--quantum/serial_link/protocol/byte_stuffer.c3
-rw-r--r--quantum/serial_link/protocol/byte_stuffer.h3
-rw-r--r--quantum/serial_link/protocol/transport.c4
-rw-r--r--quantum/serial_link/protocol/transport.h7
-rw-r--r--quantum/serial_link/tests/byte_stuffer_tests.cpp (renamed from quantum/serial_link/tests/byte_stuffer_tests.c)313
-rw-r--r--quantum/serial_link/tests/frame_router_tests.c231
-rw-r--r--quantum/serial_link/tests/frame_router_tests.cpp229
-rw-r--r--quantum/serial_link/tests/frame_validator_tests.cpp (renamed from quantum/serial_link/tests/frame_validator_tests.c)90
-rw-r--r--quantum/serial_link/tests/rules.mk22
-rw-r--r--quantum/serial_link/tests/testlist.mk6
-rw-r--r--quantum/serial_link/tests/transport_tests.c168
-rw-r--r--quantum/serial_link/tests/transport_tests.cpp188
-rw-r--r--quantum/serial_link/tests/triple_buffered_object_tests.cpp (renamed from quantum/serial_link/tests/triple_buffered_object_tests.c)52
-rw-r--r--quantum/template/Makefile76
-rw-r--r--quantum/template/readme.md10
-rw-r--r--quantum/template/rules.mk67
20 files changed, 771 insertions, 717 deletions
diff --git a/quantum/config_common.h b/quantum/config_common.h
index 09a4fe7010..8ed5f4a106 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -45,6 +45,15 @@
#define F5 0xF5
#define F6 0xF6
#define F7 0xF7
+#define A0 0x00
+#define A1 0x01
+#define A2 0x02
+#define A3 0x03
+#define A4 0x04
+#define A5 0x05
+#define A6 0x06
+#define A7 0x07
+
/* USART configuration */
#ifdef BLUETOOTH_ENABLE
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 07de3ecb8f..79ade4d000 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -65,9 +65,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
highest_td = idx;
action = &tap_dance_actions[idx];
- action->state.keycode = keycode;
action->state.pressed = record->event.pressed;
if (record->event.pressed) {
+ action->state.keycode = keycode;
action->state.count++;
action->state.timer = timer_read();
@@ -77,8 +77,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
process_tap_dance_action_on_dance_finished (paction);
reset_tap_dance (&paction->state);
}
+
+ last_td = keycode;
}
- last_td = keycode;
break;
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index 06c1694f2e..a5d7dca21e 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -18,6 +18,10 @@ void set_unicode_input_mode(uint8_t os_target)
input_mode = os_target;
}
+uint8_t get_unicode_input_mode(void) {
+ return input_mode;
+}
+
__attribute__((weak))
void unicode_input_start (void) {
switch(input_mode) {
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index 02ce3dd7e0..27f8072ee6 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -13,6 +13,7 @@
#endif
void set_unicode_input_mode(uint8_t os_target);
+uint8_t get_unicode_input_mode(void);
void unicode_input_start(void);
void unicode_input_finish(void);
void register_hex(uint16_t hex);
diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c
index fb4c45a8dc..2c87d64c29 100644
--- a/quantum/serial_link/protocol/byte_stuffer.c
+++ b/quantum/serial_link/protocol/byte_stuffer.c
@@ -31,9 +31,6 @@ SOFTWARE.
// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing
// http://www.stuartcheshire.org/papers/COBSforToN.pdf
-#define MAX_FRAME_SIZE 1024
-#define NUM_LINKS 2
-
typedef struct byte_stuffer_state {
uint16_t next_zero;
uint16_t data_pos;
diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h
index 2cc88beb42..97e8968564 100644
--- a/quantum/serial_link/protocol/byte_stuffer.h
+++ b/quantum/serial_link/protocol/byte_stuffer.h
@@ -27,6 +27,9 @@ SOFTWARE.
#include <stdint.h>
+#define MAX_FRAME_SIZE 1024
+#define NUM_LINKS 2
+
void init_byte_stuffer(void);
void byte_stuffer_recv_byte(uint8_t link, uint8_t data);
void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size);
diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c
index f418d11ceb..ff795fe201 100644
--- a/quantum/serial_link/protocol/transport.c
+++ b/quantum/serial_link/protocol/transport.c
@@ -31,6 +31,10 @@ SOFTWARE.
static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS];
static uint32_t num_remote_objects = 0;
+void reinitialize_serial_link_transport(void) {
+ num_remote_objects = 0;
+}
+
void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) {
unsigned int i;
for(i=0;i<_num_remote_objects;i++) {
diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h
index 9a052d8809..2c5d890b21 100644
--- a/quantum/serial_link/protocol/transport.h
+++ b/quantum/serial_link/protocol/transport.h
@@ -82,7 +82,7 @@ typedef struct { \
remote_object_t* obj = (remote_object_t*)&remote_object_##name; \
uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\
triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \
- return triple_buffer_read_internal(obj->object_size, tb); \
+ return (type*)triple_buffer_read_internal(obj->object_size, tb); \
}
#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \
@@ -112,7 +112,7 @@ typedef struct { \
remote_object_t* obj = (remote_object_t*)&remote_object_##name; \
uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\
triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \
- return triple_buffer_read_internal(obj->object_size, tb); \
+ return (type*)triple_buffer_read_internal(obj->object_size, tb); \
}
#define SLAVE_TO_MASTER_OBJECT(name, type) \
@@ -139,12 +139,13 @@ typedef struct { \
uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\
start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \
triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \
- return triple_buffer_read_internal(obj->object_size, tb); \
+ return (type*)triple_buffer_read_internal(obj->object_size, tb); \
}
#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name
void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects);
+void reinitialize_serial_link_transport(void);
void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size);
void update_transport(void);
diff --git a/quantum/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/tests/byte_stuffer_tests.cpp
index 64b170e8c1..ff49d727bb 100644
--- a/quantum/serial_link/tests/byte_stuffer_tests.c
+++ b/quantum/serial_link/tests/byte_stuffer_tests.cpp
@@ -22,70 +22,90 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
-#include <cgreen/cgreen.h>
-#include <cgreen/mocks.h>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <vector>
+#include <algorithm>
+extern "C" {
#include "serial_link/protocol/byte_stuffer.h"
-#include "serial_link/protocol/byte_stuffer.c"
#include "serial_link/protocol/frame_validator.h"
#include "serial_link/protocol/physical.h"
+}
-static uint8_t sent_data[MAX_FRAME_SIZE*2];
-static uint16_t sent_data_size;
+using testing::_;
+using testing::ElementsAreArray;
+using testing::Args;
-Describe(ByteStuffer);
-BeforeEach(ByteStuffer) {
- init_byte_stuffer();
- sent_data_size = 0;
-}
-AfterEach(ByteStuffer) {}
+class ByteStuffer : public ::testing::Test{
+public:
+ ByteStuffer() {
+ Instance = this;
+ init_byte_stuffer();
+ }
-void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) {
- mock(data, size);
-}
+ ~ByteStuffer() {
+ Instance = nullptr;
+ }
+
+ MOCK_METHOD3(validator_recv_frame, void (uint8_t link, uint8_t* data, uint16_t size));
+
+ void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
+ std::copy(data, data + size, std::back_inserter(sent_data));
+ }
+ std::vector<uint8_t> sent_data;
-void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
- memcpy(sent_data + sent_data_size, data, size);
- sent_data_size += size;
+ static ByteStuffer* Instance;
+};
+
+ByteStuffer* ByteStuffer::Instance = nullptr;
+
+extern "C" {
+ void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) {
+ ByteStuffer::Instance->validator_recv_frame(link, data, size);
+ }
+
+ void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
+ ByteStuffer::Instance->send_data(link, data, size);
+ }
}
-Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) {
- never_expect(validator_recv_frame);
+TEST_F(ByteStuffer, receives_no_frame_for_a_single_zero_byte) {
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .Times(0);
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) {
- never_expect(validator_recv_frame);
+TEST_F(ByteStuffer, receives_no_frame_for_a_single_FF_byte) {
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .Times(0);
byte_stuffer_recv_byte(0, 0xFF);
}
-Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) {
- never_expect(validator_recv_frame);
+TEST_F(ByteStuffer, receives_no_frame_for_a_single_random_byte) {
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .Times(0);
byte_stuffer_recv_byte(0, 0x4A);
}
-Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) {
- never_expect(validator_recv_frame);
+TEST_F(ByteStuffer, receives_no_frame_for_a_zero_length_frame) {
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .Times(0);
byte_stuffer_recv_byte(0, 1);
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_single_byte_valid_frame) {
+TEST_F(ByteStuffer, receives_single_byte_valid_frame) {
uint8_t expected[] = {0x37};
- expect(validator_recv_frame,
- when(size, is_equal_to(1)),
- when(data, is_equal_to_contents_of(expected, 1))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 2);
byte_stuffer_recv_byte(0, 0x37);
byte_stuffer_recv_byte(0, 0);
}
-
-Ensure(ByteStuffer, receives_three_bytes_valid_frame) {
+TEST_F(ByteStuffer, receives_three_bytes_valid_frame) {
uint8_t expected[] = {0x37, 0x99, 0xFF};
- expect(validator_recv_frame,
- when(size, is_equal_to(3)),
- when(data, is_equal_to_contents_of(expected, 3))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 4);
byte_stuffer_recv_byte(0, 0x37);
byte_stuffer_recv_byte(0, 0x99);
@@ -93,23 +113,19 @@ Ensure(ByteStuffer, receives_three_bytes_valid_frame) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_single_zero_valid_frame) {
+TEST_F(ByteStuffer, receives_single_zero_valid_frame) {
uint8_t expected[] = {0};
- expect(validator_recv_frame,
- when(size, is_equal_to(1)),
- when(data, is_equal_to_contents_of(expected, 1))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 1);
byte_stuffer_recv_byte(0, 1);
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_valid_frame_with_zeroes) {
+TEST_F(ByteStuffer, receives_valid_frame_with_zeroes) {
uint8_t expected[] = {5, 0, 3, 0};
- expect(validator_recv_frame,
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(expected, 4))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 2);
byte_stuffer_recv_byte(0, 5);
byte_stuffer_recv_byte(0, 2);
@@ -118,17 +134,14 @@ Ensure(ByteStuffer, receives_valid_frame_with_zeroes) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_two_valid_frames) {
+
+TEST_F(ByteStuffer, receives_two_valid_frames) {
uint8_t expected1[] = {5, 0};
uint8_t expected2[] = {3};
- expect(validator_recv_frame,
- when(size, is_equal_to(2)),
- when(data, is_equal_to_contents_of(expected1, 2))
- );
- expect(validator_recv_frame,
- when(size, is_equal_to(1)),
- when(data, is_equal_to_contents_of(expected2, 1))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected1)));
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected2)));
byte_stuffer_recv_byte(1, 2);
byte_stuffer_recv_byte(1, 5);
byte_stuffer_recv_byte(1, 1);
@@ -138,12 +151,10 @@ Ensure(ByteStuffer, receives_two_valid_frames) {
byte_stuffer_recv_byte(1, 0);
}
-Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) {
+TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_zero) {
uint8_t expected[] = {5, 7};
- expect(validator_recv_frame,
- when(size, is_equal_to(2)),
- when(data, is_equal_to_contents_of(expected, 2))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(1, 3);
byte_stuffer_recv_byte(1, 1);
byte_stuffer_recv_byte(1, 0);
@@ -153,12 +164,10 @@ Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) {
byte_stuffer_recv_byte(1, 0);
}
-Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) {
+TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) {
uint8_t expected[] = {5, 7};
- expect(validator_recv_frame,
- when(size, is_equal_to(2)),
- when(data, is_equal_to_contents_of(expected, 2))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 2);
byte_stuffer_recv_byte(0, 9);
byte_stuffer_recv_byte(0, 4); // This should have been zero
@@ -169,16 +178,14 @@ Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) {
+TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) {
uint8_t expected[254];
int i;
for (i=0;i<254;i++) {
expected[i] = i + 1;
}
- expect(validator_recv_frame,
- when(size, is_equal_to(254)),
- when(data, is_equal_to_contents_of(expected, 254))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 0xFF);
for (i=0;i<254;i++) {
byte_stuffer_recv_byte(0, i+1);
@@ -186,17 +193,15 @@ Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) {
+TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) {
uint8_t expected[255];
int i;
for (i=0;i<254;i++) {
expected[i] = i + 1;
}
expected[254] = 7;
- expect(validator_recv_frame,
- when(size, is_equal_to(255)),
- when(data, is_equal_to_contents_of(expected, 255))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 0xFF);
for (i=0;i<254;i++) {
byte_stuffer_recv_byte(0, i+1);
@@ -206,17 +211,15 @@ Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) {
+TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) {
uint8_t expected[255];
int i;
for (i=0;i<254;i++) {
expected[i] = i + 1;
}
expected[254] = 0;
- expect(validator_recv_frame,
- when(size, is_equal_to(255)),
- when(data, is_equal_to_contents_of(expected, 255))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 0xFF);
for (i=0;i<254;i++) {
byte_stuffer_recv_byte(0, i+1);
@@ -226,7 +229,7 @@ Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_two_long_frames_and_some_more) {
+TEST_F(ByteStuffer, receives_two_long_frames_and_some_more) {
uint8_t expected[515];
int i;
int j;
@@ -238,10 +241,8 @@ Ensure(ByteStuffer, receives_two_long_frames_and_some_more) {
for (i=0;i<7;i++) {
expected[254*2+i] = i + 1;
}
- expect(validator_recv_frame,
- when(size, is_equal_to(515)),
- when(data, is_equal_to_contents_of(expected, 510))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
byte_stuffer_recv_byte(0, 0xFF);
for (i=0;i<254;i++) {
byte_stuffer_recv_byte(0, i+1);
@@ -261,12 +262,10 @@ Ensure(ByteStuffer, receives_two_long_frames_and_some_more) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) {
+TEST_F(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) {
uint8_t expected[MAX_FRAME_SIZE] = {};
- expect(validator_recv_frame,
- when(size, is_equal_to(MAX_FRAME_SIZE)),
- when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
int i;
byte_stuffer_recv_byte(0, 1);
for(i=0;i<MAX_FRAME_SIZE;i++) {
@@ -275,9 +274,10 @@ Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, doesnt_recv_a_frame_thats_too_long_all_zeroes) {
+TEST_F(ByteStuffer, doesnt_recv_a_frame_thats_too_long_all_zeroes) {
uint8_t expected[1] = {0};
- never_expect(validator_recv_frame);
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .Times(0);
int i;
byte_stuffer_recv_byte(0, 1);
for(i=0;i<MAX_FRAME_SIZE;i++) {
@@ -287,12 +287,10 @@ Ensure(ByteStuffer, doesnt_recv_a_frame_thats_too_long_all_zeroes) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, received_frame_is_aborted_when_its_too_long) {
+TEST_F(ByteStuffer, received_frame_is_aborted_when_its_too_long) {
uint8_t expected[1] = {1};
- expect(validator_recv_frame,
- when(size, is_equal_to(1)),
- when(data, is_equal_to_contents_of(expected, 1))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
int i;
byte_stuffer_recv_byte(0, 1);
for(i=0;i<MAX_FRAME_SIZE;i++) {
@@ -303,76 +301,68 @@ Ensure(ByteStuffer, received_frame_is_aborted_when_its_too_long) {
byte_stuffer_recv_byte(0, 0);
}
-Ensure(ByteStuffer, does_nothing_when_sending_zero_size_frame) {
- assert_that(sent_data_size, is_equal_to(0));
+TEST_F(ByteStuffer, does_nothing_when_sending_zero_size_frame) {
+ EXPECT_EQ(sent_data.size(), 0);
byte_stuffer_send_frame(0, NULL, 0);
}
-Ensure(ByteStuffer, send_one_byte_frame) {
+TEST_F(ByteStuffer, send_one_byte_frame) {
uint8_t data[] = {5};
byte_stuffer_send_frame(1, data, 1);
uint8_t expected[] = {2, 5, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_two_byte_frame) {
+TEST_F(ByteStuffer, sends_two_byte_frame) {
uint8_t data[] = {5, 0x77};
byte_stuffer_send_frame(0, data, 2);
uint8_t expected[] = {3, 5, 0x77, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_one_byte_frame_with_zero) {
+TEST_F(ByteStuffer, sends_one_byte_frame_with_zero) {
uint8_t data[] = {0};
byte_stuffer_send_frame(0, data, 1);
uint8_t expected[] = {1, 1, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_two_byte_frame_starting_with_zero) {
+TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_zero) {
uint8_t data[] = {0, 9};
byte_stuffer_send_frame(1, data, 2);
uint8_t expected[] = {1, 2, 9, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_two_byte_frame_starting_with_non_zero) {
+TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_non_zero) {
uint8_t data[] = {9, 0};
byte_stuffer_send_frame(1, data, 2);
uint8_t expected[] = {2, 9, 1, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_three_byte_frame_zero_in_the_middle) {
+TEST_F(ByteStuffer, sends_three_byte_frame_zero_in_the_middle) {
uint8_t data[] = {9, 0, 0x68};
byte_stuffer_send_frame(0, data, 3);
uint8_t expected[] = {2, 9, 2, 0x68, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_three_byte_frame_data_in_the_middle) {
+TEST_F(ByteStuffer, sends_three_byte_frame_data_in_the_middle) {
uint8_t data[] = {0, 0x55, 0};
byte_stuffer_send_frame(0, data, 3);
uint8_t expected[] = {1, 2, 0x55, 1, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_three_byte_frame_with_all_zeroes) {
+TEST_F(ByteStuffer, sends_three_byte_frame_with_all_zeroes) {
uint8_t data[] = {0, 0, 0};
byte_stuffer_send_frame(0, data, 3);
uint8_t expected[] = {1, 1, 1, 1, 0};
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_frame_with_254_non_zeroes) {
+TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes) {
uint8_t data[254];
int i;
for(i=0;i<254;i++) {
@@ -385,11 +375,10 @@ Ensure(ByteStuffer, sends_frame_with_254_non_zeroes) {
expected[i] = i;
}
expected[255] = 0;
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_frame_with_255_non_zeroes) {
+TEST_F(ByteStuffer, sends_frame_with_255_non_zeroes) {
uint8_t data[255];
int i;
for(i=0;i<255;i++) {
@@ -404,17 +393,16 @@ Ensure(ByteStuffer, sends_frame_with_255_non_zeroes) {
expected[255] = 2;
expected[256] = 255;
expected[257] = 0;
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_frame_with_254_non_zeroes_followed_by_zero) {
+TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes_followed_by_zero) {
uint8_t data[255];
int i;
for(i=0;i<254;i++) {
data[i] = i + 1;
}
- data[255] = 0;
+ data[254] = 0;
byte_stuffer_send_frame(0, data, 255);
uint8_t expected[258];
expected[0] = 0xFF;
@@ -424,53 +412,46 @@ Ensure(ByteStuffer, sends_frame_with_254_non_zeroes_followed_by_zero) {
expected[255] = 1;
expected[256] = 1;
expected[257] = 0;
- assert_that(sent_data_size, is_equal_to(sizeof(expected)));
- assert_that(sent_data, is_equal_to_contents_of(expected, sizeof(expected)));
+ EXPECT_THAT(sent_data, ElementsAreArray(expected));
}
-Ensure(ByteStuffer, sends_and_receives_full_roundtrip_small_packet) {
+TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet) {
uint8_t original_data[] = { 1, 2, 3};
byte_stuffer_send_frame(0, original_data, sizeof(original_data));
- expect(validator_recv_frame,
- when(size, is_equal_to(sizeof(original_data))),
- when(data, is_equal_to_contents_of(original_data, sizeof(original_data)))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(original_data)));
int i;
- for(i=0;i<sent_data_size;i++) {
- byte_stuffer_recv_byte(1, sent_data[i]);
+ for(auto& d : sent_data) {
+ byte_stuffer_recv_byte(1, d);
}
}
-Ensure(ByteStuffer, sends_and_receives_full_roundtrip_small_packet_with_zeros) {
+TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet_with_zeros) {
uint8_t original_data[] = { 1, 0, 3, 0, 0, 9};
byte_stuffer_send_frame(1, original_data, sizeof(original_data));
- expect(validator_recv_frame,
- when(size, is_equal_to(sizeof(original_data))),
- when(data, is_equal_to_contents_of(original_data, sizeof(original_data)))
- );
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(original_data)));
int i;
- for(i=0;i<sent_data_size;i++) {
- byte_stuffer_recv_byte(0, sent_data[i]);
+ for(auto& d : sent_data) {
+ byte_stuffer_recv_byte(1, d);
}
}
-Ensure(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes) {
+TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes) {
uint8_t original_data[254];
int i;
for(i=0;i<254;i++) {
original_data[i] = i + 1;
}
byte_stuffer_send_frame(0, original_data, sizeof(original_data));
- expect(validator_recv_frame,
- when(size, is_equal_to(sizeof(original_data))),
- when(data, is_equal_to_contents_of(original_data, sizeof(original_data)))
- );
- for(i=0;i<sent_data_size;i++) {
- byte_stuffer_recv_byte(1, sent_data[i]);
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(original_data)));
+ for(auto& d : sent_data) {
+ byte_stuffer_recv_byte(1, d);
}
}
-Ensure(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) {
+TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) {
uint8_t original_data[256];
int i;
for(i=0;i<254;i++) {
@@ -479,16 +460,14 @@ Ensure(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) {
original_data[254] = 22;
original_data[255] = 23;
byte_stuffer_send_frame(0, original_data, sizeof(original_data));
- expect(validator_recv_frame,
- when(size, is_equal_to(sizeof(original_data))),
- when(data, is_equal_to_contents_of(original_data, sizeof(original_data)))
- );
- for(i=0;i<sent_data_size;i++) {
- byte_stuffer_recv_byte(1, sent_data[i]);
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(original_data)));
+ for(auto& d : sent_data) {
+ byte_stuffer_recv_byte(1, d);
}
}
-Ensure(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) {
+TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) {
uint8_t original_data[255];
int i;
for(i=0;i<254;i++) {
@@ -496,11 +475,9 @@ Ensure(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) {
}
original_data[254] = 0;
byte_stuffer_send_frame(0, original_data, sizeof(original_data));
- expect(validator_recv_frame,
- when(size, is_equal_to(sizeof(original_data))),
- when(data, is_equal_to_contents_of(original_data, sizeof(original_data)))
- );
- for(i=0;i<sent_data_size;i++) {
- byte_stuffer_recv_byte(1, sent_data[i]);
+ EXPECT_CALL(*this, validator_recv_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(original_data)));
+ for(auto& d : sent_data) {
+ byte_stuffer_recv_byte(1, d);
}
}
diff --git a/quantum/serial_link/tests/frame_router_tests.c b/quantum/serial_link/tests/frame_router_tests.c
deleted file mode 100644
index 6c806fa939..0000000000
--- a/quantum/serial_link/tests/frame_router_tests.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2016 Fred Sundvik
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#include <cgreen/cgreen.h>
-#include <cgreen/mocks.h>
-#include "serial_link/protocol/byte_stuffer.c"
-#include "serial_link/protocol/frame_validator.c"
-#include "serial_link/protocol/frame_router.c"
-#include "serial_link/protocol/transport.h"
-
-static uint8_t received_data[256];
-static uint16_t received_data_size;
-
-typedef struct {
- uint8_t sent_data[256];
- uint16_t sent_data_size;
-} receive_buffer_t;
-
-typedef struct {
- receive_buffer_t send_buffers[2];
-} router_buffer_t;
-
-router_buffer_t router_buffers[8];
-
-router_buffer_t* current_router_buffer;
-
-
-Describe(FrameRouter);
-BeforeEach(FrameRouter) {
- init_byte_stuffer();
- memset(router_buffers, 0, sizeof(router_buffers));
- current_router_buffer = 0;
-}
-AfterEach(FrameRouter) {}
-
-typedef struct {
- uint32_t data;
- uint8_t extra[16];
-} frame_buffer_t;
-
-
-void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
- receive_buffer_t* buffer = &current_router_buffer->send_buffers[link];
- memcpy(buffer->sent_data + buffer->sent_data_size, data, size);
- buffer->sent_data_size += size;
-}
-
-static void receive_data(uint8_t link, uint8_t* data, uint16_t size) {
- int i;
- for(i=0;i<size;i++) {
- byte_stuffer_recv_byte(link, data[i]);
- }
-}
-
-static void activate_router(uint8_t num) {
- current_router_buffer = router_buffers + num;
- router_set_master(num==0);
-}
-
-static void simulate_transport(uint8_t from, uint8_t to) {
- activate_router(to);
- if (from > to) {
- receive_data(DOWN_LINK,
- router_buffers[from].send_buffers[UP_LINK].sent_data,
- router_buffers[from].send_buffers[UP_LINK].sent_data_size);
- }
- else if(to > from) {
- receive_data(UP_LINK,
- router_buffers[from].send_buffers[DOWN_LINK].sent_data,
- router_buffers[from].send_buffers[DOWN_LINK].sent_data_size);
- }
-}
-
-void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) {
- mock(from, data, size);
-}
-
-
-Ensure(FrameRouter, master_broadcast_is_received_by_everyone) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(0);
- router_send_frame(0xFF, (uint8_t*)&data, 4);
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(0)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(0, 1);
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(0)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(1, 2);
- assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, master_send_is_received_by_targets) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(0);
- router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4);
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-
- simulate_transport(0, 1);
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(0)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(1, 2);
- assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(0)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(2, 3);
- assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, first_link_sends_to_master) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(1);
- router_send_frame(0, (uint8_t*)&data, 4);
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(1)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(1, 0);
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, second_link_sends_to_master) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(2);
- router_send_frame(0, (uint8_t*)&data, 4);
- assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-
- simulate_transport(2, 1);
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-
- expect(transport_recv_frame,
- when(from, is_equal_to(2)),
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(&data.data, 4))
- );
- simulate_transport(1, 0);
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, master_sends_to_master_does_nothing) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(0);
- router_send_frame(0, (uint8_t*)&data, 4);
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, link_sends_to_other_link_does_nothing) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(1);
- router_send_frame(2, (uint8_t*)&data, 4);
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-}
-
-Ensure(FrameRouter, master_receives_on_uplink_does_nothing) {
- frame_buffer_t data;
- data.data = 0xAB7055BB;
- activate_router(1);
- router_send_frame(0, (uint8_t*)&data, 4);
- assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0));
- assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-
- never_expect(transport_recv_frame);
- activate_router(0);
- receive_data(UP_LINK,
- router_buffers[1].send_buffers[UP_LINK].sent_data,
- router_buffers[1].send_buffers[UP_LINK].sent_data_size);
- assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0));
- assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0));
-}
diff --git a/quantum/serial_link/tests/frame_router_tests.cpp b/quantum/serial_link/tests/frame_router_tests.cpp
new file mode 100644
index 0000000000..2bd5bf830d
--- /dev/null
+++ b/quantum/serial_link/tests/frame_router_tests.cpp
@@ -0,0 +1,229 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 Fred Sundvik
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <array>
+extern "C" {
+ #include "serial_link/protocol/transport.h"
+ #include "serial_link/protocol/byte_stuffer.h"
+ #include "serial_link/protocol/frame_router.h"
+}
+
+using testing::_;
+using testing::ElementsAreArray;
+using testing::Args;
+
+class FrameRouter : public testing::Test {
+public:
+ FrameRouter() :
+ current_router_buffer(nullptr)
+ {
+ Instance = this;
+ init_byte_stuffer();
+ }
+
+ ~FrameRouter() {
+ Instance = nullptr;
+ }
+
+ void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
+ auto& buffer = current_router_buffer->send_buffers[link];
+ std::copy(data, data + size, std::back_inserter(buffer));
+ }
+
+ void receive_data(uint8_t link, uint8_t* data, uint16_t size) {
+ int i;
+ for(i=0;i<size;i++) {
+ byte_stuffer_recv_byte(link, data[i]);
+ }
+ }
+
+ void activate_router(uint8_t num) {
+ current_router_buffer = router_buffers + num;
+ router_set_master(num==0);
+ }
+
+ void simulate_transport(uint8_t from, uint8_t to) {
+ activate_router(to);
+ if (from > to) {
+ receive_data(DOWN_LINK,
+ router_buffers[from].send_buffers[UP_LINK].data(),
+ router_buffers[from].send_buffers[UP_LINK].size());
+ }
+ else if(to > from) {
+ receive_data(UP_LINK,
+ router_buffers[from].send_buffers[DOWN_LINK].data(),
+ router_buffers[from].send_buffers[DOWN_LINK].size());
+ }
+ }
+
+ MOCK_METHOD3(transport_recv_frame, void (uint8_t from, uint8_t* data, uint16_t size));
+
+ std::vector<uint8_t> received_data;
+
+ struct router_buffer {
+ std::vector<uint8_t> send_buffers[2];
+ };
+
+ router_buffer router_buffers[8];
+ router_buffer* current_router_buffer;
+
+ static FrameRouter* Instance;
+};
+
+FrameRouter* FrameRouter::Instance = nullptr;
+
+
+typedef struct {
+ std::array<uint8_t, 4> data;
+ uint8_t extra[16];
+} frame_buffer_t;
+
+
+extern "C" {
+ void send_data(uint8_t link, const uint8_t* data, uint16_t size) {
+ FrameRouter::Instance->send_data(link, data, size);
+ }
+
+
+ void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) {
+ FrameRouter::Instance->transport_recv_frame(from, data, size);
+ }
+}
+
+TEST_F(FrameRouter, master_broadcast_is_received_by_everyone) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(0);
+ router_send_frame(0xFF, (uint8_t*)&data, 4);
+ EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+ EXPECT_CALL(*this, transport_recv_frame(0, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(0, 1);
+ EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(0, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(1, 2);
+ EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, master_send_is_received_by_targets) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(0);
+ router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4);
+ EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+
+ simulate_transport(0, 1);
+ EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(0, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(1, 2);
+ EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(0, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(2, 3);
+ EXPECT_GT(router_buffers[3].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[3].send_buffers[UP_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, first_link_sends_to_master) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(1);
+ router_send_frame(0, (uint8_t*)&data, 4);
+ EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(1, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(1, 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, second_link_sends_to_master) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(2);
+ router_send_frame(0, (uint8_t*)&data, 4);
+ EXPECT_GT(router_buffers[2].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[2].send_buffers[DOWN_LINK].size(), 0);
+
+ simulate_transport(2, 1);
+ EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(2, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data.data)));
+ simulate_transport(1, 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, master_sends_to_master_does_nothing) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(0);
+ router_send_frame(0, (uint8_t*)&data, 4);
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, link_sends_to_other_link_does_nothing) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(1);
+ router_send_frame(2, (uint8_t*)&data, 4);
+ EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+}
+
+TEST_F(FrameRouter, master_receives_on_uplink_does_nothing) {
+ frame_buffer_t data;
+ data.data = {0xAB, 0x70, 0x55, 0xBB};
+ activate_router(1);
+ router_send_frame(0, (uint8_t*)&data, 4);
+ EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0);
+
+ EXPECT_CALL(*this, transport_recv_frame(_, _, _))
+ .Times(0);
+ activate_router(0);
+ receive_data(UP_LINK,
+ router_buffers[1].send_buffers[UP_LINK].data(),
+ router_buffers[1].send_buffers[UP_LINK].size());
+ EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0);
+ EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0);
+}
diff --git a/quantum/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/tests/frame_validator_tests.cpp
index d20947e2c9..9223af83b0 100644
--- a/quantum/serial_link/tests/frame_validator_tests.c
+++ b/quantum/serial_link/tests/frame_validator_tests.cpp
@@ -22,24 +22,47 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
-#include <cgreen/cgreen.h>
-#include <cgreen/mocks.h>
-#include "serial_link/protocol/frame_validator.c"
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+extern "C" {
+#include "serial_link/protocol/frame_validator.h"
+}
+
+using testing::_;
+using testing::ElementsAreArray;
+using testing::Args;
+
+class FrameValidator : public testing::Test {
+public:
+ FrameValidator() {
+ Instance = this;
+ }
+
+ ~FrameValidator() {
+ Instance = nullptr;
+ }
+
+ MOCK_METHOD3(route_incoming_frame, void (uint8_t link, uint8_t* data, uint16_t size));
+ MOCK_METHOD3(byte_stuffer_send_frame, void (uint8_t link, uint8_t* data, uint16_t size));
+ static FrameValidator* Instance;
+};
+
+FrameValidator* FrameValidator::Instance = nullptr;
+
+extern "C" {
void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) {
- mock(data, size);
+ FrameValidator::Instance->route_incoming_frame(link, data, size);
}
void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) {
- mock(data, size);
+ FrameValidator::Instance->byte_stuffer_send_frame(link, data, size);
+}
}
-Describe(FrameValidator);
-BeforeEach(FrameValidator) {}
-AfterEach(FrameValidator) {}
-
-Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) {
- never_expect(route_incoming_frame);
+TEST_F(FrameValidator, doesnt_validate_frames_under_5_bytes) {
+ EXPECT_CALL(*this, route_incoming_frame(_, _, _))
+ .Times(0);
uint8_t data[] = {1, 2};
validator_recv_frame(0, 0, 1);
validator_recv_frame(0, data, 2);
@@ -47,55 +70,46 @@ Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) {
validator_recv_frame(0, data, 4);
}
-Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) {
+TEST_F(FrameValidator, validates_one_byte_frame_with_correct_crc) {
uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3};
- expect(route_incoming_frame,
- when(size, is_equal_to(1)),
- when(data, is_equal_to_contents_of(data, 1))
- );
+ EXPECT_CALL(*this, route_incoming_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data, 1)));
validator_recv_frame(0, data, 5);
}
-Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) {
+TEST_F(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) {
uint8_t data[] = {0x44, 0, 0, 0, 0};
- never_expect(route_incoming_frame);
+ EXPECT_CALL(*this, route_incoming_frame(_, _, _))
+ .Times(0);
validator_recv_frame(1, data, 5);
}
-Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) {
+TEST_F(FrameValidator, validates_four_byte_frame_with_correct_crc) {
uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA};
- expect(route_incoming_frame,
- when(size, is_equal_to(4)),
- when(data, is_equal_to_contents_of(data, 4))
- );
+ EXPECT_CALL(*this, route_incoming_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data, 4)));
validator_recv_frame(1, data, 8);
}
-Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) {
+TEST_F(FrameValidator, validates_five_byte_frame_with_correct_crc) {
uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47};
- expect(route_incoming_frame,
- when(size, is_equal_to(5)),
- when(data, is_equal_to_contents_of(data, 5))
- );
+ EXPECT_CALL(*this, route_incoming_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(data, 5)));
validator_recv_frame(0, data, 9);
}
-Ensure(FrameValidator, sends_one_byte_with_correct_crc) {
+TEST_F(FrameValidator, sends_one_byte_with_correct_crc) {
uint8_t original[] = {0x44, 0, 0, 0, 0};
uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3};
- expect(byte_stuffer_send_frame,
- when(size, is_equal_to(sizeof(expected))),
- when(data, is_equal_to_contents_of(expected, sizeof(expected)))
- );
+ EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
validator_send_frame(0, original, 1);
}
-Ensure(FrameValidator, sends_five_bytes_with_correct_crc) {
+TEST_F(FrameValidator, sends_five_bytes_with_correct_crc) {
uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47};
- expect(byte_stuffer_send_frame,
- when(size, is_equal_to(sizeof(expected))),
- when(data, is_equal_to_contents_of(expected, sizeof(expected)))
- );
+ EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _))
+ .With(Args<1, 2>(ElementsAreArray(expected)));
validator_send_frame(0, original, 5);
}
diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk
new file mode 100644
index 0000000000..b81515bc55
--- /dev/null
+++ b/quantum/serial_link/tests/rules.mk
@@ -0,0 +1,22 @@
+serial_link_byte_stuffer_SRC :=\
+ $(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \
+ $(SERIAL_PATH)/protocol/byte_stuffer.c
+
+serial_link_frame_validator_SRC := \
+ $(SERIAL_PATH)/tests/frame_validator_tests.cpp \
+ $(SERIAL_PATH)/protocol/frame_validator.c
+
+serial_link_frame_router_SRC := \
+ $(SERIAL_PATH)/tests/frame_router_tests.cpp \
+ $(SERIAL_PATH)/protocol/byte_stuffer.c \
+ $(SERIAL_PATH)/protocol/frame_validator.c \
+ $(SERIAL_PATH)/protocol/frame_router.c
+
+serial_link_triple_buffered_object_SRC := \
+ $(SERIAL_PATH)/tests/triple_buffered_object_tests.cpp \
+ $(SERIAL_PATH)/protocol/triple_buffered_object.c
+
+serial_link_transport_SRC := \
+ $(SERIAL_PATH)/tests/transport_tests.cpp \
+ $(SERIAL_PATH)/protocol/transport.c \
+ $(SERIAL_PATH)/protocol/triple_buffered_object.c
diff --git a/quantum/serial_link/tests/testlist.mk b/quantum/serial_link/tests/testlist.mk
new file mode 100644
index 0000000000..a80e888849
--- /dev/null
+++ b/quantum/serial_link/tests/testlist.mk
@@ -0,0 +1,6 @@
+TEST_LIST +=\
+ serial_link_byte_stuffer\
+ serial_link_frame_validator\
+ serial_link_frame_router\
+ serial_link_triple_buffered_object\
+ serial_link_transport \ No newline at end of file
diff --git a/quantum/serial_link/tests/transport_tests.c b/quantum/serial_link/tests/transport_tests.c
deleted file mode 100644
index 358e1b9fd4..0000000000
--- a/quantum/serial_link/tests/transport_tests.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2016 Fred Sundvik
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#include <cgreen/cgreen.h>
-#include <cgreen/mocks.h>
-#include "serial_link/protocol/transport.c"
-#include "serial_link/protocol/triple_buffered_object.c"
-
-void signal_data_written(void) {
- mock();
-}
-
-static uint8_t sent_data[2048];
-static uint16_t sent_data_size;
-
-void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
- mock(destination);
- memcpy(sent_data + sent_data_size, data, size);
- sent_data_size += size;
-}
-
-typedef struct {
- uint32_t test;
-} test_object1_t;
-
-typedef struct {
- uint32_t test1;
- uint32_t test2;
-} test_object2_t;
-
-MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t);
-MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t);
-SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t);
-
-static remote_object_t* test_remote_objects[] = {
- REMOTE_OBJECT(master_to_slave),
- REMOTE_OBJECT(master_to_single_slave),
- REMOTE_OBJECT(slave_to_master),
-};
-
-Describe(Transport);
-BeforeEach(Transport) {
- add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*));
- sent_data_size = 0;
-}
-AfterEach(Transport) {}
-
-Ensure(Transport, write_to_local_signals_an_event) {
- begin_write_master_to_slave();
- expect(signal_data_written);
- end_write_master_to_slave();
- begin_write_slave_to_master();
- expect(signal_data_written);
- end_write_slave_to_master();
- begin_write_master_to_single_slave(1);
- expect(signal_data_written);
- end_write_master_to_single_slave(1);
-}
-
-Ensure(Transport, writes_from_master_to_all_slaves) {
- update_transport();
- test_object1_t* obj = begin_write_master_to_slave();
- obj->test = 5;
- expect(signal_data_written);
- end_write_master_to_slave();
- expect(router_send_frame,
- when(destination, is_equal_to(0xFF)));
- update_transport();
- transport_recv_frame(0, sent_data, sent_data_size);
- test_object1_t* obj2 = read_master_to_slave();
- assert_that(obj2, is_not_equal_to(NULL));
- assert_that(obj2->test, is_equal_to(5));
-}
-
-Ensure(Transport, writes_from_slave_to_master) {
- update_transport();
- test_object1_t* obj = begin_write_slave_to_master();
- obj->test = 7;
- expect(signal_data_written);
- end_write_slave_to_master();
- expect(router_send_frame,
- when(destination, is_equal_to(0)));
- update_transport();
- transport_recv_frame(3, sent_data, sent_data_size);
- test_object1_t* obj2 = read_slave_to_master(2);
- assert_that(read_slave_to_master(0), is_equal_to(NULL));
- assert_that(obj2, is_not_equal_to(NULL));
- assert_that(obj2->test, is_equal_to(7));
-}
-
-Ensure(Transport, writes_from_master_to_single_slave) {
- update_transport();
- test_object1_t* obj = begin_write_master_to_single_slave(3);
- obj->test = 7;
- expect(signal_data_written);
- end_write_master_to_single_slave(3);
- expect(router_send_frame,
- when(destination, is_equal_to(4)));
- update_transport();
- transport_recv_frame(0, sent_data, sent_data_size);
- test_object1_t* obj2 = read_master_to_single_slave();
- assert_that(obj2, is_not_equal_to(NULL));
- assert_that(obj2->test, is_equal_to(7));
-}
-
-Ensure(Transport, ignores_object_with_invalid_id) {
- update_transport();
- test_object1_t* obj = begin_write_master_to_single_slave(3);
- obj->test = 7;
- expect(signal_data_written);
- end_write_master_to_single_slave(3);
- expect(router_send_frame,
- when(destination, is_equal_to(4)));
- update_transport();
- sent_data[sent_data_size - 1] = 44;
- transport_recv_frame(0, sent_data, sent_data_size);
- test_object1_t* obj2 = read_master_to_single_slave();
- assert_that(obj2, is_equal_to(NULL));
-}
-
-Ensure(Transport, ignores_object_with_size_too_small) {
- update_transport();
- test_object1_t* obj = begin_write_master_to_slave();
- obj->test = 7;
- expect(signal_data_written);
- end_write_master_to_slave();
- expect(router_send_frame);
- update_transport();
- sent_data[sent_data_size - 2] = 0;
- transport_recv_frame(0, sent_data, sent_data_size - 1);
- test_object1_t* obj2 = read_master_to_slave();
- assert_that(obj2, is_equal_to(NULL));
-}
-
-Ensure(Transport, ignores_object_with_size_too_big) {
- update_transport();
- test_object1_t* obj = begin_write_master_to_slave();
- obj->test = 7;
- expect(signal_data_written);
- end_write_master_to_slave();
- expect(router_send_frame);
- update_transport();
- sent_data[sent_data_size + 21] = 0;
- transport_recv_frame(0, sent_data, sent_data_size + 22);
- test_object1_t* obj2 = read_master_to_slave();
- assert_that(obj2, is_equal_to(NULL));
-}
diff --git a/quantum/serial_link/tests/transport_tests.cpp b/quantum/serial_link/tests/transport_tests.cpp
new file mode 100644
index 0000000000..21b7b165f6
--- /dev/null
+++ b/quantum/serial_link/tests/transport_tests.cpp
@@ -0,0 +1,188 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 Fred Sundvik
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+using testing::_;
+using testing::ElementsAreArray;
+using testing::Args;
+
+extern "C" {
+#include "serial_link/protocol/transport.h"
+}
+
+struct test_object1 {
+ uint32_t test;
+};
+
+struct test_object2 {
+ uint32_t test1;
+ uint32_t test2;
+};
+
+MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1);
+MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1);
+SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1);
+
+static remote_object_t* test_remote_objects[] = {
+ REMOTE_OBJECT(master_to_slave),
+ REMOTE_OBJECT(master_to_single_slave),
+ REMOTE_OBJECT(slave_to_master),
+};
+
+class Transport : public testing::Test {
+public:
+ Transport() {
+ Instance = this;
+ add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*));
+ }
+
+ ~Transport() {
+ Instance = nullptr;
+ reinitialize_serial_link_transport();
+ }
+
+ MOCK_METHOD0(signal_data_written, void ());
+ MOCK_METHOD1(router_send_frame, void (uint8_t destination));
+
+ void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
+ router_send_frame(destination);
+ std::copy(data, data + size, std::back_inserter(sent_data));
+ }
+
+ static Transport* Instance;
+
+ std::vector<uint8_t> sent_data;
+};
+
+Transport* Transport::Instance = nullptr;
+
+extern "C" {
+void signal_data_written(void) {
+ Transport::Instance->signal_data_written();
+}
+
+void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
+ Transport::Instance->router_send_frame(destination, data, size);
+}
+}
+
+TEST_F(Transport, write_to_local_signals_an_event) {
+ begin_write_master_to_slave();
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_slave();
+ begin_write_slave_to_master();
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_slave_to_master();
+ begin_write_master_to_single_slave(1);
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_single_slave(1);
+}
+
+TEST_F(Transport, writes_from_master_to_all_slaves) {
+ update_transport();
+ test_object1* obj = begin_write_master_to_slave();
+ obj->test = 5;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_slave();
+ EXPECT_CALL(*this, router_send_frame(0xFF));
+ update_transport();
+ transport_recv_frame(0, sent_data.data(), sent_data.size());
+ test_object1* obj2 = read_master_to_slave();
+ EXPECT_NE(obj2, nullptr);
+ EXPECT_EQ(obj2->test, 5);
+}
+
+TEST_F(Transport, writes_from_slave_to_master) {
+ update_transport();
+ test_object1* obj = begin_write_slave_to_master();
+ obj->test = 7;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_slave_to_master();
+ EXPECT_CALL(*this, router_send_frame(0));
+ update_transport();
+ transport_recv_frame(3, sent_data.data(), sent_data.size());
+ test_object1* obj2 = read_slave_to_master(2);
+ EXPECT_EQ(read_slave_to_master(0), nullptr);
+ EXPECT_NE(obj2, nullptr);
+ EXPECT_EQ(obj2->test, 7);
+}
+
+TEST_F(Transport, writes_from_master_to_single_slave) {
+ update_transport();
+ test_object1* obj = begin_write_master_to_single_slave(3);
+ obj->test = 7;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_single_slave(3);
+ EXPECT_CALL(*this, router_send_frame(4));
+ update_transport();
+ transport_recv_frame(0, sent_data.data(), sent_data.size());
+ test_object1* obj2 = read_master_to_single_slave();
+ EXPECT_NE(obj2, nullptr);
+ EXPECT_EQ(obj2->test, 7);
+}
+
+TEST_F(Transport, ignores_object_with_invalid_id) {
+ update_transport();
+ test_object1* obj = begin_write_master_to_single_slave(3);
+ obj->test = 7;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_single_slave(3);
+ EXPECT_CALL(*this, router_send_frame(4));
+ update_transport();
+ sent_data[sent_data.size() - 1] = 44;
+ transport_recv_frame(0, sent_data.data(), sent_data.size());
+ test_object1* obj2 = read_master_to_single_slave();
+ EXPECT_EQ(obj2, nullptr);
+}
+
+TEST_F(Transport, ignores_object_with_size_too_small) {
+ update_transport();
+ test_object1* obj = begin_write_master_to_slave();
+ obj->test = 7;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_slave();
+ EXPECT_CALL(*this, router_send_frame(_));
+ update_transport();
+ sent_data[sent_data.size() - 2] = 0;
+ transport_recv_frame(0, sent_data.data(), sent_data.size() - 1);
+ test_object1* obj2 = read_master_to_slave();
+ EXPECT_EQ(obj2, nullptr);
+}
+
+TEST_F(Transport, ignores_object_with_size_too_big) {
+ update_transport();
+ test_object1* obj = begin_write_master_to_slave();
+ obj->test = 7;
+ EXPECT_CALL(*this, signal_data_written());
+ end_write_master_to_slave();
+ EXPECT_CALL(*this, router_send_frame(_));
+ update_transport();
+ sent_data.resize(sent_data.size() + 22);
+ sent_data[sent_data.size() - 1] = 0;
+ transport_recv_frame(0, sent_data.data(), sent_data.size());
+ test_object1* obj2 = read_master_to_slave();
+ EXPECT_EQ(obj2, nullptr);
+}
diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/tests/triple_buffered_object_tests.cpp
index 6f7c82b468..7724bbee9c 100644
--- a/quantum/serial_link/tests/triple_buffered_object_tests.c
+++ b/quantum/serial_link/tests/triple_buffered_object_tests.cpp
@@ -22,53 +22,55 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
-#include <cgreen/cgreen.h>
-#include "serial_link/protocol/triple_buffered_object.c"
+#include "gtest/gtest.h"
+extern "C" {
+#include "serial_link/protocol/triple_buffered_object.h"
+}
-typedef struct {
+struct test_object{
uint8_t state;
uint32_t buffer[3];
-}test_object_t;
-
-test_object_t test_object;
+};
-Describe(TripleBufferedObject);
-BeforeEach(TripleBufferedObject) {
- triple_buffer_init((triple_buffer_object_t*)&test_object);
-}
-AfterEach(TripleBufferedObject) {}
+test_object test_object;
+class TripleBufferedObject : public testing::Test {
+public:
+ TripleBufferedObject() {
+ triple_buffer_init((triple_buffer_object_t*)&test_object);
+ }
+};
-Ensure(TripleBufferedObject, writes_and_reads_object) {
+TEST_F(TripleBufferedObject, writes_and_reads_object) {
*triple_buffer_begin_write(&test_object) = 0x3456ABCC;
triple_buffer_end_write(&test_object);
- assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC));
+ EXPECT_EQ(*triple_buffer_read(&test_object), 0x3456ABCC);
}
-Ensure(TripleBufferedObject, does_not_read_empty) {
- assert_that(triple_buffer_read(&test_object), is_equal_to(NULL));
+TEST_F(TripleBufferedObject, does_not_read_empty) {
+ EXPECT_EQ(triple_buffer_read(&test_object), nullptr);
}
-Ensure(TripleBufferedObject, writes_twice_and_reads_object) {
+TEST_F(TripleBufferedObject, writes_twice_and_reads_object) {
*triple_buffer_begin_write(&test_object) = 0x3456ABCC;
triple_buffer_end_write(&test_object);
*triple_buffer_begin_write(&test_object) = 0x44778899;
triple_buffer_end_write(&test_object);
- assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899));
+ EXPECT_EQ(*triple_buffer_read(&test_object), 0x44778899);
}
-Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) {
+TEST_F(TripleBufferedObject, performs_another_write_in_the_middle_of_read) {
*triple_buffer_begin_write(&test_object) = 1;
triple_buffer_end_write(&test_object);
uint32_t* read = triple_buffer_read(&test_object);
*triple_buffer_begin_write(&test_object) = 2;
triple_buffer_end_write(&test_object);
- assert_that(*read, is_equal_to(1));
- assert_that(*triple_buffer_read(&test_object), is_equal_to(2));
- assert_that(triple_buffer_read(&test_object), is_equal_to(NULL));
+ EXPECT_EQ(*read, 1);
+ EXPECT_EQ(*triple_buffer_read(&test_object), 2);
+ EXPECT_EQ(triple_buffer_read(&test_object), nullptr);
}
-Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) {
+TEST_F(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) {
*triple_buffer_begin_write(&test_object) = 1;
triple_buffer_end_write(&test_object);
uint32_t* read = triple_buffer_read(&test_object);
@@ -76,7 +78,7 @@ Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) {
triple_buffer_end_write(&test_object);
*triple_buffer_begin_write(&test_object) = 3;
triple_buffer_end_write(&test_object);
- assert_that(*read, is_equal_to(1));
- assert_that(*triple_buffer_read(&test_object), is_equal_to(3));
- assert_that(triple_buffer_read(&test_object), is_equal_to(NULL));
+ EXPECT_EQ(*read, 1);
+ EXPECT_EQ(*triple_buffer_read(&test_object), 3);
+ EXPECT_EQ(triple_buffer_read(&test_object), nullptr);
}
diff --git a/quantum/template/Makefile b/quantum/template/Makefile
index 3f6d133c9b..4e2a6f00fd 100644
--- a/quantum/template/Makefile
+++ b/quantum/template/Makefile
@@ -1,75 +1,3 @@
-
-
-# MCU name
-#MCU = at90usb1287
-MCU = atmega32u4
-
-# Processor frequency.
-# This will define a symbol, F_CPU, in all source code files equal to the
-# processor frequency in Hz. You can then use this symbol in your source code to
-# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
-# automatically to create a 32-bit value in your source code.
-#
-# This will be an integer division of F_USB below, as it is sourced by
-# F_USB after it has run through any CPU prescalers. Note that this value
-# does not *change* the processor frequency - it should merely be updated to
-# reflect the processor speed set externally so that the code can use accurate
-# software delays.
-F_CPU = 16000000
-
-
-#
-# LUFA specific
-#
-# Target architecture (see library "Board Types" documentation).
-ARCH = AVR8
-
-# Input clock frequency.
-# This will define a symbol, F_USB, in all source code files equal to the
-# input clock frequency (before any prescaling is performed) in Hz. This value may
-# differ from F_CPU if prescaling is used on the latter, and is required as the
-# raw input clock is fed directly to the PLL sections of the AVR for high speed
-# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
-# at the end, this will be done automatically to create a 32-bit value in your
-# source code.
-#
-# If no clock division is performed on the input clock inside the AVR (via the
-# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
-F_USB = $(F_CPU)
-
-# Interrupt driven control endpoint task(+60)
-OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
-
-
-# Boot Section Size in *bytes*
-# Teensy halfKay 512
-# Teensy++ halfKay 1024
-# Atmel DFU loader 4096
-# LUFA bootloader 4096
-# USBaspLoader 2048
-OPT_DEFS += -DBOOTLOADER_SIZE=512
-
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
-MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
-EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
-CONSOLE_ENABLE ?= yes # Console for debug(+400)
-COMMAND_ENABLE ?= yes # Commands for debug and configuration
-# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
-SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
-# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
-NKRO_ENABLE ?= no # USB Nkey Rollover
-BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
-MIDI_ENABLE ?= no # MIDI controls
-UNICODE_ENABLE ?= no # Unicode
-BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
-AUDIO_ENABLE ?= no # Audio output on port C6
-
-ifndef QUANTUM_DIR
+ifndef MAKEFILE_INCLUDED
include ../../Makefile
-endif
-
-
+endif \ No newline at end of file
diff --git a/quantum/template/readme.md b/quantum/template/readme.md
index b2fb4dd98d..b16f4cd768 100644
--- a/quantum/template/readme.md
+++ b/quantum/template/readme.md
@@ -3,7 +3,7 @@
## Quantum MK Firmware
-For the full Quantum feature list, see [the parent readme.md](/doc/readme.md).
+For the full Quantum feature list, see [the parent readme](/).
## Building
@@ -13,16 +13,16 @@ Depending on which keymap you would like to use, you will have to compile slight
### Default
-To build with the default keymap, simply run `make`.
+To build with the default keymap, simply run `make default`.
### Other Keymaps
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
-To build the firmware binary hex file with a keymap just do `make` with `keymap` option like:
+To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
```
-$ make keymap=[default|jack|<name>]
+$ make [default|jack|<name>]
```
-Keymaps follow the format **__keymap.c__** and are stored in folders in the `keymaps` folder, eg `keymaps/my_keymap/` \ No newline at end of file
+Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.
diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk
new file mode 100644
index 0000000000..55898147dd
--- /dev/null
+++ b/quantum/template/rules.mk
@@ -0,0 +1,67 @@
+# MCU name
+#MCU = at90usb1287
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in *bytes*
+# Teensy halfKay 512
+# Teensy++ halfKay 1024
+# Atmel DFU loader 4096
+# LUFA bootloader 4096
+# USBaspLoader 2048
+OPT_DEFS += -DBOOTLOADER_SIZE=512
+
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
+EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
+CONSOLE_ENABLE ?= yes # Console for debug(+400)
+COMMAND_ENABLE ?= yes # Commands for debug and configuration
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
+# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+NKRO_ENABLE ?= no # USB Nkey Rollover
+BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
+MIDI_ENABLE ?= no # MIDI controls
+UNICODE_ENABLE ?= no # Unicode
+BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE ?= no # Audio output on port C6