summaryrefslogtreecommitdiffstats
path: root/CAN-binder/libs/nanopb/examples/using_double_on_avr
diff options
context:
space:
mode:
Diffstat (limited to 'CAN-binder/libs/nanopb/examples/using_double_on_avr')
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/Makefile24
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/README.txt25
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/decode_double.c33
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.c123
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.h26
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/doubleproto.proto15
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/encode_double.c25
-rw-r--r--CAN-binder/libs/nanopb/examples/using_double_on_avr/test_conversions.c56
8 files changed, 0 insertions, 327 deletions
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/Makefile b/CAN-binder/libs/nanopb/examples/using_double_on_avr/Makefile
deleted file mode 100644
index 874a64b..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-# Include the nanopb provided Makefile rules
-include ../../extra/nanopb.mk
-
-# Compiler flags to enable all warnings & debug info
-CFLAGS = -Wall -Werror -g -O0
-CFLAGS += -I$(NANOPB_DIR)
-
-all: run_tests
-
-.SUFFIXES:
-
-clean:
- rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
-
-test_conversions: test_conversions.c double_conversion.c
- $(CC) $(CFLAGS) -o $@ $^
-
-%: %.c double_conversion.c doubleproto.pb.c
- $(CC) $(CFLAGS) -o $@ $^ $(NANOPB_CORE)
-
-run_tests: test_conversions encode_double decode_double
- ./test_conversions
- ./encode_double | ./decode_double
-
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/README.txt b/CAN-binder/libs/nanopb/examples/using_double_on_avr/README.txt
deleted file mode 100644
index d9fcdfc..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/README.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Nanopb example "using_double_on_avr"
-====================================
-
-Some processors/compilers, such as AVR-GCC, do not support the double
-datatype. Instead, they have sizeof(double) == 4. Because protocol
-binary format uses the double encoding directly, this causes trouble
-if the protocol in .proto requires double fields.
-
-This directory contains a solution to this problem. It uses uint64_t
-to store the raw wire values, because its size is correct on all
-platforms. The file double_conversion.c provides functions that
-convert these values to/from floats, without relying on compiler
-support.
-
-To use this method, you need to make some modifications to your code:
-
-1) Change all 'double' fields into 'fixed64' in the .proto.
-
-2) Whenever writing to a 'double' field, use float_to_double().
-
-3) Whenever reading a 'double' field, use double_to_float().
-
-The conversion routines are as accurate as the float datatype can
-be. Furthermore, they should handle all special values (NaN, inf, denormalized
-numbers) correctly. There are testcases in test_conversions.c.
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/decode_double.c b/CAN-binder/libs/nanopb/examples/using_double_on_avr/decode_double.c
deleted file mode 100644
index 5802eca..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/decode_double.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Decodes a double value into a float variable.
- * Used to read double values with AVR code, which doesn't support double directly.
- */
-
-#include <stdio.h>
-#include <pb_decode.h>
-#include "double_conversion.h"
-#include "doubleproto.pb.h"
-
-int main()
-{
- uint8_t buffer[32];
- size_t count = fread(buffer, 1, sizeof(buffer), stdin);
- pb_istream_t stream = pb_istream_from_buffer(buffer, count);
-
- AVRDoubleMessage message;
- pb_decode(&stream, AVRDoubleMessage_fields, &message);
-
- float v1 = double_to_float(message.field1);
- float v2 = double_to_float(message.field2);
-
- printf("Values: %f %f\n", v1, v2);
-
- if (v1 == 1234.5678f &&
- v2 == 0.00001f)
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.c b/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.c
deleted file mode 100644
index cf79b9a..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Conversion routines for platforms that do not support 'double' directly. */
-
-#include "double_conversion.h"
-#include <math.h>
-
-typedef union {
- float f;
- uint32_t i;
-} conversion_t;
-
-/* Note: IEE 754 standard specifies float formats as follows:
- * Single precision: sign, 8-bit exp, 23-bit frac.
- * Double precision: sign, 11-bit exp, 52-bit frac.
- */
-
-uint64_t float_to_double(float value)
-{
- conversion_t in;
- in.f = value;
- uint8_t sign;
- int16_t exponent;
- uint64_t mantissa;
-
- /* Decompose input value */
- sign = (in.i >> 31) & 1;
- exponent = ((in.i >> 23) & 0xFF) - 127;
- mantissa = in.i & 0x7FFFFF;
-
- if (exponent == 128)
- {
- /* Special value (NaN etc.) */
- exponent = 1024;
- }
- else if (exponent == -127)
- {
- if (!mantissa)
- {
- /* Zero */
- exponent = -1023;
- }
- else
- {
- /* Denormalized */
- mantissa <<= 1;
- while (!(mantissa & 0x800000))
- {
- mantissa <<= 1;
- exponent--;
- }
- mantissa &= 0x7FFFFF;
- }
- }
-
- /* Combine fields */
- mantissa <<= 29;
- mantissa |= (uint64_t)(exponent + 1023) << 52;
- mantissa |= (uint64_t)sign << 63;
-
- return mantissa;
-}
-
-float double_to_float(uint64_t value)
-{
- uint8_t sign;
- int16_t exponent;
- uint32_t mantissa;
- conversion_t out;
-
- /* Decompose input value */
- sign = (value >> 63) & 1;
- exponent = ((value >> 52) & 0x7FF) - 1023;
- mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */
-
- /* Figure if value is in range representable by floats. */
- if (exponent == 1024)
- {
- /* Special value */
- exponent = 128;
- }
- else if (exponent > 127)
- {
- /* Too large */
- if (sign)
- return -INFINITY;
- else
- return INFINITY;
- }
- else if (exponent < -150)
- {
- /* Too small */
- if (sign)
- return -0.0f;
- else
- return 0.0f;
- }
- else if (exponent < -126)
- {
- /* Denormalized */
- mantissa |= 0x1000000;
- mantissa >>= (-126 - exponent);
- exponent = -127;
- }
-
- /* Round off mantissa */
- mantissa = (mantissa + 1) >> 1;
-
- /* Check if mantissa went over 2.0 */
- if (mantissa & 0x800000)
- {
- exponent += 1;
- mantissa &= 0x7FFFFF;
- mantissa >>= 1;
- }
-
- /* Combine fields */
- out.i = mantissa;
- out.i |= (uint32_t)(exponent + 127) << 23;
- out.i |= (uint32_t)sign << 31;
-
- return out.f;
-}
-
-
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.h b/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.h
deleted file mode 100644
index 62b6a8a..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/double_conversion.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* AVR-GCC does not have real double datatype. Instead its double
- * is equal to float, i.e. 32 bit value. If you need to communicate
- * with other systems that use double in their .proto files, you
- * need to do some conversion.
- *
- * These functions use bitwise operations to mangle floats into doubles
- * and then store them in uint64_t datatype.
- */
-
-#ifndef DOUBLE_CONVERSION
-#define DOUBLE_CONVERSION
-
-#include <stdint.h>
-
-/* Convert native 4-byte float into a 8-byte double. */
-extern uint64_t float_to_double(float value);
-
-/* Convert 8-byte double into native 4-byte float.
- * Values are rounded to nearest, 0.5 away from zero.
- * Overflowing values are converted to Inf or -Inf.
- */
-extern float double_to_float(uint64_t value);
-
-
-#endif
-
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/doubleproto.proto b/CAN-binder/libs/nanopb/examples/using_double_on_avr/doubleproto.proto
deleted file mode 100644
index 72d3f9c..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/doubleproto.proto
+++ /dev/null
@@ -1,15 +0,0 @@
-// A message containing doubles, as used by other applications.
-syntax = "proto2";
-
-message DoubleMessage {
- required double field1 = 1;
- required double field2 = 2;
-}
-
-// A message containing doubles, but redefined using uint64_t.
-// For use in AVR code.
-message AVRDoubleMessage {
- required fixed64 field1 = 1;
- required fixed64 field2 = 2;
-}
-
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/encode_double.c b/CAN-binder/libs/nanopb/examples/using_double_on_avr/encode_double.c
deleted file mode 100644
index cd532d4..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/encode_double.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Encodes a float value into a double on the wire.
- * Used to emit doubles from AVR code, which doesn't support double directly.
- */
-
-#include <stdio.h>
-#include <pb_encode.h>
-#include "double_conversion.h"
-#include "doubleproto.pb.h"
-
-int main()
-{
- AVRDoubleMessage message = {
- float_to_double(1234.5678f),
- float_to_double(0.00001f)
- };
-
- uint8_t buffer[32];
- pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
-
- pb_encode(&stream, AVRDoubleMessage_fields, &message);
- fwrite(buffer, 1, stream.bytes_written, stdout);
-
- return 0;
-}
-
diff --git a/CAN-binder/libs/nanopb/examples/using_double_on_avr/test_conversions.c b/CAN-binder/libs/nanopb/examples/using_double_on_avr/test_conversions.c
deleted file mode 100644
index 22620a6..0000000
--- a/CAN-binder/libs/nanopb/examples/using_double_on_avr/test_conversions.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "double_conversion.h"
-#include <math.h>
-#include <stdio.h>
-
-static const double testvalues[] = {
- 0.0, -0.0, 0.1, -0.1,
- M_PI, -M_PI, 123456.789, -123456.789,
- INFINITY, -INFINITY, NAN, INFINITY - INFINITY,
- 1e38, -1e38, 1e39, -1e39,
- 1e-38, -1e-38, 1e-39, -1e-39,
- 3.14159e-37,-3.14159e-37, 3.14159e-43, -3.14159e-43,
- 1e-60, -1e-60, 1e-45, -1e-45,
- 0.99999999999999, -0.99999999999999, 127.999999999999, -127.999999999999
-};
-
-#define TESTVALUES_COUNT (sizeof(testvalues)/sizeof(testvalues[0]))
-
-int main()
-{
- int status = 0;
- int i;
- for (i = 0; i < TESTVALUES_COUNT; i++)
- {
- double orig = testvalues[i];
- float expected_float = (float)orig;
- double expected_double = (double)expected_float;
-
- float got_float = double_to_float(*(uint64_t*)&orig);
- uint64_t got_double = float_to_double(got_float);
-
- uint32_t e1 = *(uint32_t*)&expected_float;
- uint32_t g1 = *(uint32_t*)&got_float;
- uint64_t e2 = *(uint64_t*)&expected_double;
- uint64_t g2 = got_double;
-
- if (g1 != e1)
- {
- printf("%3d double_to_float fail: %08x != %08x\n", i, g1, e1);
- status = 1;
- }
-
- if (g2 != e2)
- {
- printf("%3d float_to_double fail: %016llx != %016llx\n", i,
- (unsigned long long)g2,
- (unsigned long long)e2);
- status = 1;
- }
- }
-
- return status;
-}
-
-
-
-