Test all canutil functions and document in README.
authorChristopher Peplin <chris.peplin@rhubarbtech.com>
Sun, 29 Dec 2013 18:57:37 +0000 (13:57 -0500)
committerChristopher Peplin <chris.peplin@rhubarbtech.com>
Sun, 29 Dec 2013 18:57:37 +0000 (13:57 -0500)
README.mkd
src/canutil/read.h
src/canutil/write.c
src/canutil/write.h
tests/write_tests.c

index 8f6ac5f..b96d587 100644 (file)
@@ -3,26 +3,46 @@ CAN Message Utilities for C
 
 ## Bitfield Manipulation
 
+    uint8_t data[4] = {0x12, 0x34, 0x56, 0x78};
+    uint8_t result = getByte(data, sizeof(data), 0);
+    uint8_t result = getNibble(data, sizeof(data), 0);
+    fail_unless(copyBitsRightAligned(data, 4, 4, 12, result, 4));
+
+## 8 Byte Bitfield Manipulation
+
+TODO setting bit fields is just copying
+TODO bring back old uint64_t implementation of getBitField if it's faster /
+    simpler
+
 ## CAN Signal Encoding
 
+The library supports encoding floating point CAN signals as well as booleans
+into a uint64_t payload.
+
+    uint64_t payload = bitfield_encode_float(1, 1, 3, 1, 0)
+    // payload == 0x1000000000000000
+
+    payload = bitfield_encode_bool(true, 1, 3);
+    // payload == 0x1000000000000000
+
 ## CAN Signal Decoding
 
 The library supports parsing floating point CAN signals as well as booleans.
 
     uint64_t payload = 0xeb00000000000000;
