summaryrefslogtreecommitdiff
path: root/digital/avr/modules/math/fixed/test
diff options
context:
space:
mode:
Diffstat (limited to 'digital/avr/modules/math/fixed/test')
-rw-r--r--digital/avr/modules/math/fixed/test/Makefile38
-rw-r--r--digital/avr/modules/math/fixed/test/avrconfig.h86
-rw-r--r--digital/avr/modules/math/fixed/test/test_fixed.c247
3 files changed, 371 insertions, 0 deletions
diff --git a/digital/avr/modules/math/fixed/test/Makefile b/digital/avr/modules/math/fixed/test/Makefile
new file mode 100644
index 00000000..04aa4cff
--- /dev/null
+++ b/digital/avr/modules/math/fixed/test/Makefile
@@ -0,0 +1,38 @@
+BASE = ../../../..
+PROGS = test_fixed
+SIMU_PROGS = test_fixed
+test_fixed_SOURCES = test_fixed.c
+MODULES = uart proto utils math/fixed math/random
+CONFIGFILE = avrconfig.h
+# atmega8, atmega8535, atmega128...
+AVR_MCU = atmega128
+# -O2 : speed
+# -Os : size
+OPTIMIZE = -O2
+
+HOST_LIBS = -lm
+
+include $(BASE)/make/Makefile.gen
+
+# Automatic tests.
+
+TEST_FILES = test.mul test.div test.cos test.sqrt
+TEST_FILES := $(TEST_FILES:%=%.host) $(TEST_FILES:%=%.simu)
+code_mul = m
+code_div = d
+code_cos = c
+code_sqrt = s
+code = $(code_$(1:test.%.$(2)=%))
+
+clean.test:
+ rm -f $(TEST_FILES)
+
+SIMULAVR = simulavr -d $(AVR_MCU) -W 0x22,- -R 0x20,- -T uart0_exit
+
+.PRECIOUS: $(TEST_FILES)
+
+test.%.host: test_fixed.host
+ echo '!$(call code,$@,host)' | ./$< > $@
+
+test.%.simu: test_fixed.avr.simu.elf
+ echo '!$(call code,$@,simu)\r' | $(SIMULAVR) -f $< > $@
diff --git a/digital/avr/modules/math/fixed/test/avrconfig.h b/digital/avr/modules/math/fixed/test/avrconfig.h
new file mode 100644
index 00000000..763c9185
--- /dev/null
+++ b/digital/avr/modules/math/fixed/test/avrconfig.h
@@ -0,0 +1,86 @@
+#ifndef avrconfig_h
+#define avrconfig_h
+/* avrconfig.h */
+/* avr.math.fixed - Fixed point math module. {{{
+ *
+ * Copyright (C) 2005 Nicolas Schodet
+ *
+ * Robot APB Team/Efrei 2006.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+/* global */
+/** AVR Frequency : 1000000, 1843200, 2000000, 3686400, 4000000, 7372800,
+ * 8000000, 11059200, 14745600, 16000000, 18432000, 20000000. */
+#define AC_FREQ 14745600
+
+/* uart - UART module. */
+/** Select hardware uart for primary uart: 0, 1 or -1 to disable. */
+#define AC_UART0_PORT 0
+/** Baudrate: 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800,
+ * 115200, 230400, 250000, 500000, 1000000. */
+#define AC_UART0_BAUDRATE 115200
+/** Send mode:
+ * - POLLING: no interrupts.
+ * - RING: interrupts, ring buffer. */
+#define AC_UART0_SEND_MODE RING
+/** Recv mode, same as send mode. */
+#define AC_UART0_RECV_MODE RING
+/** Character size: 5, 6, 7, 8, 9 (only 8 implemented). */
+#define AC_UART0_CHAR_SIZE 8
+/** Parity : ODD, EVEN, NONE. */
+#define AC_UART0_PARITY EVEN
+/** Stop bits : 1, 2. */
+#define AC_UART0_STOP_BITS 1
+/** Send buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_SEND_BUFFER_SIZE 32
+/** Recv buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_RECV_BUFFER_SIZE 32
+/** If the send buffer is full when putc:
+ * - DROP: drop the new byte.
+ * - WAIT: wait until there is room in the send buffer. */
+#define AC_UART0_SEND_BUFFER_FULL WAIT
+/** In HOST compilation:
+ * - STDIO: use stdin/out.
+ * - PTS: use pseudo terminal. */
+#define AC_UART0_HOST_DRIVER STDIO
+/** Same thing for secondary port. */
+#define AC_UART1_PORT -1
+#define AC_UART1_BAUDRATE 115200
+#define AC_UART1_SEND_MODE RING
+#define AC_UART1_RECV_MODE RING
+#define AC_UART1_CHAR_SIZE 8
+#define AC_UART1_PARITY EVEN
+#define AC_UART1_STOP_BITS 1
+#define AC_UART1_SEND_BUFFER_SIZE 32
+#define AC_UART1_RECV_BUFFER_SIZE 32
+#define AC_UART1_SEND_BUFFER_FULL WAIT
+#define AC_UART1_HOST_DRIVER STDIO
+
+/* proto - Protocol module. */
+/** Maximum argument size. */
+#define AC_PROTO_ARGS_MAX_SIZE 8
+/** Callback function name. */
+#define AC_PROTO_CALLBACK proto_callback
+/** Putchar function name. */
+#define AC_PROTO_PUTC uart0_putc
+/** Support for quote parameter. */
+#define AC_PROTO_QUOTE 0
+
+#endif /* avrconfig_h */
diff --git a/digital/avr/modules/math/fixed/test/test_fixed.c b/digital/avr/modules/math/fixed/test/test_fixed.c
new file mode 100644
index 00000000..875aad4f
--- /dev/null
+++ b/digital/avr/modules/math/fixed/test/test_fixed.c
@@ -0,0 +1,247 @@
+/* test_fixed.c */
+/* avr.math.fixed - Fixed point math module. {{{
+ *
+ * Copyright (C) 2005 Nicolas Schodet
+ *
+ * Robot APB Team/Efrei 2006.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "common.h"
+#include "modules/math/fixed/fixed.h"
+#include "modules/math/random/random.h"
+#include "modules/uart/uart.h"
+#include "modules/proto/proto.h"
+#include "modules/utils/utils.h"
+#include "io.h"
+
+#ifdef HOST
+
+#include <math.h>
+#include <fenv.h>
+#include <stdio.h>
+
+static void
+check_mul (int32_t a, int32_t b, int32_t r)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ double af = (double) a / (1 << 24);
+ double bf = (double) b / (1 << 24);
+ int32_t ri = rint (af * bf * (1 << 24));
+ if (r != ri && !fetestexcept (FE_INVALID))
+ printf ("error: %08x * %08x != %08x (%08x)\n", a, b, r, ri);
+}
+
+static void
+check_div (int32_t a, int32_t b, int32_t r)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ double af = (double) a / (1 << 24);
+ double bf = (double) b / (1 << 24);
+ int32_t ri = af / bf * (1 << 24);
+ if (r != ri && !fetestexcept (FE_INVALID))
+ printf ("error: %08x / %08x != %08x (%08x)\n", a, b, r, ri);
+}
+
+static void
+check_cos (int32_t a, int32_t rc, int32_t rs)
+{
+ double af = (double) a / (1 << 24) * 2 * M_PI;
+ int32_t rci = cos (af) * (1 << 24);
+ if (rc != rci)
+ printf ("error: cos (%08x) != %08x (%08x%+d)\n",
+ a, rc, rci, rc - rci);
+ int32_t rsi = sin (af) * (1 << 24);
+ if (rs != rsi)
+ printf ("error: sin (%08x) != %08x (%08x%+d)\n",
+ a, rs, rsi, rs - rsi);
+}
+
+static void
+check_sqrt (uint32_t a, uint32_t rf, uint16_t ri)
+{
+ double aff = (double) a / (1 << 8);
+ uint32_t rfi = sqrt (aff) * (1 << 8);
+ if (rf != rfi)
+ printf ("error: sqrt_f (%08x) != %08x (%08x%+d)\n",
+ a, rf, rfi, rf - rfi);
+ double aif = (double) a;
+ uint16_t rii = sqrt (aif);
+ if (ri != rii)
+ printf ("error: sqrt_i (%08x) != %04x (%04x%+d)\n",
+ a, ri, rii, ri - rii);
+}
+
+#else
+
+# define check_mul(a, b, r)
+# define check_div(a, b, r)
+# define check_cos(a, rc, rs)
+# define check_sqrt(a, rf, ri)
+
+#endif
+
+void
+proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
+{
+ uint8_t ap, bp, as, bs;
+ uint16_t i;
+ int32_t al, bl, rl[4];
+ uint32_t patl[] = { 0xa66a6aa6, 0x5a5affff, 0xffcdffcd, 0xffffffff };
+#define patn (sizeof (patl) / sizeof (patl[0]))
+#define c(cmd, size) (cmd << 8 | size)
+ switch (c (cmd, size))
+ {
+ case c ('z', 0):
+ utils_reset ();
+ break;
+ case c ('m', 0):
+ for (ap = 0; ap < patn; ap++)
+ for (bp = 0; bp < patn; bp++)
+ for (as = 0; as < 32; as++)
+ for (bs = 0; bs < 32; bs++)
+ {
+ al = patl[ap] >> as;
+ bl = patl[bp] >> bs;
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_mul_f824 (al, bl);
+ check_mul (al, bl, rl[0]);
+ rl[1] = fixed_mul_f824 (-al, bl);
+ check_mul (-al, bl, rl[1]);
+ rl[2] = fixed_mul_f824 (al, -bl);
+ check_mul (al, -bl, rl[2]);
+ rl[3] = fixed_mul_f824 (-al, -bl);
+ check_mul (-al, -bl, rl[3]);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 ();
+ bl = random_u32 ();
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_mul_f824 (al, bl);
+ check_mul (al, bl, rl[0]);
+ rl[1] = fixed_mul_f824 (-al, bl);
+ check_mul (-al, bl, rl[1]);
+ rl[2] = fixed_mul_f824 (al, -bl);
+ check_mul (al, -bl, rl[2]);
+ rl[3] = fixed_mul_f824 (-al, -bl);
+ check_mul (-al, -bl, rl[3]);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ break;
+ case c ('d', 0):
+ for (ap = 0; ap < patn; ap++)
+ for (bp = 0; bp < patn; bp++)
+ for (as = 0; as < 32; as++)
+ for (bs = 0; bs < 31; bs++)
+ {
+ al = patl[ap] >> as;
+ bl = patl[bp] >> bs;
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_div_f824 (al, bl);
+ check_div (al, bl, rl[0]);
+ rl[1] = fixed_div_f824 (-al, bl);
+ check_div (-al, bl, rl[1]);
+ rl[2] = fixed_div_f824 (al, -bl);
+ check_div (al, -bl, rl[2]);
+ rl[3] = fixed_div_f824 (-al, -bl);
+ check_div (-al, -bl, rl[3]);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 ();
+ bl = random_u32 ();
+ if (bl != 0)
+ {
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_div_f824 (al, bl);
+ check_div (al, bl, rl[0]);
+ rl[1] = fixed_div_f824 (-al, bl);
+ check_div (-al, bl, rl[1]);
+ rl[2] = fixed_div_f824 (al, -bl);
+ check_div (al, -bl, rl[2]);
+ rl[3] = fixed_div_f824 (-al, -bl);
+ check_div (-al, -bl, rl[3]);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ }
+ break;
+ case c ('c', 0):
+ for (al = 0; al < (1L << 24); al += 257)
+ {
+ proto_send1d ('a', al);
+ rl[0] = fixed_cos_f824 (al);
+ rl[1] = fixed_sin_f824 (al);
+ check_cos (al, rl[0], rl[1]);
+ proto_send2d ('r', rl[0], rl[1]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 () & 0xffffff;
+ proto_send1d ('a', al);
+ rl[0] = fixed_cos_f824 (al);
+ rl[1] = fixed_sin_f824 (al);
+ check_cos (al, rl[0], rl[1]);
+ proto_send2d ('r', rl[0], rl[1]);
+ }
+ break;
+ case c ('s', 0):
+ for (ap = 0; ap < patn; ap++)
+ for (as = 0; as < 32; as++)
+ {
+ al = patl[ap] >> as;
+ proto_send1d ('a', al);
+ rl[0] = fixed_sqrt_uf248 (al);
+ rl[1] = fixed_sqrt_ui32 (al);
+ check_sqrt (al, rl[0], rl[1]);
+ proto_send2d ('r', rl[0], rl[1]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 ();
+ proto_send1d ('a', al);
+ rl[0] = fixed_sqrt_uf248 (al);
+ rl[1] = fixed_sqrt_ui32 (al);
+ check_sqrt (al, rl[0], rl[1]);
+ proto_send2d ('r', rl[0], rl[1]);
+ }
+ break;
+ default:
+ proto_send0 ('?');
+ return;
+ }
+ /* When no error acknoledge. */
+ proto_send (cmd, size, args);
+#undef c
+}
+
+int
+main (int argc, char **argv)
+{
+ avr_init (argc, argv);
+ sei ();
+ uart0_init ();
+ proto_send0 ('z');
+ while (1)
+ {
+ uint8_t c = uart0_getc ();
+ proto_accept (c);
+ }
+}