diff options
| -rw-r--r-- | fw/Makefile | 2 | ||||
| -rw-r--r-- | fw/signal.c | 93 | ||||
| -rw-r--r-- | fw/signal.h | 33 | ||||
| -rw-r--r-- | fw/signal_utestable.h | 2 | ||||
| -rw-r--r-- | fw/tests/unit/signal_utests.c | 51 | ||||
| -rw-r--r-- | fw/tests/unit/types_utests.c | 63 | ||||
| -rw-r--r-- | fw/tests/unit/types_utests.h | 5 |
7 files changed, 180 insertions, 69 deletions
diff --git a/fw/Makefile b/fw/Makefile index 1c0fb95..4d88b3a 100644 --- a/fw/Makefile +++ b/fw/Makefile @@ -38,7 +38,7 @@ UTEST_INCLUDES = -I. -I $(UNITY_DIR) UTEST_CFLAGS = -std=c99 -Wall $(UTEST_INCLUDES) UTEST_LDFLAGS = UTEST_BIN = $(basename $(wildcard $(UTEST_DIR)/*.c)) -UTEST_SRC = $(wildcard $(UTEST_DIR)/*.c) $(UNITY_DIR)/unity.c +UTEST_SRC = $(wildcard $(UTEST_DIR)/*.c) $(UNITY_DIR)/unity.c signal.c UTEST_OBJ = $(UTEST_SRC:.c=.o) UTEST_HDR = $(wildcard $(UTEST_DIR)/*.h) $(UNITY_DIR)/unity.h diff --git a/fw/signal.c b/fw/signal.c new file mode 100644 index 0000000..30916e0 --- /dev/null +++ b/fw/signal.c @@ -0,0 +1,93 @@ +#include <stdbool.h> +#include <stdint.h> + +#include "types.h" +#include "can.h" + +#include "signal.h" +#include "signal_utestable.h" + +// Extract a little-endian value from a frame. +// Assumes signal is within the frame's DATA FIELD. +Status +pluckLE(const SigFmt *sig, const CanFrame *frame, U32 *raw) { + // TODO +} + +// Extract a big-endian value from a frame. +// Assumes signal is within the frame's DATA FIELD. +void +pluckBE(const SigFmt *sig, const CanFrame *frame, U32 *raw) { + U8 i, end, mask; + + *raw = 0ul; + end = sig->start+sig->size; + + // First iteration starts at arbitrary bit: namely the (i%8)'th bit. + // Subsequent iterations start at bit 0 of each byte. + + for (i = sig->start; i < end; i += 8u-(i%8u)) { + mask = 0xFF << (i%8u); + if (i/8u == end/8u) { // if end in this byte + mask >>= (8u - (end%8u)); // ignore top bits + *raw <<= (end%8u) - (i%8u); // include bits between i and end + } else { + *raw <<= 8u - (i%8u); // include bits between i and end of byte + } + *raw |= (frame->data[i/8u] & mask) >> (i%8u); + } +} + +Status +sigPluck(const SigFmt *sig, const CanFrame *frame, Number *raw) { + // Preconditions + if ( + (sig->start >= (8u * frame->dlc)) // signal starts outside DATA FIELD + || (sig->size > (8u * frame->dlc - sig->start)) // signal extends outside DATA FIELD + || (sig->size < 1u) // signal is empty + ) { + return FAIL; + } + + // Read signal into U32 + switch (sig->order) { + case LITTLE_ENDIAN: + pluckLE(sig, frame, &raw->u32); + break; + case BIG_ENDIAN: + pluckBE(sig, frame, &raw->u32); + break; + default: + return FAIL; // invalid byte order + } + + // Shrink signal to appropriate size and set +/- sign + if (sig->size <= 8u) { + raw->u8 = raw->u32 & 0xFF; + if (sig->isSigned) { + raw->type = NUM_I8; + raw->i8 = *(I8 *)&raw->u8; + } else { + raw->type = NUM_U8; + } + } else if (sig->size <= 16u) { + raw->u16 = raw->u32 & 0xFFFF; + if (sig->isSigned) { + raw->type = NUM_I16; + raw->i16 = *(I16 *)&raw->u16; + } else { + raw->type = NUM_U16; + } + } else if (sig->size <= 32u) { + if (sig->isSigned) { + raw->type = NUM_I32; + raw->i32 = *(I32 *)&raw->u32; + } else { + raw->type = NUM_U32; + } + } else { + return FAIL; // signal too big + } + + return OK; +} diff --git a/fw/signal.h b/fw/signal.h new file mode 100644 index 0000000..8bbc120 --- /dev/null +++ b/fw/signal.h @@ -0,0 +1,33 @@ +/** DBC Signals. + * See "DBC File Format Documentation" v.01/2007 + * + * Device PIC16F1459 + * Compiler: XC8 v3.00 + * + * Usage: + * + * #include <stdbool.h> + * #include <stdint.h> + * #include "types.h" + * #include "can.h" + * #include "signal.h" + */ + +// Byte order +typedef enum { + LITTLE_ENDIAN = 0, + BIG_ENDIAN, +} ByteOrder; + +// A Signal Format defines how a DBC signal is encoded in a CAN frame. +typedef struct { + CanId id; // ID of message containing the signal + U8 start; // start bit -- position of signal within DATA FIELD + U8 size; // size of the signal in bits + ByteOrder order; // little-endian/big-endian + bool isSigned; +} SigFmt; + +// Extract the raw signal value out of a CAN frame's DATA FIELD. +// Assumes the frame's ID matches that of the signal. +Status sigPluck(const SigFmt *sig, const CanFrame *frame, Number *raw); diff --git a/fw/signal_utestable.h b/fw/signal_utestable.h new file mode 100644 index 0000000..6ab802b --- /dev/null +++ b/fw/signal_utestable.h @@ -0,0 +1,2 @@ +Status pluckLE(const SigFmt *sig, const CanFrame *frame, U32 *raw); +void pluckBE(const SigFmt *sig, const CanFrame *frame, U32 *raw); diff --git a/fw/tests/unit/signal_utests.c b/fw/tests/unit/signal_utests.c new file mode 100644 index 0000000..ebce8f6 --- /dev/null +++ b/fw/tests/unit/signal_utests.c @@ -0,0 +1,51 @@ +#include <stdbool.h> +#include <stdint.h> + +#include <unity.h> + +#include <types.h> +#include <can.h> +#include <signal.h> +#include <signal_utestable.h> + +void setUp(void) {} +void tearDown(void) {} + +static void +testPluckLE(void) { + setUp(); + + // TODO + TEST_ASSERT(0); + + tearDown(); +} + +static void +testPluckBE(void) { + setUp(); + + // 1111 1111 (1110 11)10 (1111 0010) 1111 1(101) + // 7 0 15 8 23 16 31 24 + CanFrame frame = {.data = {0xFF, 0xEE, 0xF2, 0xFD}}; + SigFmt sig = { + .start = 10u, + .size = 17u, + }; + U32 want = 0x1DF95; + U32 got; + pluckBE(&sig, &frame, &got); + TEST_ASSERT_EQUAL_UINT32(want, got); + + tearDown(); +} + +int +main(void) { + UnityBegin(__FILE__); + + RUN_TEST(testPluckLE); + RUN_TEST(testPluckBE); + + return UnityEnd(); +} diff --git a/fw/tests/unit/types_utests.c b/fw/tests/unit/types_utests.c deleted file mode 100644 index 578a100..0000000 --- a/fw/tests/unit/types_utests.c +++ /dev/null @@ -1,63 +0,0 @@ -#include <stdbool.h> -#include <stdint.h> - -#include <unity.h> - -#include <types.h> - -void setUp(void) {} -void tearDown(void) {} - -void -testAddU16(void) { - setUp(); - // TODO - TEST_ASSERT(false); - tearDown(); -} - -void -testAddU16U8(void) { - setUp(); - // TODO - TEST_ASSERT(false); - tearDown(); -} - -void -testLshiftU16(void) { - setUp(); - // TODO - TEST_ASSERT(false); - tearDown(); -} - -void -testRshiftU16(void) { - setUp(); - // TODO - TEST_ASSERT(false); - tearDown(); -} - -void -testCmpU16(void) { - setUp(); - // TODO - TEST_ASSERT(false); - tearDown(); -} - -int -main(void) { - UnityBegin(__FILE__); - - // Types - RUN_TEST(testAddU16); - RUN_TEST(testAddU16U8); - RUN_TEST(testLshiftU16); - RUN_TEST(testRshiftU16); - RUN_TEST(testCmpU16); - - return UnityEnd(); -} diff --git a/fw/tests/unit/types_utests.h b/fw/tests/unit/types_utests.h deleted file mode 100644 index 1923727..0000000 --- a/fw/tests/unit/types_utests.h +++ /dev/null @@ -1,5 +0,0 @@ -testAddU16(void); -testAddU16U8(void); -testLshiftU16(void); -testRshiftU16(void); -testCmpU16(void); |