diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/bin.c | 64 | ||||
-rw-r--r-- | shared/bin.h | 52 | ||||
-rw-r--r-- | shared/consts.h | 17 | ||||
-rw-r--r-- | shared/makefile | 2 | ||||
-rw-r--r-- | shared/readme.md | 8 |
5 files changed, 143 insertions, 0 deletions
diff --git a/shared/bin.c b/shared/bin.c new file mode 100644 index 0000000..a2c91a4 --- /dev/null +++ b/shared/bin.c @@ -0,0 +1,64 @@ +#include <stdlib.h> + +#include "bin.h" + +#define W2_ENDIAN_LITTLE (1) +#define W2_ENDIAN_BIG (0) + +#define _SHIFT_0B (8 * 0) +#define _SHIFT_1B (8 * 1) +#define _SHIFT_2B (8 * 2) +#define _SHIFT_3B (8 * 3) +#define _BYTE_0 ((uint32_t)(0xff << (_SHIFT_0B))) +#define _BYTE_1 ((uint32_t)(0xff << (_SHIFT_1B))) +#define _BYTE_2 ((uint32_t)(0xff << (_SHIFT_2B))) +#define _BYTE_3 ((uint32_t)(0xff << (_SHIFT_3B))) + +const uint8_t W2_STRUCT_T_SIZES[] = {sizeof(uint8_t), sizeof(uint16_t), sizeof(uint32_t)}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshift-count-overflow" +w2_s_bin *w2_bin_from_uint8_t(uint8_t data) { + size_t size = 1; + w2_s_bin *ret = malloc(sizeof(w2_s_bin) + sizeof(uint8_t) * size); + ret->bytes = size; + ret->data[0] = data; + return ret; +} + +w2_s_bin *w2_bin_from_uint16_t(uint16_t data) { + size_t size = 2; + w2_s_bin *ret = malloc(sizeof(w2_s_bin) + sizeof(uint8_t) * size); + data = w2_bin_hton16(data); + ret->bytes = size; + ret->data[0] = (data & _BYTE_1) >> _SHIFT_1B; + ret->data[1] = (data & _BYTE_0) >> _SHIFT_0B; + return ret; +} + +w2_s_bin *w2_bin_from_uint32_t(uint32_t data) { + size_t size = 4; + w2_s_bin *ret = malloc(sizeof(w2_s_bin) + sizeof(uint8_t) * size); + data = w2_bin_hton32(data); + ret->bytes = size; + ret->data[0] = (data & _BYTE_3) >> _SHIFT_3B; + ret->data[1] = (data & _BYTE_2) >> _SHIFT_2B; + ret->data[2] = (data & _BYTE_1) >> _SHIFT_1B; + ret->data[3] = (data & _BYTE_0) >> _SHIFT_0B; + return ret; +} + +uint32_t w2_bin_hton32(uint32_t h32) { + if (g_w2_endianness == W2_ENDIAN_BIG) return h32; + return ((h32 & _BYTE_0) << _SHIFT_3B) | ((h32 & _BYTE_1) << _SHIFT_1B) | + ((h32 & _BYTE_2) >> _SHIFT_1B) | ((h32 & _BYTE_3) >> _SHIFT_3B); +} +#pragma GCC diagnostic pop + +uint16_t w2_bin_hton16(uint16_t h16) { + if (g_w2_endianness == W2_ENDIAN_BIG) return h16; + return ((h16 & _BYTE_0) << _SHIFT_1B) | ((h16 & _BYTE_1) >> _SHIFT_1B); +} + +uint32_t w2_bin_ntoh32(uint32_t n32) { return w2_bin_hton32(n32); } +uint16_t w2_bin_ntoh16(uint16_t n16) { return w2_bin_hton16(n16); } diff --git a/shared/bin.h b/shared/bin.h new file mode 100644 index 0000000..1c9b951 --- /dev/null +++ b/shared/bin.h @@ -0,0 +1,52 @@ +#pragma once +/** + * helper file for binary data + * + * - fix endianness with functions inspired by UNIX arpa/inet.h + * - convert uint16_t and uint32_t to w2_s_bin + */ + +#include <stdint.h> + +extern uint8_t g_w2_endianness; + +#define W2_T_UINT8_T (0) +#define W2_T_UINT16_T (1) +#define W2_T_UINT32_T (2) + +enum w2_e_struct_types { + W2_ST_UINT8_T, + W2_ST_UINT16_T, + W2_ST_UINT32_T, +}; + +extern const uint8_t W2_STRUCT_T_SIZES[]; + +typedef struct { + uint16_t bytes; + uint8_t data[]; +} w2_s_bin; + +typedef struct { + enum w2_e_struct_types type; + uint16_t length; + const uint8_t *data; +} w2_s_struct_property; + +typedef struct { + uint16_t length; + w2_s_struct_property *properties[]; +} w2_s_property_list; + +w2_s_bin *w2_bin_from_uint8_t(uint8_t data); +w2_s_bin *w2_bin_from_uint16_t(uint16_t data); +w2_s_bin *w2_bin_from_uint32_t(uint32_t data); + +/** convert 32-bit value from host endian to network (big-endian) */ +uint32_t w2_bin_hton32(uint32_t h32); +/** convert 16-bit value from host endian to network (big-endian) */ +uint16_t w2_bin_hton16(uint16_t h16); +/** convert 32-bit value from network (big-endian) to host endian */ +uint32_t w2_bin_ntoh32(uint32_t n32); +/** convert 16-bit value from network (big-endian) to host endian */ +uint16_t w2_bin_ntoh16(uint16_t n16); diff --git a/shared/consts.h b/shared/consts.h new file mode 100644 index 0000000..70efcac --- /dev/null +++ b/shared/consts.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef W2_BUILD_STR +// is defined by CFLAGS += -DW2_BUILD_STR in makefile +#define W2_BUILD_STR ("????????") +#endif + +/** max logic module execution time in milliseconds */ +#define W2_MAX_MODULE_CYCLE_MS (20) +/** serial baud rate (bit/s) */ +#define W2_SERIAL_BAUD (9600) +/** size of the error handling buffer (in errors, not bytes) */ +#define W2_ERROR_BUFFER_SIZE (16) +/** size of the serial communication buffer (in messages, not bytes) */ +#define W2_SERCOMM_BUFFER_SIZE (16) +/** size of input (receive) buffer (in bytes) */ +#define W2_SERIAL_READ_BUFFER_SIZE (255) diff --git a/shared/makefile b/shared/makefile new file mode 100644 index 0000000..815d33c --- /dev/null +++ b/shared/makefile @@ -0,0 +1,2 @@ +SOURCES += $(wildcard ../shared/*.c) +HEADERS += $(wildcard ../shared/*.h) diff --git a/shared/readme.md b/shared/readme.md new file mode 100644 index 0000000..870f015 --- /dev/null +++ b/shared/readme.md @@ -0,0 +1,8 @@ +# shared code + +this is the subdirectory for all code that is shared between the robot code and +the client code. to use these, include the .h files with a relative path (e.g. +`#include "../shared/consts.h"`). makefiles should add `include +../shared/makefile` to add the .c and .h files to `$SOURCES` and `$HEADERS` in +the makefile targets (this is already done for the robot and client +subdirectories). |