diff --git a/serial_link/protocol/transport.c b/serial_link/protocol/transport.c index 399894ff9..7b2c14950 100644 --- a/serial_link/protocol/transport.c +++ b/serial_link/protocol/transport.c @@ -24,10 +24,12 @@ SOFTWARE. #include "protocol/transport.h" -static uint32_t current_send_frame; +static remote_object_t* remote_objects; +static uint32_t num_remote_objects; -void init_transport(void) { - current_send_frame = 0; +void init_transport(remote_object_t* _remote_objects, uint32_t _num_remote_objects) { + remote_objects = _remote_objects; + num_remote_objects = _num_remote_objects; } void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { @@ -35,5 +37,4 @@ void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { } uint32_t transport_send_frame(uint8_t to, uint8_t* data, uint16_t size) { - return ++current_send_frame; } diff --git a/serial_link/protocol/transport.h b/serial_link/protocol/transport.h index 6f2cf277f..86086b8b8 100644 --- a/serial_link/protocol/transport.h +++ b/serial_link/protocol/transport.h @@ -28,63 +28,66 @@ SOFTWARE. #include "protocol/triple_buffered_object.h" #define NUM_SLAVES 8 +#define LOCAL_OBJECT_EXTRA 16 + +// master -> slave = 1 local(target all), 1 remote object +// slave -> master = 1 local(target 0), multiple remote objects +// master -> single slave (multiple local, target id), 1 remote object +typedef enum { + MASTER_TO_ALL_SLAVES, + MASTER_TO_SINGLE_SLAVE, + SLAVE_TO_MASTER, +} remote_object_type; typedef struct { - uint16_t element_size; - uint16_t buffer_size; - uint8_t is_master; + remote_object_type object_type; + uint16_t object_size; uint8_t buffer[] __attribute__((aligned(4))); } remote_object_t; -typedef struct { - uint16_t element_size; - uint8_t destination; - uint8_t buffer[] __attribute__((aligned(4))); -} local_object_t; +#define REMOTE_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + objectsize * 3) +#define LOCAL_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) -#define REMOTE_OBJECT_BUFFER(id, type) \ -typedef struct { \ - triple_buffer_object_t object; \ - type buffer[3]; \ -} remote_object_buffer_##id##_t; - -#define MASTER_REMOTE_OBJECT(id, type) \ -REMOTE_OBJECT_BUFFER(id, type) \ +#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \ typedef struct { \ remote_object_t object; \ - remote_object_buffer_##id##_t buffer; \ -} master_remote_object_##id##_t; \ -master_remote_object_##id##_t remote_object_##id = { \ - .object = { \ - .element_size = sizeof(type), \ - .buffer_size = sizeof(remote_object_buffer_##id##_t), \ - .is_master = true \ - }}; + uint8_t buffer[ \ + num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \ + num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ +} remote_object_##name##_t; -#define SLAVE_REMOTE_OBJECT(id, type) \ -REMOTE_OBJECT_BUFFER(id, type) \ -typedef struct { \ - remote_object_t object; \ - remote_object_buffer_##id##_t buffer[NUM_SLAVES];\ -} slave_remote_object_##id##_t; \ -slave_remote_object_##id##_t remote_object_##id = { \ - .object = { \ - .element_size = sizeof(type), \ - .buffer_size = sizeof(remote_object_buffer_##id##_t), \ - .is_master = true \ - }}; +#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_ALL_SLAVES, \ + .object_size = sizeof(type), \ + } \ + }; -#define LOCAL_OBJECT(id, type) \ -typedef struct { \ - uint32_t element_size; \ - uint8_t buffer[NUM_SLAVES][sizeof(type) + 16][3]; \ -} remote_object_##id##_t; \ -remote_object_##id##_t remote_object_##id = {.element_size = sizeof(type) + 16}; +#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_SINGLE_SLAVE, \ + .object_size = sizeof(type), \ + } \ + }; -#define REMOTE_OBJECT(id) (remote_object_t*)&remote_object_##id +#define SLAVE_TO_MASTER_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = SLAVE_TO_MASTER, \ + .object_size = sizeof(type), \ + } \ + }; +#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name -void init_transport(void); +void init_transport(remote_object_t* remote_objects, uint32_t num_remote_objects); void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); uint32_t transport_send_frame(uint8_t to, uint8_t* data, uint16_t size); diff --git a/serial_link/tests/transport_tests.c b/serial_link/tests/transport_tests.c index f9f5b4773..31e7b2dc7 100644 --- a/serial_link/tests/transport_tests.c +++ b/serial_link/tests/transport_tests.c @@ -34,32 +34,21 @@ typedef struct { uint32_t test2; } test_object2_t; -MASTER_REMOTE_OBJECT(0, test_object1_t); -SLAVE_REMOTE_OBJECT(1, test_object1_t); -MASTER_REMOTE_OBJECT(2, test_object2_t); -SLAVE_REMOTE_OBJECT(3, 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); -// We want -// master -> slave = 1 local(target all), 1 remote object -// slave -> master = 1 local(target 0), multiple remote objects -// master -> single slave (multiple local, target id), 1 remote object - -remote_object_t* remote_objects[] = { - REMOTE_OBJECT(0), - REMOTE_OBJECT(1), - REMOTE_OBJECT(2), - REMOTE_OBJECT(3), +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) { - init_transport(); + init_transport(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t)); } AfterEach(Transport) {} -Ensure(Transport, packet_number_is_sequential) { - assert_that(transport_send_frame(0, NULL, 0), is_equal_to(1)); - assert_that(transport_send_frame(0, NULL, 0), is_equal_to(2)); - // It doesn't matter if the destination changes - assert_that(transport_send_frame(1, NULL, 0), is_equal_to(3)); +Ensure(Transport, write_to_local_signals_an_event) { }