-    float result = bitfield_parse_float(payload,
+    float float_result = bitfield_parse_float(payload,
             2, // starting bit
             4, // width of the signal's field
             1001.0, // transformation factor for the signal value
             -30000.0); // transformation offset for the signal value
-    // result == -19990.0
+    // float_result == -19990.0
 
-    bool result = bitfield_parse_bool(payload,
+    bool bool_result = bitfield_parse_bool(payload,
             0, // starting bit
             1, // width of the signal's field
             1.0, // transformation factor for the signal value
             0); // transformation offset for the signal value
-    // result == true
+    // bool_result == true
 
 ## Testing
 
index 028b03a..865bb27 100644 (file)
@@ -10,20 +10,28 @@ extern "C" {
 
 /* Public: Parse a CAN signal from a message and apply required transformation.
  *
- * signal - The details of the signal to decode and forward.
- * data   - The raw bytes of the CAN message that contains the signal, assumed
- *      to be in big-endian byte order from CAN.
+ * data - the payload containing the signal.
+ * bit_offset - the starting bit for the signal.
+ * bit_size - the width of the signal.
+ * factor - the transformation factor for the signal value, applied after
+ *      pulling out the bit field. Use 1.0 for no factor.
+ * offset - the transformation offset for the signal value, applied after
+ *      pulling out the bit field. Use 0 for no offset.
  *
- * Returns the final, transformed value of the signal.
+ * Returns the decoded and transformed value of the signal.
  */
 float bitfield_parse_float(uint64_t data, uint8_t bit_offset, uint8_t bit_size,
         float factor, float offset);
 
 /* Public: Parse a CAN signal from a message and interpret it as a boolean.
  *
- * signal - The details of the signal to decode and forward.
- * data   - The raw bytes of the CAN message that contains the signal, assumed
- *      to be in big-endian byte order from CAN.
+ * data - the payload containing the signal.
+ * bit_offset - the starting bit for the signal.
+ * bit_size - the width of the signal.
+ * factor - the transformation factor for the signal value, applied after
+ *      pulling out the bit field. Use 1.0 for no factor.
+ * offset - the transformation offset for the signal value, applied after
+ *      pulling out the bit field. Use 0 for no offset.
  *
  * Returns false if the value was 0, otherwise true.
  */
index 14d2a44..583c251 100644 (file)
@@ -9,11 +9,13 @@ uint64_t bitfield_encode_float(float value, uint8_t bit_offset, uint8_t bit_size
         raw += 0.5;
     }
     uint64_t result = 0;
-    set_bit_field(&result, (uint64_t)raw, bit_offset, bit_size);
+    if(!set_bit_field(&result, (uint64_t)raw, bit_offset, bit_size)) {
+        // debug("%f will not fit in a %d bit field", value, bit_size);
+    }
     return result;
 }
 
-uint64_t bitfield_encode_bool(bool value, uint8_t bit_offset, uint8_t bit_size,
-        float factor, float offset) {
-    return bitfield_encode_float(value, offset, factor, bit_offset, bit_size);
+uint64_t bitfield_encode_bool(const bool value, const uint8_t bit_offset,
+        const uint8_t bit_size) {
+    return bitfield_encode_float(value, bit_offset, bit_size, 1.0, 0);
 }
index 3d13b1d..f117a06 100644 (file)
@@ -8,11 +8,35 @@
 extern "C" {
 #endif
 
+/* Public: Encode a floating point number into a fixed point, fixed bit width
+ *      field in a bit array.
+ *
+ * value - the floating point value to encode.
+ * bit_offset - the starting point for the encoded bits in the returned value.
+ * bit_size - The max width of the field in the resulting bit array. If bit_size
+ *      isn't big enough to store the fixed point version of the value, the bitfeld
+ *      will *not* be set. TODO some error reporting would be nice.
+ * factor - a factor used to transform from floating to fixed point before
+ *      encoding. Use 1.0 for no factor.
+ * offset - an offset used to transform from floating to fixed point before
+ *      encoding. Use 0 for no offset.
+ *
+ * Returns a big-endian uint64_t with the value encoded as a bitfield.
+ */
 uint64_t bitfield_encode_float(float value, uint8_t bit_offset, uint8_t bit_size,
                 float factor, float offset);
 
-uint64_t bitfield_encode_bool(bool value, uint8_t bit_offset, uint8_t bit_size,
-                float factor, float offset);
+/* Public: Encode a boolean into fixed bit width field in a bit array.
+ *
+ * value - the boolean value to encode - true will be 1, false will be 0.
+ * bit_offset - the starting point for the encoded bits in the returned value.
+ * bit_size - The max width of the field in the resulting bit array. If bit_size
+ *      isn't big enough to store the fixed point version of the value, the bitfeld
+ *      will *not* be set. TODO some error reporting would be nice.
+ *
+ * Returns a big-endian uint64_t with the value encoded as a bitfield.
+ */
+uint64_t bitfield_encode_bool(const bool value, const uint8_t bit_offset, const uint8_t bit_size);
 
 #ifdef __cplusplus
 }
index ed555f6..8cc35e2 100644 (file)
@@ -6,6 +6,9 @@ START_TEST (test_encode_can_signal)
 {
     uint64_t value = bitfield_encode_float(0, 1, 3, 1, 0);
     ck_assert_int_eq(value, 0);
+
+    value = bitfield_encode_float(1, 1, 3, 1, 0);
+    ck_assert_int_eq(value, 0x1000000000000000LLU);
 }
 END_TEST
 
@@ -16,11 +19,22 @@ START_TEST (test_encode_can_signal_rounding_precision)
 }
 END_TEST
 
+START_TEST (test_encode_bool)
+{
+    uint64_t value = bitfield_encode_bool(true, 1, 3);
+    ck_assert_int_eq(value, 0x1000000000000000LLU);
+    value = bitfield_encode_bool(false, 1, 3);
+    ck_assert_int_eq(value, 0x0000000000000000LLU);
+}
+END_TEST
+// TODO test encode bool
+
 Suite* canwriteSuite(void) {
     Suite* s = suite_create("write");
     TCase *tc_core = tcase_create("core");
     tcase_add_checked_fixture(tc_core, NULL, NULL);
     tcase_add_test(tc_core, test_encode_can_signal);
+    tcase_add_test(tc_core, test_encode_bool);
     tcase_add_test(tc_core, test_encode_can_signal_rounding_precision);
     suite_add_tcase(s, tc_core);