From 583f00e0b8efe2832f63efb478a51d3ad35e92ed Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 7 Oct 2007 22:16:03 +0200 Subject: Included SI2E avr modules. Well, this need more works... --- digital/avr/README | 25 ++ digital/avr/common/common.h | 73 +++++ digital/avr/common/io.h | 50 +++ digital/avr/make/Makefile.avr | 121 +++++++ digital/avr/make/Makefile.gen | 101 ++++++ digital/avr/make/Makefile.host | 48 +++ digital/avr/modules/adc/Makefile.module | 1 + digital/avr/modules/adc/README | 25 ++ digital/avr/modules/adc/adc.c | 67 ++++ digital/avr/modules/adc/adc.h | 51 +++ digital/avr/modules/host/Makefile.module | 1 + digital/avr/modules/host/README | 25 ++ digital/avr/modules/host/host.h | 65 ++++ digital/avr/modules/host/host.host.c | 102 ++++++ digital/avr/modules/host/test/Makefile | 12 + digital/avr/modules/host/test/avrconfig.h | 28 ++ digital/avr/modules/host/test/test_host.c | 61 ++++ digital/avr/modules/math/fixed/Makefile | 5 + digital/avr/modules/math/fixed/Makefile.module | 3 + digital/avr/modules/math/fixed/README | 25 ++ digital/avr/modules/math/fixed/fixed.h | 81 +++++ digital/avr/modules/math/fixed/fixed.txt | 52 +++ digital/avr/modules/math/fixed/fixed_cosin_f824.c | 81 +++++ .../avr/modules/math/fixed/fixed_div_f824.avr.S | 166 ++++++++++ .../avr/modules/math/fixed/fixed_mul_f824.avr.S | 172 ++++++++++ digital/avr/modules/math/fixed/fixed_sqrt_uf248.c | 48 +++ digital/avr/modules/math/fixed/fixed_sqrt_ui32.c | 48 +++ digital/avr/modules/math/fixed/test/Makefile | 38 +++ digital/avr/modules/math/fixed/test/avrconfig.h | 86 +++++ digital/avr/modules/math/fixed/test/test_fixed.c | 247 ++++++++++++++ digital/avr/modules/math/random/Makefile.module | 1 + digital/avr/modules/math/random/README | 26 ++ digital/avr/modules/math/random/random.h | 33 ++ digital/avr/modules/math/random/test/Makefile | 12 + digital/avr/modules/math/random/test/avrconfig.h | 86 +++++ digital/avr/modules/math/random/test/test_random.c | 44 +++ digital/avr/modules/math/random/tt800.c | 86 +++++ digital/avr/modules/proto/Makefile | 5 + digital/avr/modules/proto/Makefile.module | 1 + digital/avr/modules/proto/README | 25 ++ digital/avr/modules/proto/avrconfig.h | 38 +++ digital/avr/modules/proto/proto.c | 206 ++++++++++++ digital/avr/modules/proto/proto.h | 56 ++++ digital/avr/modules/proto/proto.txt | 89 +++++ digital/avr/modules/proto/proto_inline.c | 303 +++++++++++++++++ digital/avr/modules/proto/test/Makefile | 12 + digital/avr/modules/proto/test/avrconfig.h | 86 +++++ digital/avr/modules/proto/test/test_proto.c | 84 +++++ digital/avr/modules/proto/utils/protodec | 107 ++++++ digital/avr/modules/twi/Makefile | 5 + digital/avr/modules/twi/Makefile.module | 1 + digital/avr/modules/twi/README | 23 ++ digital/avr/modules/twi/avrconfig.h | 31 ++ digital/avr/modules/twi/test/Makefile.master | 25 ++ digital/avr/modules/twi/test/Makefile.slave | 24 ++ digital/avr/modules/twi/test/avrconfig_master.h | 92 ++++++ digital/avr/modules/twi/test/avrconfig_slave.h | 92 ++++++ digital/avr/modules/twi/test/test_twi_master.c | 94 ++++++ digital/avr/modules/twi/test/test_twi_sl.c | 51 +++ digital/avr/modules/twi/twi.avr.c | 363 +++++++++++++++++++++ digital/avr/modules/twi/twi.c | 33 ++ digital/avr/modules/twi/twi.h | 55 ++++ digital/avr/modules/uart/Makefile | 5 + digital/avr/modules/uart/Makefile.module | 3 + digital/avr/modules/uart/README | 24 ++ digital/avr/modules/uart/avrconfig.h | 71 ++++ digital/avr/modules/uart/test/Makefile | 18 + digital/avr/modules/uart/test/avrconfig_polling.h | 76 +++++ digital/avr/modules/uart/test/avrconfig_ring.h | 76 +++++ digital/avr/modules/uart/test/avrconfig_twoports.h | 76 +++++ digital/avr/modules/uart/test/test_uart.c | 70 ++++ digital/avr/modules/uart/uart.avr.c | 299 +++++++++++++++++ digital/avr/modules/uart/uart.h | 60 ++++ digital/avr/modules/uart/uart.host.c | 175 ++++++++++ digital/avr/modules/uart/uart.simu.c | 78 +++++ digital/avr/modules/uart/uart.txt | 26 ++ digital/avr/modules/uart/uart0.c | 34 ++ digital/avr/modules/uart/uart1.c | 34 ++ digital/avr/modules/uart/uart_common.h | 87 +++++ digital/avr/modules/utils/Makefile | 5 + digital/avr/modules/utils/Makefile.module | 1 + digital/avr/modules/utils/README | 25 ++ digital/avr/modules/utils/avrconfig.h | 33 ++ digital/avr/modules/utils/byte.h | 100 ++++++ digital/avr/modules/utils/test/Makefile | 15 + digital/avr/modules/utils/test/avrconfig.h | 33 ++ digital/avr/modules/utils/test/test_byte.c | 39 +++ digital/avr/modules/utils/test/test_byte_methods.c | 67 ++++ digital/avr/modules/utils/test/test_utils.c | 49 +++ digital/avr/modules/utils/utils.avr.h | 105 ++++++ digital/avr/modules/utils/utils.h | 82 +++++ digital/avr/modules/utils/utils.host.c | 50 +++ digital/avr/modules/utils/utils.host.h | 36 ++ digital/avr/modules/utils/utils.txt | 6 + 94 files changed, 5955 insertions(+) create mode 100644 digital/avr/README create mode 100644 digital/avr/common/common.h create mode 100644 digital/avr/common/io.h create mode 100644 digital/avr/make/Makefile.avr create mode 100644 digital/avr/make/Makefile.gen create mode 100644 digital/avr/make/Makefile.host create mode 100644 digital/avr/modules/adc/Makefile.module create mode 100644 digital/avr/modules/adc/README create mode 100644 digital/avr/modules/adc/adc.c create mode 100644 digital/avr/modules/adc/adc.h create mode 100644 digital/avr/modules/host/Makefile.module create mode 100644 digital/avr/modules/host/README create mode 100644 digital/avr/modules/host/host.h create mode 100644 digital/avr/modules/host/host.host.c create mode 100644 digital/avr/modules/host/test/Makefile create mode 100644 digital/avr/modules/host/test/avrconfig.h create mode 100644 digital/avr/modules/host/test/test_host.c create mode 100644 digital/avr/modules/math/fixed/Makefile create mode 100644 digital/avr/modules/math/fixed/Makefile.module create mode 100644 digital/avr/modules/math/fixed/README create mode 100644 digital/avr/modules/math/fixed/fixed.h create mode 100644 digital/avr/modules/math/fixed/fixed.txt create mode 100644 digital/avr/modules/math/fixed/fixed_cosin_f824.c create mode 100644 digital/avr/modules/math/fixed/fixed_div_f824.avr.S create mode 100644 digital/avr/modules/math/fixed/fixed_mul_f824.avr.S create mode 100644 digital/avr/modules/math/fixed/fixed_sqrt_uf248.c create mode 100644 digital/avr/modules/math/fixed/fixed_sqrt_ui32.c create mode 100644 digital/avr/modules/math/fixed/test/Makefile create mode 100644 digital/avr/modules/math/fixed/test/avrconfig.h create mode 100644 digital/avr/modules/math/fixed/test/test_fixed.c create mode 100644 digital/avr/modules/math/random/Makefile.module create mode 100644 digital/avr/modules/math/random/README create mode 100644 digital/avr/modules/math/random/random.h create mode 100644 digital/avr/modules/math/random/test/Makefile create mode 100644 digital/avr/modules/math/random/test/avrconfig.h create mode 100644 digital/avr/modules/math/random/test/test_random.c create mode 100644 digital/avr/modules/math/random/tt800.c create mode 100644 digital/avr/modules/proto/Makefile create mode 100644 digital/avr/modules/proto/Makefile.module create mode 100644 digital/avr/modules/proto/README create mode 100644 digital/avr/modules/proto/avrconfig.h create mode 100644 digital/avr/modules/proto/proto.c create mode 100644 digital/avr/modules/proto/proto.h create mode 100644 digital/avr/modules/proto/proto.txt create mode 100644 digital/avr/modules/proto/proto_inline.c create mode 100644 digital/avr/modules/proto/test/Makefile create mode 100644 digital/avr/modules/proto/test/avrconfig.h create mode 100644 digital/avr/modules/proto/test/test_proto.c create mode 100755 digital/avr/modules/proto/utils/protodec create mode 100644 digital/avr/modules/twi/Makefile create mode 100644 digital/avr/modules/twi/Makefile.module create mode 100644 digital/avr/modules/twi/README create mode 100644 digital/avr/modules/twi/avrconfig.h create mode 100644 digital/avr/modules/twi/test/Makefile.master create mode 100644 digital/avr/modules/twi/test/Makefile.slave create mode 100644 digital/avr/modules/twi/test/avrconfig_master.h create mode 100644 digital/avr/modules/twi/test/avrconfig_slave.h create mode 100644 digital/avr/modules/twi/test/test_twi_master.c create mode 100644 digital/avr/modules/twi/test/test_twi_sl.c create mode 100644 digital/avr/modules/twi/twi.avr.c create mode 100644 digital/avr/modules/twi/twi.c create mode 100644 digital/avr/modules/twi/twi.h create mode 100644 digital/avr/modules/uart/Makefile create mode 100644 digital/avr/modules/uart/Makefile.module create mode 100644 digital/avr/modules/uart/README create mode 100644 digital/avr/modules/uart/avrconfig.h create mode 100644 digital/avr/modules/uart/test/Makefile create mode 100644 digital/avr/modules/uart/test/avrconfig_polling.h create mode 100644 digital/avr/modules/uart/test/avrconfig_ring.h create mode 100644 digital/avr/modules/uart/test/avrconfig_twoports.h create mode 100644 digital/avr/modules/uart/test/test_uart.c create mode 100644 digital/avr/modules/uart/uart.avr.c create mode 100644 digital/avr/modules/uart/uart.h create mode 100644 digital/avr/modules/uart/uart.host.c create mode 100644 digital/avr/modules/uart/uart.simu.c create mode 100644 digital/avr/modules/uart/uart.txt create mode 100644 digital/avr/modules/uart/uart0.c create mode 100644 digital/avr/modules/uart/uart1.c create mode 100644 digital/avr/modules/uart/uart_common.h create mode 100644 digital/avr/modules/utils/Makefile create mode 100644 digital/avr/modules/utils/Makefile.module create mode 100644 digital/avr/modules/utils/README create mode 100644 digital/avr/modules/utils/avrconfig.h create mode 100644 digital/avr/modules/utils/byte.h create mode 100644 digital/avr/modules/utils/test/Makefile create mode 100644 digital/avr/modules/utils/test/avrconfig.h create mode 100644 digital/avr/modules/utils/test/test_byte.c create mode 100644 digital/avr/modules/utils/test/test_byte_methods.c create mode 100644 digital/avr/modules/utils/test/test_utils.c create mode 100644 digital/avr/modules/utils/utils.avr.h create mode 100644 digital/avr/modules/utils/utils.h create mode 100644 digital/avr/modules/utils/utils.host.c create mode 100644 digital/avr/modules/utils/utils.host.h create mode 100644 digital/avr/modules/utils/utils.txt (limited to 'digital') diff --git a/digital/avr/README b/digital/avr/README new file mode 100644 index 00000000..8a0b8ada --- /dev/null +++ b/digital/avr/README @@ -0,0 +1,25 @@ +avr.modules - AVR modules. + +AVR modules are a set of small and simple modules to make it easy to program a +robot with AVR microcontrolers. + + +Copyright (C) 2005 Efrei Robotique + +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. diff --git a/digital/avr/common/common.h b/digital/avr/common/common.h new file mode 100644 index 00000000..1097942b --- /dev/null +++ b/digital/avr/common/common.h @@ -0,0 +1,73 @@ +#ifndef common_h +#define common_h +/* common.h - Common definitions and includes. */ +/* avr.modules - AVR modules. {{{ + * + * 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 + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; + +#ifndef HOST + +# define assert(x) + +# define avr_init(argc, argv) do { } while (0) + +#else /* HOST */ + +# ifdef NDEBUG +# warning "you should not disable debug" +# endif + +# include + +/* Should use __assert instead of __assert_fail if not using GCC. This is + * left as an exercise to the reader :). */ +# if __GNUC_PREREQ (3, 0) +# define assert_print(expr, msg) \ + (__ASSERT_VOID_CAST (__builtin_expect (!!(expr), 1) ? 0 : \ + (__assert_fail (msg, __FILE__, __LINE__, \ + __ASSERT_FUNCTION), 0))) +# else +# define assert_print(expr, msg) \ + (__ASSERT_VOID_CAST ((expr) ? 0 : \ + (__assert_fail (msg, __FILE__, __LINE__, \ + __ASSERT_FUNCTION), 0))) +# endif + +/** Initialise host module. */ +void +host_init (int argc, char **argv); + +#define avr_init host_init + +#endif /* HOST */ + +#endif /* common_h */ diff --git a/digital/avr/common/io.h b/digital/avr/common/io.h new file mode 100644 index 00000000..8e169b9e --- /dev/null +++ b/digital/avr/common/io.h @@ -0,0 +1,50 @@ +#ifndef io_h +#define io_h +/* io.h */ +/* avr.modules - AVR modules. {{{ + * + * 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. + * + * }}} */ + +#ifndef HOST + +/* Avr part. */ +#include +#if !defined (__AVR_LIBC_VERSION__) || __AVR_LIBC_VERSION__ < 10400UL +# include + /* No INTERRUPT as it is dangerous. */ +# undef INTERRUPT + /* SIGNAL is now ISR. */ +# define ISR SIGNAL +#endif + +#else /* HOST */ + +/* Same as on AVR. */ +#define _BV(x) (1<<(x)) +/* No interrupt support on host. */ +#define sei() +#define cli() + +#endif /* HOST */ + +#endif /* io_h */ diff --git a/digital/avr/make/Makefile.avr b/digital/avr/make/Makefile.avr new file mode 100644 index 00000000..b063fe53 --- /dev/null +++ b/digital/avr/make/Makefile.avr @@ -0,0 +1,121 @@ +# Makefile.avr - AVR part Makefile. +# +# Flags. + +AVR_CFLAGS := $(CFLAGS) -mmcu=$(AVR_MCU) +AVR_ASFLAGS := $(ASFLAGS) -mmcu=$(AVR_MCU) +AVR_CPPFLAGS := $(CPPFLAGS) $(AVR_DEFS) +AVR_LDFLAGS := $(LDFLAGS) +AVR_LDLIBS := $(LDLIBS) $(AVR_LIBS) + +AVR_CC := avr-gcc +AVR_OBJCOPY := avr-objcopy +AVR_OBJDUMP := avr-objdump +AVR_COMPILE.c = $(AVR_CC) $(AVR_CFLAGS) $(AVR_CPPFLAGS) -c +ifdef L +AVR_COMPILE.c += -Wa,-adhlns=$(@:%.avr.o=%.c.avr.lst) +endif +AVR_COMPILE.S := $(AVR_CC) $(AVR_ASFLAGS) $(AVR_CPPFLAGS) -c +AVR_LINK.o := $(AVR_CC) $(AVR_CFLAGS) $(AVR_LDFLAGS) + +# Main rules. + +avr: elf lst hex + +simu: simuelf + +.PHONY: avr simu clean.avr elf simuelf lst \ + text hex srec bin eeprom ehex esrec ebin + +# General rules. + +AVR_PROGS += $(PROGS) +AVR_ELFS := $(AVR_PROGS:%=%.avr.elf) +AVR_SIMU_ELFS := $(SIMU_PROGS:%=%.avr.simu.elf) +AVR_SOURCES := $(filter-out %.host.c,$(ALL_SOURCES)) +AVR_C_SOURCES := $(filter %.c,$(AVR_SOURCES)) +AVR_S_SOURCES := $(filter %.S,$(AVR_SOURCES)) +AVR_OBJECTS := $(AVR_C_SOURCES:%.c=%.avr.o) $(AVR_S_SOURCES:%.S=%.avr.o) +AVR_SIMU_OBJECTS := $(AVR_OBJECTS:%.avr.o=%.avr.simu.o) + +elf: $(AVR_ELFS) +simuelf: $(AVR_SIMU_ELFS) +lst: $(AVR_PROGS:%=%.avr.lst) + +define AVR_PROG_template +$(1).avr.elf: $$(patsubst %.S,%.avr.o,$$(patsubst %.c,%.avr.o,\ + $$(filter-out %.host.c,$$($(1)_SOURCES)))) +$(1).avr.simu.elf: $$(patsubst %.S,%.avr.simu.o,$$(patsubst %.c,%.avr.simu.o,\ + $$(filter-out %.host.c,$$($(1)_SOURCES)))) +endef + +$(foreach prog,$(AVR_PROGS),$(eval $(call AVR_PROG_template,$(prog)))) + +$(AVR_ELFS) $(AVR_SIMU_ELFS): + $(AVR_LINK.o) $^ $(AVR_LDLIBS) -o $@ + +%.avr.lst: %.avr.elf + $(AVR_OBJDUMP) -h -S $< > $@ + +%.avr.o: %.c + $(AVR_COMPILE.c) -o $@ $< + +%.avr.simu.o: %.c + $(AVR_COMPILE.c) -DSIMU=1 -o $@ $< + +%.avr.o: %.S + $(AVR_COMPILE.S) -o $@ $< + +%.avr.simu.o: %.S + $(AVR_COMPILE.S) -DSIMU=1 -o $@ $< + +# Dependency checking. +-include $(AVR_OBJECTS:%.avr.o=%.avr.d) +-include $(AVR_SIMU_OBJECTS:%.avr.simu.o=%.avr.d) + +# Rules for building the .text rom images. + +TEXTS := $(AVR_PROGS:%=%.hex) $(AVR_PROGS:%=%.bin) $(AVR_PROGS:%=%.srec) + +text: hex + +hex: $(AVR_PROGS:%=%.hex) +bin: $(AVR_PROGS:%=%.bin) +srec: $(AVR_PROGS:%=%.srec) + +%.hex: %.avr.elf + $(AVR_OBJCOPY) -j .text -j .data -O ihex $< $@ + +%.srec: %.avr.elf + $(AVR_OBJCOPY) -j .text -j .data -O srec $< $@ + +%.bin: %.avr.elf + $(AVR_OBJCOPY) -j .text -j .data -O binary $< $@ + +# Rules for building the .eeprom rom images. + +EEPROMS := $(AVR_PROGS:%=%_eeprom.hex) $(AVR_PROGS:%=%_eeprom.bin) \ + $(AVR_PROGS:%=%_eeprom.srec) + +eeprom: ehex + +ehex: $(AVR_PROGS:%=%_eeprom.hex) +ebin: $(AVR_PROGS:%=%_eeprom.bin) +esrec: $(AVR_PROGS:%=%_eeprom.srec) + +%_eeprom.hex: %.avr.elf + $(AVR_OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ + +%_eeprom.srec: %.avr.elf + $(AVR_OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ + +%_eeprom.bin: %.avr.elf + $(AVR_OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ + +# Cleaning. + +clean.avr: + rm -f *.avr.o *.avr.d $(AVR_ELFS) \ + *.avr.simu.o *.avr.simu.d $(AVR_SIMU_ELFS) \ + *.avr.lst *.avr.map $(TEXTS) $(EEPROMS) + diff --git a/digital/avr/make/Makefile.gen b/digital/avr/make/Makefile.gen new file mode 100644 index 00000000..0fa9b983 --- /dev/null +++ b/digital/avr/make/Makefile.gen @@ -0,0 +1,101 @@ +# Makefile.gen - General Makefile. + +# Flags + +INCLUDES := -I$(BASE) -I$(BASE)/common +CFLAGS := -g -Wall -W -Wundef -Wno-unused-parameter -Wno-pointer-sign \ + $(OPTIMIZE) +ASFLAGS := -Wa,--gstabs +CPPFLAGS := $(DEFS) $(INCLUDES) -MMD \ + $(if $(CONFIGFILE),$(CONFIGFILE:%=-include %)) +LDFLAGS := +LDLIBS := $(LIBS) + +# Usefull macros. +## Return $(A) only if defined, else return B. +## $(call defval A,B) +defval = $(if $(filter undefined,$(origin $(1))),$(2),$($(1))) + +# Main rules. + +all: avr simu host + +.PHONY: all clean doc + +# General rules. + +ALL_PROGS := $(PROGS) $(AVR_PROGS) $(HOST_PROGS) $(SIMU_PROGS) +ALL_SOURCES = $(foreach prog,$(ALL_PROGS),$($(prog)_SOURCES)) + +# Modules. + +MODULES += host + +ALL_MODULES := $(sort $(MODULES) \ + $(foreach prog,$(ALL_PROGS),$($(prog)_MODULES))) + +include $(ALL_MODULES:%=$(BASE)/modules/%/Makefile.module) + +define MODULES_template +$(1)_SOURCES += $(foreach module,\ + $(call defval,$(1)_MODULES,$(MODULES)),\ + $($(subst /,_,$(module))_SOURCES)\ +) +endef + +$(foreach prog,$(ALL_PROGS),$(eval $(call MODULES_template,$(prog)))) + +vpath %.c $(ALL_MODULES:%=$(BASE)/modules/%) +vpath %.S $(ALL_MODULES:%=$(BASE)/modules/%) + +# Compilation test rules. + +define TEST_MCU_template +test.sub:: + $$(MAKE) CONFIGFILE=$(1) AVR_MCU=$(2) clean elf +endef + +define TEST_template +$$(foreach mcu,\ + $$(if $$($(1:%.h=%)_TEST_MCU),$$($(1:%.h=%)_TEST_MCU),$$(TEST_MCU)),\ + $$(eval $$(call TEST_MCU_template,$(1),$$(mcu)))) +test.sub:: + $$(MAKE) CONFIGFILE=$(1) clean host +endef + +$(foreach config,$(TEST_CONFIGFILES),$(eval $(call TEST_template,$(config)))) + +test: test.sub clean + +# Include other Makefiles. + +ifneq (,$(filter-out %.c %.avr.S,$(ALL_SOURCES))) +$(error Sources should be .c or .avr.S files) +endif + +ifneq (,$(strip $(ALL_PROGS))) +include $(BASE)/make/Makefile.avr +include $(BASE)/make/Makefile.host +else +avr: +simu: +host: +clean.avr: +clean.host: +endif + +# Rules for building the doc. + +doc: $(DOC) + +%.html: %.txt %.exd + aft $< + +%.exd: $(EXTRACTDOC) + test -n "$^" && extractdoc $^ > $@ || true + +# Cleaning. + +clean: clean.avr clean.host + rm -f *.bak *~ $(DOC) *.exd $(EXTRA_CLEAN_FILES) + diff --git a/digital/avr/make/Makefile.host b/digital/avr/make/Makefile.host new file mode 100644 index 00000000..d2942506 --- /dev/null +++ b/digital/avr/make/Makefile.host @@ -0,0 +1,48 @@ +# Makefile.host - Host Makefile. +# +# Flags. + +HOST_CFLAGS := $(CFLAGS) +HOST_CPPFLAGS := $(CPPFLAGS) $(HOST_DEFS) -DHOST=1 +HOST_LDFLAGS := $(LDFLAGS) +HOST_LDLIBS := $(LDLIBS) $(HOST_LIBS) + +HOST_COMPILE.c := $(CC) $(HOST_CFLAGS) $(HOST_CPPFLAGS) -c +HOST_LINK.o := $(CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) + +# Main rules. + +host: exe + +.PHONY: host clean.host exe + +# General rules. + +HOST_PROGS += $(PROGS) +HOST_EXES := $(HOST_PROGS:%=%.host) +HOST_SOURCES := $(filter-out %.avr.c %.avr.S,$(ALL_SOURCES)) +HOST_OBJECTS := $(HOST_SOURCES:%.c=%.host.o) + +exe: $(HOST_EXES) + +define HOST_PROG_template +$(1).host: $$(patsubst %.c,%.host.o,\ + $$(filter-out %.avr.c %.avr.S,$$($(1)_SOURCES))) +endef + +$(foreach prog,$(HOST_PROGS),$(eval $(call HOST_PROG_template,$(prog)))) + +$(HOST_EXES): + $(HOST_LINK.o) $^ $(HOST_LDLIBS) -o $@ + +%.host.o: %.c + $(HOST_COMPILE.c) -o $@ $< + +# Dependency checking. +-include $(HOST_OBJECTS:%.host.o=%.host.d) + +# Cleaning. + +clean.host: + rm -f *.host.o *.host.d $(HOST_EXES) + diff --git a/digital/avr/modules/adc/Makefile.module b/digital/avr/modules/adc/Makefile.module new file mode 100644 index 00000000..d14349c3 --- /dev/null +++ b/digital/avr/modules/adc/Makefile.module @@ -0,0 +1 @@ +adc_SOURCES = adc.c diff --git a/digital/avr/modules/adc/README b/digital/avr/modules/adc/README new file mode 100644 index 00000000..ce7d8827 --- /dev/null +++ b/digital/avr/modules/adc/README @@ -0,0 +1,25 @@ +avr.adc - ADC AVR module. + +Analog to Digital Converter module for AVR. See modules README for more +details about AVR modules. + + +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. diff --git a/digital/avr/modules/adc/adc.c b/digital/avr/modules/adc/adc.c new file mode 100644 index 00000000..d6ae9094 --- /dev/null +++ b/digital/avr/modules/adc/adc.c @@ -0,0 +1,67 @@ +/* adc.c */ +/* n.avr.adc - AVR ADC Module. {{{ + * + * Copyright (C) 2005 Thomas Burg + * + * 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. + * + * Contact : + * Email: burg AT efrei DOT fr + * }}} */ +#include "adc.h" + +#include "io.h" +#include "modules/utils/utils.h" + +/* Tested AVR check. */ +#if defined (__AVR_ATmega8__) +#elif defined (__AVR_ATmega8535__) +#elif defined (__AVR_ATmega128__) +#elif defined (__AVR_ATmega64__) +#else +# warning "adc: not tested on this chip." +#endif + +/* ADC configuration. */ +/* REFS = 01: AVCC with external capacitor at AREF pin. + * 11: Internal 2.56V Voltage Reference with external capacitor + * at AREF pin. */ +#define ADMUX_CFG (regv (REFS1, REFS0, ADLAR, MUX4, MUX3, MUX2, MUX1, MUX0, \ + 1, 1, 0, 0, 0, 0, 0, 0)) +#define ADCSR_CFG (regv (ADEN, ADSC, ADATE, ADIF, ADIE, ADPS2, ADPS1, ADPS0, \ + 1, 0, 0, 1, 0, 0, 0, 0)) +#define ADCSR_CFG_115200 7 + +/* +AutoDec */ +/* -AutoDec */ + +/** Initialise adc. */ +void +adc_init (void) +{ + /* Low freq. */ + ADCSR = ADCSR_CFG | ADCSR_CFG_115200; +} + +/** Choose and start mesure on adc line. */ +void +adc_start (uint8_t c) +{ + /* Choose adc. */ + ADMUX = ADMUX_CFG | (c & 0x07); + /* Start mesure. */ + ADCSR |= _BV (ADSC); +} + diff --git a/digital/avr/modules/adc/adc.h b/digital/avr/modules/adc/adc.h new file mode 100644 index 00000000..56ae8c59 --- /dev/null +++ b/digital/avr/modules/adc/adc.h @@ -0,0 +1,51 @@ +#ifndef adc_h +#define adc_h +/* adc.h */ +/* n.avr.adc - AVR ADC Module. {{{ + * + * Copyright (C) 2005 Thomas Burg + * + * 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. + * + * Contact : + * Email: burg AT efrei DOT fr + * }}} */ + +#include "common.h" +/* Different name on ATmega8535. */ + +#if defined (__AVR_ATmega8535__) +#define ADCSR ADCSRA +#endif + +/* +AutoDec */ + +/** Initialise adc. */ +void +adc_init (void); + +/** Choose and start mesure on adc line. */ +void +adc_start (uint8_t c); + +/* -AutoDec */ + +/** check on finish mesure */ +#define adc_checkf() bit_is_set (ADCSR, ADIF) + +/** read mesure */ +#define adc_read() ADCW + +#endif /* adc_h */ diff --git a/digital/avr/modules/host/Makefile.module b/digital/avr/modules/host/Makefile.module new file mode 100644 index 00000000..cf2cf1ee --- /dev/null +++ b/digital/avr/modules/host/Makefile.module @@ -0,0 +1 @@ +host_SOURCES = host.host.c diff --git a/digital/avr/modules/host/README b/digital/avr/modules/host/README new file mode 100644 index 00000000..7b9e5075 --- /dev/null +++ b/digital/avr/modules/host/README @@ -0,0 +1,25 @@ +avr.host - Host fonctions modules. + +Host and simulation functions. See modules README for more details about AVR +modules. + + +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. diff --git a/digital/avr/modules/host/host.h b/digital/avr/modules/host/host.h new file mode 100644 index 00000000..73cd4a58 --- /dev/null +++ b/digital/avr/modules/host/host.h @@ -0,0 +1,65 @@ +#ifndef host_h +#define host_h +/* host.h */ +/* avr.host - Host fonctions modules. {{{ + * + * Copyright (C) 2005-2006 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. + * + * }}} */ + +/* Discourage use of this header in non HOST compilation. */ +#ifndef HOST +# error Use this header only for HOST only files ! +#endif + +/** Initialise host module. */ +void +host_init (int argc, char **argv); + +/** Retrieve saved program arguments. Program name and used parameters are + * stripped. */ +void +host_get_program_arguments (int *argc, char ***argv); + +/** Host variables are usefull on reset. They are passed in the environment. + * This is not optimised for performance. */ + +/** Register a host integer. */ +void +host_register_integer (const char *name, int val); + +/** Register a host string. */ +void +host_register_string (const char *name, const char *val); + +/** Fetch a host integer, return -1 if non existant. */ +int +host_fetch_integer (const char *name); + +/** Fetch a host string, return 0 if non existant. */ +const char * +host_fetch_string (const char *name); + +/** Reset the program. */ +void +host_reset (void) __attribute__ ((noreturn)); + +#endif /* host_h */ diff --git a/digital/avr/modules/host/host.host.c b/digital/avr/modules/host/host.host.c new file mode 100644 index 00000000..7967e9cd --- /dev/null +++ b/digital/avr/modules/host/host.host.c @@ -0,0 +1,102 @@ +/* host.host.c */ +/* avr.host - Host fonctions modules. {{{ + * + * Copyright (C) 2005-2006 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. + * + * }}} */ +#define _GNU_SOURCE +#include "common.h" +#include "host.h" + +#include +#include +#include +#include + +/* Saved arguments. Uninitialised global variables are set to 0 by the + * compiler. */ +static int host_saved_argc; +static char **host_saved_argv; + +/** Initialise host module. */ +void +host_init (int argc, char **argv) +{ + host_saved_argc = argc; + host_saved_argv = argv; +} + +/** Retrieve saved program arguments. Program name and used parameters are + * stripped. */ +void +host_get_program_arguments (int *argc, char ***argv) +{ + assert (host_saved_argc); + *argc = host_saved_argc - 1; + *argv = host_saved_argv + 1; +} + +/** Register a host integer. */ +void +host_register_integer (const char *name, int val) +{ + int r; + char sval[256]; + /* Convert to string, and register the string. */ + r = snprintf (sval, sizeof (sval), "%d", val); + assert (r < (int) sizeof (sval)); + host_register_string (name, sval); +} + +/** Register a host string. */ +void +host_register_string (const char *name, const char *val) +{ + int r; + r = setenv (name, val, 1); + assert (r == 0); +} + +/** Fetch a host integer, return -1 if non existant. */ +int +host_fetch_integer (const char *name) +{ + const char *sval = host_fetch_string (name); + return sval ? atoi (sval) : -1; +} + +/** Fetch a host string, return 0 if non existant. */ +const char * +host_fetch_string (const char *name) +{ + return getenv (name); +} + +/** Reset the program. */ +void +host_reset (void) +{ + assert (host_saved_argv); + execv (program_invocation_name, host_saved_argv); + assert_perror (errno); + abort (); +} + diff --git a/digital/avr/modules/host/test/Makefile b/digital/avr/modules/host/test/Makefile new file mode 100644 index 00000000..5f8343c4 --- /dev/null +++ b/digital/avr/modules/host/test/Makefile @@ -0,0 +1,12 @@ +BASE = ../../.. +HOST_PROGS = test_host +test_host_SOURCES = test_host.c +MODULES = host +CONFIGFILE = avrconfig.h +# atmega8, atmega8535, atmega128... +AVR_MCU = none +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/host/test/avrconfig.h b/digital/avr/modules/host/test/avrconfig.h new file mode 100644 index 00000000..f3c23a9c --- /dev/null +++ b/digital/avr/modules/host/test/avrconfig.h @@ -0,0 +1,28 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h - test_host config file. */ +/* host - Host fonctions modules. {{{ + * + * 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. + * + * }}} */ + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/host/test/test_host.c b/digital/avr/modules/host/test/test_host.c new file mode 100644 index 00000000..8c98a94a --- /dev/null +++ b/digital/avr/modules/host/test/test_host.c @@ -0,0 +1,61 @@ +/* test_host.c */ +/* avr.host - Host fonctions modules. {{{ + * + * Copyright (C) 2005-2006 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/host/host.h" + +#include +#include + +int +main (int argc, char **argv) +{ + int i; + const char *s; + int ac; + char **av; + printf ("reset\n"); + host_init (argc, argv); + i = host_fetch_integer ("avr_integer"); + s = host_fetch_string ("avr_string"); + if (i != -1) + { + printf ("get\n"); + host_get_program_arguments (&ac, &av); + assert_print (ac == 1 && strcmp (av[0], "ni") == 0, + "argument passing not working"); + assert (i == 42); + assert (strcmp (s, "Ni!") == 0); + } + else + { + printf ("set\n"); + assert_print (argc == 2 && strcmp (argv[1], "ni") == 0, + "please provide \"ni\" as the first argument"); + host_register_integer ("avr_integer", 42); + host_register_string ("avr_string", "Ni!"); + host_reset (); + } + return 0; +} diff --git a/digital/avr/modules/math/fixed/Makefile b/digital/avr/modules/math/fixed/Makefile new file mode 100644 index 00000000..44892c74 --- /dev/null +++ b/digital/avr/modules/math/fixed/Makefile @@ -0,0 +1,5 @@ +BASE = ../../.. +DOC = fixed.html +EXTRACTDOC = fixed.h + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/math/fixed/Makefile.module b/digital/avr/modules/math/fixed/Makefile.module new file mode 100644 index 00000000..ed7e89fe --- /dev/null +++ b/digital/avr/modules/math/fixed/Makefile.module @@ -0,0 +1,3 @@ +math_fixed_SOURCES = fixed_mul_f824.avr.S fixed_div_f824.avr.S \ + fixed_cosin_f824.c \ + fixed_sqrt_uf248.c fixed_sqrt_ui32.c diff --git a/digital/avr/modules/math/fixed/README b/digital/avr/modules/math/fixed/README new file mode 100644 index 00000000..639d4fca --- /dev/null +++ b/digital/avr/modules/math/fixed/README @@ -0,0 +1,25 @@ +avr.math.fixed - Fixed point math module. + +Provide fixed point math function for AVR, and host simulation. See modules +README for more details about AVR modules. + + +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. diff --git a/digital/avr/modules/math/fixed/fixed.h b/digital/avr/modules/math/fixed/fixed.h new file mode 100644 index 00000000..a3200c18 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed.h @@ -0,0 +1,81 @@ +#ifndef fixed_h +#define fixed_h +/* fixed.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. + * + * }}} */ + +/* Numbers notation: + * [u]{i|f}x[.y] + * u: unsigned + * i: integer + * f: fixed point + * x: integral part size in bits + * y: fractionnal part size in bits + * + * Ex: i16: signed 16 bit word, uf8.8: unsigned fixed 8.8. + * + * Angles are mapped from [0, 2pi) to [0,1). */ + +#ifndef HOST + +/* Multiply f8.24 by f8.24, return f8.24. */ +#define fixed_mul_f824(a, b) ({ \ + uint16_t dummy; \ + asm ("" : "=r" (dummy)); \ + fixed_mul_f824_asm (dummy, a, b); }) +int32_t +fixed_mul_f824_asm (uint16_t dummy, int32_t a, int32_t b); + +/* Divide f8.24 by f8.24, return f8.24. */ +int32_t +fixed_div_f824 (int32_t a, int32_t b); + +#else /* HOST */ + +/** Multiply f8.24 by f8.24, return f8.24. */ +#define fixed_mul_f824(a, b) (((int64_t) (a) * (int64_t) (b) \ + + 0x800000LL) >> 24) + +/** Divide f8.24 by f8.24, return f8.24. */ +#define fixed_div_f824(a, b) (((int64_t) (a) << 24) / (int64_t) (b)) + +#endif + +/** Compute cosinus, angle f8.24, result f8.24. */ +int32_t +fixed_cos_f824 (int32_t a); + +/** Compute sinus, angle f8.24, result f8.24. */ +int32_t +fixed_sin_f824 (int32_t a); + +/** Compute square root, uf24.8. */ +uint32_t +fixed_sqrt_uf248 (uint32_t x); + +/** Compute square root, ui32 -> ui16. */ +uint16_t +fixed_sqrt_ui32 (uint32_t x); + +#endif /* fixed_h */ diff --git a/digital/avr/modules/math/fixed/fixed.txt b/digital/avr/modules/math/fixed/fixed.txt new file mode 100644 index 00000000..645d9cc6 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed.txt @@ -0,0 +1,52 @@ +*Title: Module AVR math à virgule fixe +*Author: Ni + +* La virgule fixe + +Le format à virgule fixe, à opposer à la virgule flottante, divise un mot +binaire en deux parties, la partie entière et la partie fractionnaire. + +L'inconvénient par rapport à la virgule flottante, c'est de pouvoir +représenter une plage plus petite de nombres. Il faut aussi faire très +attention de ne pas déborder lors des calculs intermédiaires. + +L'avantage, c'est la vitesse d'exécution, ça tombe bien, on est pressé ! + +Je vous laisse consulter internet pour plus d'informations. + +* Notation des nombres + +Pour décoder le nom des fonctions : + +^<< + [u]{i|f}x[.y] +^>> + + [u] non signé ; + [i] entier ; + [f] virgule fixe ; + [x] taille de la partie entière en bits ; + [y] taille de la partie fractionnaire en bits. + +Par exemple : + + [i16] mot signé 16 bits ; + [uf24.8] nombre en virgule fixe non signé, avec 24 bits pour la partie + entière et 8 bits pour la partie fractionnaire. + +* Format des angles + +Les angles utilisés sont dans l'intervalle [0 ; 1[. La valeur 1 correspond à 2 +pi radians, soit un tour complet. Le sens des angles orientés est le sens +trigonométrique bien sur. + +* Routines de tests + +Pour tester les algorithmes, on compile test_fixed pour hôte et pour AVR. On +lance les deux et l'on compare les résultats, ils doivent être identiques. + +La version hôte vérifie les calculs avec la bibliothèque mathématique du C. + +* Doc + +*File: fixed.exd diff --git a/digital/avr/modules/math/fixed/fixed_cosin_f824.c b/digital/avr/modules/math/fixed/fixed_cosin_f824.c new file mode 100644 index 00000000..d5148f42 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed_cosin_f824.c @@ -0,0 +1,81 @@ +/* fixed_cosin_f824.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 "fixed.h" + +/** Compute cosinus for angles between [0,pi/2]. */ +static int32_t +fixed_cos_dli (int32_t a) +{ + static const int32_t f[] = { + (1L << 24) * -26.42625678337439745096, + (1L << 24) * 60.24464137187666035919, + (1L << 24) * -85.45681720669372773226, + (1L << 24) * 64.93939402266829148905, + (1L << 24) * -19.73920880217871723738, + (1L << 24) * 1 + }; + int32_t r; + int32_t a2; + uint8_t i; + a2 = fixed_mul_f824 (a, a); + r = f[0]; + for (i = 1; i < sizeof (f) / sizeof (f[0]); i++) + r = fixed_mul_f824 (r, a2) + f[i]; + return r; +} + +/** Compute cosinus, angle f8.24, result f8.24. */ +int32_t +fixed_cos_f824 (int32_t a) +{ + a &= (1L << 24) - 1; + uint8_t z = ((uint32_t) a >> 16) & 0xc0; + if (z == 0) + return fixed_cos_dli (a); + else if (z == 1 << 6) + return -fixed_cos_dli ((1L << 23) - a); + else if (z == 2 << 6) + return -fixed_cos_dli (a & 0xff7fffff); + else + return fixed_cos_dli ((1L << 24) - a); +} + +/** Compute sinus, angle f8.24, result f8.24. */ +int32_t +fixed_sin_f824 (int32_t a) +{ + a &= (1L << 24) - 1; + uint8_t z = ((uint32_t) a >> 16) & 0xc0; + if (z == 0) + return fixed_cos_dli ((1L << 22) - a); + else if (z == 1 << 6) + return fixed_cos_dli (a - (1L << 22)); + else if (z == 2 << 6) + return -fixed_cos_dli ((1L << 23) + (1L << 22) - a); + else + return -fixed_cos_dli (a - (1L << 23) - (1L << 22)); +} + diff --git a/digital/avr/modules/math/fixed/fixed_div_f824.avr.S b/digital/avr/modules/math/fixed/fixed_div_f824.avr.S new file mode 100644 index 00000000..43f4e0c3 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed_div_f824.avr.S @@ -0,0 +1,166 @@ +; fixed_div_f824.avr.S +; 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. +; +; }}} + +; Perfs: +; 1186 cycles in worse case +; 843 per second, per MHz + +#define dd3 r25 +#define dd2 r24 +#define dd1 r23 +#define dd0 r22 + +#define dv3 r21 +#define dv2 r20 +#define dv1 r19 +#define dv0 r18 + +; r28-r29 are avoided because they should be saved. +#define rem3 r31 +#define rem2 r30 +#define rem1 r27 +#define rem0 r26 + +#define __tmp_reg__ r0 +#define __zero_reg__ r1 + +#define cnt r16 + + .text + .global fixed_div_f824 + .func fixed_div_f824 +fixed_div_f824: + push cnt +; Store sign. + mov __tmp_reg__, dd3 + eor __tmp_reg__, dv3 +; Change sign. + sbrs dd3, 7 + rjmp 1f + com dd3 + com dd2 + com dd1 + neg dd0 + sbci dd1, 0xff + sbci dd2, 0xff + sbci dd3, 0xff +1: sbrs dv3, 7 + rjmp 2f + com dv3 + com dv2 + com dv1 + neg dv0 + sbci dv1, 0xff + sbci dv2, 0xff + sbci dv3, 0xff +; Clear rem. +2: clr rem0 + clr rem1 + movw rem2, rem0 +; First loop, dropped bits. + ldi cnt, 24 +1: ;lsl dd0 ; shift out dd + lsl dd1 ; do not touch dd0 + rol dd2 + rol dd3 + rol rem0 ; shift in rem + rol rem1 ; 24 bits only + rol rem2 + ;rol rem3 + sub rem0, dv0 ; rem -= dv + sbc rem1, dv1 + sbc rem2, dv2 + sbc rem3, dv3 + brcc 2f ; if negative, restore rem + add rem0, dv0 + adc rem1, dv1 + adc rem2, dv2 + adc rem3, dv3 +2: dec cnt ; test for loop + brne 1b +; Second loop, stored bits. + ldi cnt, 8 +1: rol dd0 ; shift out dd, shift in result + rol rem0 ; shift in rem + rol rem1 + rol rem2 + rol rem3 + sub rem0, dv0 ; rem -= dv + sbc rem1, dv1 + sbc rem2, dv2 + sbc rem3, dv3 + brcc 2f ; if negative, restore rem + add rem0, dv0 + adc rem1, dv1 + adc rem2, dv2 + adc rem3, dv3 + clc ; result bit 0 + rjmp 3f +2: sec ; result bit 1 +3: dec cnt ; test for loop + brne 1b +; Last loop, stored bits, dd padding bits. + ldi cnt, 24 +1: rol dd0 ; shift out dd, shift in result + rol dd1 ; 0s come from the first loop + rol dd2 + rol dd3 + rol rem0 ; shift in rem + rol rem1 + rol rem2 + rol rem3 + sub rem0, dv0 ; rem -= dv + sbc rem1, dv1 + sbc rem2, dv2 + sbc rem3, dv3 + brcc 2f ; if negative, restore rem + add rem0, dv0 + adc rem1, dv1 + adc rem2, dv2 + adc rem3, dv3 + clc ; result bit 0 + rjmp 3f +2: sec ; result bit 1 +3: dec cnt ; test for loop + brne 1b +; Store last bit. + rol dd0 ; shift in result + rol dd1 + rol dd2 + rol dd3 +; Restore sign. + sbrs __tmp_reg__, 7 + rjmp 1f + com dd3 + com dd2 + com dd1 + neg dd0 + sbci dd1, 0xff + sbci dd2, 0xff + sbci dd3, 0xff +; Return. +1: pop r16 + ret + .endfunc diff --git a/digital/avr/modules/math/fixed/fixed_mul_f824.avr.S b/digital/avr/modules/math/fixed/fixed_mul_f824.avr.S new file mode 100644 index 00000000..9da807d7 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed_mul_f824.avr.S @@ -0,0 +1,172 @@ +; fixed_mul_f824.avr.S +; 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. +; +; }}} + +; a: A3.A2 A1 A0 +; b: B3.B2 B1 B0 +; m: M3.M2 M1 M0 +; +; . => fractional dot +; A3xB3. | +; |A3xB2 | +; | .A3xB1 | +; | . A3xB0| +; |A2xB3 | +; | .A2xB2 | +; | . A2xB1| +; | . A2xB0 +; | .A1xB3 | +; | . A1xB2| +; | . A1xB1 +; | . |A1xB0 +; | . A0xB3| +; | . A0xB2 +; | . |A0xB1 +; | . | A0xB0 +; . [- step 1 --] +; [- step 2 --] +; +; The operation is done in two steps. The three lsb multiplications can not be +; avoided. +; All multiplications results are added together. If the result is negative, +; do the sign extension (the sbc instructions). +; Result is rounded to the nearest value. +; +; Perfs: +; 96 cycles +; 10416 per second, per MHz + +#define dummy1 r25 +#define dummy0 r24 + +; mulsu are only allowed in r16-r23. +#define a3 r23 +#define a2 r22 +#define a1 r21 +#define a0 r20 + +#define b3 r19 +#define b2 r18 +#define b1 r17 +#define b0 r16 + +; r23 and r22 are used for a, registers will be moved before return. +#define m3 r25 +#define m2 r24 +#define m1 r27 +#define m0 r26 + +#define m1r r23 +#define m0r r22 + +#define z r30 + + .text + .global fixed_mul_f824_asm + .func fixed_mul_f824_asm +fixed_mul_f824_asm: + clr z +; Low dword (>> 8, with 8 guards). + mul a0, b1 + movw m0, r0 + clr m2 + clr m3 + mul a0, b0 + add m0, r1 + adc m1, z + adc m2, z + mul a1, b0 + add m0, r0 + adc m1, r1 + adc m2, z + mul a0, b2 + add m1, r0 + adc m2, r1 + adc m3, z + mul a1, b1 + add m1, r0 + adc m2, r1 + adc m3, z + mul a2, b0 + add m1, r0 + adc m2, r1 + adc m3, z +; Rounding, m0 is dropped. + ldi m0, 0x80 + add m1, m0 + adc m2, z + adc m3, z +; Shift. + movw m0, m2 +; Upper word. + mulsu b3, a2 + movw m2, r0 + mulsu b3, a0 + sbc m2, z + sbc m3, z + add m0, r0 + adc m1, r1 + adc m2, z + adc m3, z + mul a1, b2 + add m0, r0 + adc m1, r1 + adc m2, z + adc m3, z + mul a2, b1 + add m0, r0 + adc m1, r1 + adc m2, z + adc m3, z + mulsu a3, b0 + sbc m2, z + sbc m3, z + add m0, r0 + adc m1, r1 + adc m2, z + adc m3, z + mulsu b3, a1 + sbc m3, z + add m1, r0 + adc m2, r1 + adc m3, z + mul a2, b2 + add m1, r0 + adc m2, r1 + adc m3, z + mulsu a3, b1 + sbc m3, z + add m1, r0 + adc m2, r1 + adc m3, z + mulsu a3, b2 + add m2, r0 + adc m3, r1 + muls a3, b3 + add m3, r0 +; Restore r1 and return. + clr r1 + movw m0r, m0 + ret + .endfunc diff --git a/digital/avr/modules/math/fixed/fixed_sqrt_uf248.c b/digital/avr/modules/math/fixed/fixed_sqrt_uf248.c new file mode 100644 index 00000000..6d673120 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed_sqrt_uf248.c @@ -0,0 +1,48 @@ +/* fixed_sqrt_uf248.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 "fixed.h" + +/** Compute square root, uf24.8. */ +uint32_t +fixed_sqrt_uf248 (uint32_t x) +{ + uint32_t root, bit, test; + root = 0; + bit = 1L << 30; + do + { + test = root + bit; + if (x >= test) + { + x -= test; + root = test + bit; + } + root >>= 1; + bit >>= 2; + } while (bit); + return root << 4; +} + diff --git a/digital/avr/modules/math/fixed/fixed_sqrt_ui32.c b/digital/avr/modules/math/fixed/fixed_sqrt_ui32.c new file mode 100644 index 00000000..88de5841 --- /dev/null +++ b/digital/avr/modules/math/fixed/fixed_sqrt_ui32.c @@ -0,0 +1,48 @@ +/* fixed_sqrt_ui32.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 "fixed.h" + +/** Compute square root, ui32 -> ui16. */ +uint16_t +fixed_sqrt_ui32 (uint32_t x) +{ + uint32_t root, bit, test; + root = 0; + bit = 1L << 30; + do + { + test = root + bit; + if (x >= test) + { + x -= test; + root = test + bit; + } + root >>= 1; + bit >>= 2; + } while (bit); + return root; +} + 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 +#include +#include + +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); + } +} diff --git a/digital/avr/modules/math/random/Makefile.module b/digital/avr/modules/math/random/Makefile.module new file mode 100644 index 00000000..491dd63b --- /dev/null +++ b/digital/avr/modules/math/random/Makefile.module @@ -0,0 +1 @@ +math_random_SOURCES = tt800.c diff --git a/digital/avr/modules/math/random/README b/digital/avr/modules/math/random/README new file mode 100644 index 00000000..1e8e07af --- /dev/null +++ b/digital/avr/modules/math/random/README @@ -0,0 +1,26 @@ +avr.math.random - Pseudo random numbers generator. + +Provide RNG for AVR, using the TT800 algorithm. See modules README for more +details about AVR modules. + +The TT800 has his own copyright notice, see tt800.c file. + +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. diff --git a/digital/avr/modules/math/random/random.h b/digital/avr/modules/math/random/random.h new file mode 100644 index 00000000..5822cfd2 --- /dev/null +++ b/digital/avr/modules/math/random/random.h @@ -0,0 +1,33 @@ +#ifndef random_h +#define random_h +/* random.h */ +/* avr.math.random - Pseudo random numbers generator. {{{ + * + * 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. + * + * }}} */ + +/** Generate a 32 bit pseudo random number. Sequences are deterministic and + * same numbers are drawn on each runs as the seed is always the same. */ +uint32_t +random_u32 (void); + +#endif /* random_h */ diff --git a/digital/avr/modules/math/random/test/Makefile b/digital/avr/modules/math/random/test/Makefile new file mode 100644 index 00000000..0bc3c0e5 --- /dev/null +++ b/digital/avr/modules/math/random/test/Makefile @@ -0,0 +1,12 @@ +BASE = ../../../.. +PROGS = test_random +test_random_SOURCES = test_random.c +MODULES = uart proto math/random +CONFIGFILE = avrconfig.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8 +# -O2 : speed +# -Os : size +OPTIMIZE = -Os + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/math/random/test/avrconfig.h b/digital/avr/modules/math/random/test/avrconfig.h new file mode 100644 index 00000000..5f25426e --- /dev/null +++ b/digital/avr/modules/math/random/test/avrconfig.h @@ -0,0 +1,86 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.math.random - Pseudo random numbers generator. {{{ + * + * 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/random/test/test_random.c b/digital/avr/modules/math/random/test/test_random.c new file mode 100644 index 00000000..c4d2b045 --- /dev/null +++ b/digital/avr/modules/math/random/test/test_random.c @@ -0,0 +1,44 @@ +/* test_random.c */ +/* avr.math.random - Pseudo random numbers generator. {{{ + * + * 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/random/random.h" +#include "modules/uart/uart.h" +#include "modules/proto/proto.h" +#include "io.h" + +void +proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ +} + +int +main (void) +{ + sei (); + uart0_init (); + proto_send0 ('z'); + while (42) + proto_send1d ('r', random_u32 ()); +} diff --git a/digital/avr/modules/math/random/tt800.c b/digital/avr/modules/math/random/tt800.c new file mode 100644 index 00000000..64675e8a --- /dev/null +++ b/digital/avr/modules/math/random/tt800.c @@ -0,0 +1,86 @@ +/* A C-program for TT800 : July 8th 1996 Version + by M. Matsumoto, email: m-mat @ math.sci.hiroshima-u.ac.jp + + Modified for AVR modules by Nicolas Schodet. + + genrand() generate one pseudorandom number with double precision + which is uniformly distributed on [0,1]-interval + for each call. One may choose any initial 25 seeds + except all zeros. + + Copyright (C) 1996, Makoto Matsumoto + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + See: ACM Transactions on Modelling and Computer Simulation, + Vol. 4, No. 3, 1994, pages 254-266. +*/ +#include "common.h" + +#define N 25 +#define M 7 + +uint32_t +random_u32 (void) +{ + uint32_t y; + static uint8_t k = 0; + static uint32_t x[N]={ /* initial 25 seeds, change as you wish */ + 0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23, + 0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825, + 0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f, + 0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9, + 0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb + }; + static uint32_t mag01[2]={ + 0x0, 0x8ebfd028 /* this is magic vector `a', don't change */ + }; + if (k==N) { /* generate N words at one time */ + uint8_t kk; + for (kk=0;kk> 1) ^ mag01[x[kk] % 2]; + } + for (; kk> 1) ^ mag01[x[kk] % 2]; + } + k=0; + } + y = x[k]; + y ^= (y << 7) & 0x2b5b2500; /* s and b, magic vectors */ + y ^= (y << 15) & 0xdb8b0000; /* t and c, magic vectors */ + /*y &= 0xffffffff;*/ /* you may delete this line if word size = 32 */ +/* + the following line was added by Makoto Matsumoto in the 1996 version + to improve lower bit's corellation. + Delete this line to o use the code published in 1994. +*/ + y ^= (y >> 16); /* added to the 1994 version */ + k++; + return y; +} diff --git a/digital/avr/modules/proto/Makefile b/digital/avr/modules/proto/Makefile new file mode 100644 index 00000000..1c9f69b6 --- /dev/null +++ b/digital/avr/modules/proto/Makefile @@ -0,0 +1,5 @@ +BASE = ../.. +DOC = proto.html +EXTRACTDOC = proto.h avrconfig.h proto_inline.c + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/proto/Makefile.module b/digital/avr/modules/proto/Makefile.module new file mode 100644 index 00000000..933c537e --- /dev/null +++ b/digital/avr/modules/proto/Makefile.module @@ -0,0 +1 @@ +proto_SOURCES = proto.c diff --git a/digital/avr/modules/proto/README b/digital/avr/modules/proto/README new file mode 100644 index 00000000..d2ba108f --- /dev/null +++ b/digital/avr/modules/proto/README @@ -0,0 +1,25 @@ +avr.proto - Protocol AVR module. + +This is a simple humman readable protocol for use over serial line for +example. See modules README for more details about AVR modules. + + +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. diff --git a/digital/avr/modules/proto/avrconfig.h b/digital/avr/modules/proto/avrconfig.h new file mode 100644 index 00000000..fe075333 --- /dev/null +++ b/digital/avr/modules/proto/avrconfig.h @@ -0,0 +1,38 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.proto - Protocol AVR 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. + * + * }}} */ + +/* 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 1 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/proto/proto.c b/digital/avr/modules/proto/proto.c new file mode 100644 index 00000000..72aa2512 --- /dev/null +++ b/digital/avr/modules/proto/proto.c @@ -0,0 +1,206 @@ +/* proto.c */ +/* avr.proto - Protocol AVR 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 "proto.h" + +#include + +/* +AutoDec */ + +/** Accept a digit to be used for args. */ +static void +proto_accept_digit (uint8_t c); + +#if AC_PROTO_QUOTE == 1 +/** Accept a quoted char to be used for args. */ +static void +proto_accept_char (uint8_t c); +#endif + +/* Send a hex digit. */ +inline static void +proto_hex (uint8_t h); + +/* -AutoDec */ + +static uint8_t cmd; +static uint8_t size; +static uint8_t args[AC_PROTO_ARGS_MAX_SIZE]; + +/** Step of decoding: + * - 0: nothing received. + * - 1: bang received. + * - 2: command received. + * - 3: command received, and processing a number. + * - 4: quote received. + * - 5: double quote received. */ +static uint8_t step; + +/** Accept a new character. */ +void +proto_accept (uint8_t c) +{ + if (c == '!') + step = 1; + else + { + switch (step) + { + case 0: + /* Nothing received yet. */ + break; + case 1: + /* Bang received yet. */ + if (isalpha (c)) + { + cmd = c; + size = 0; + step = 2; + } + else + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + } + break; + case 2: + /* Command received yet. */ + if (c == '\r') + { + AC_PROTO_CALLBACK (cmd, size, args); + step = 0; + } +#if AC_PROTO_QUOTE == 1 + else if (c == '\'') + step = 4; + else if (c == '"') + step = 5; +#endif + else + { + step = 3; + proto_accept_digit (c); + } + break; + case 3: + step--; + proto_accept_digit (c); + break; +#if AC_PROTO_QUOTE == 1 + case 4: + step = 2; + proto_accept_char (c); + break; + case 5: + if (c == '\r') + { + AC_PROTO_CALLBACK (cmd, size, args); + step = 0; + } + else + { + proto_accept_char (c); + } + break; +#endif + } + } +} + +/** Accept a digit to be used for args. */ +static void +proto_accept_digit (uint8_t c) +{ + /* Test for argument list overflow. */ + if (size >= AC_PROTO_ARGS_MAX_SIZE) + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + return; + } + /* Convert from hexa. */ + if ('0' <= c && c <= '9') + c -= '0'; + else if ('a' <= c && c <= 'f') + c -= 'a' - 10; + else if ('A' <= c && c <= 'F') + c -= 'A' - 10; + else + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + return; + } + /* Add digit. */ + args[size] <<= 4; + args[size] |= c; + if (step == 2) + size++; +} + +#if AC_PROTO_QUOTE == 1 +/** Accept a quoted char to be used for args. */ +static void +proto_accept_char (uint8_t c) +{ + /* Test for argument list overflow or unwanted char. */ + if (size >= AC_PROTO_ARGS_MAX_SIZE || !isprint (c)) + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + return; + } + /* Add char. */ + args[size] = c; + size++; +} +#endif + +/* Send a hex digit. */ +inline static void +proto_hex (uint8_t h) +{ + AC_PROTO_PUTC (h >= 10 ? h - 10 + 'a' : h + '0'); +} + +/* Send a argument byte. */ +void +proto_arg (uint8_t a) +{ + proto_hex ((a >> 4) & 0xf); + proto_hex ((a >> 0) & 0xf); +} + +/** Send a command, generic function. */ +void +proto_send (uint8_t cmd, uint8_t size, uint8_t *args) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + while (size--) + proto_arg (*args++); + AC_PROTO_PUTC ('\r'); +} + diff --git a/digital/avr/modules/proto/proto.h b/digital/avr/modules/proto/proto.h new file mode 100644 index 00000000..b267309f --- /dev/null +++ b/digital/avr/modules/proto/proto.h @@ -0,0 +1,56 @@ +#ifndef proto_h +#define proto_h +/* proto.h */ +/* {{{ + * + * Copyright (C) 2004 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * 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. + * + * }}} */ + +/** Protocol callback function. Take the command and the arguments. Must be + * defined by the user. */ +void +AC_PROTO_CALLBACK (uint8_t cmd, uint8_t size, uint8_t *args); + +/** Protocol putc function. Take a char to send. Must be defined by the + * user. */ +void +AC_PROTO_PUTC (uint8_t c); + +/* +AutoDec */ + +/** Accept a new character. */ +void +proto_accept (uint8_t c); + +/* Send a argument byte. */ +void +proto_arg (uint8_t a); + +/** Send a command, generic function. */ +void +proto_send (uint8_t cmd, uint8_t size, uint8_t *args); + +/* -AutoDec */ + +#include "proto_inline.c" + +#endif /* proto_h */ diff --git a/digital/avr/modules/proto/proto.txt b/digital/avr/modules/proto/proto.txt new file mode 100644 index 00000000..2a20d268 --- /dev/null +++ b/digital/avr/modules/proto/proto.txt @@ -0,0 +1,89 @@ +*Title: Module AVR Protocole série +*Author: Ni + +* Principe + +Ce module s'occupe de gérer le protocole de communication sur une ligne de type +port série. Il propose un service de décodage et un service d'encodage. + +Pour utiliser le décodage, il suffit d'appeler une fonctions à chaque +caractère reçu. Si une commande a été reçu, ou en cas d'erreur, elle appelle +une fonction définie par l'utilisateur avec pour paramètres les informations +sur la commande reçue. + +Pour utiliser l'encodage, il suffit d'appeler une fonction émission avec +les paramètres que l'on veux envoyer. + +* Protocole + +Le protocole de communication est basé sur des trames. Chaque trame commence +par un point d'exclamation et se termine par un retour chariot. Tout ce qui +n'est pas entouré de ces caractères est ignoré. + +Le point d'exclamation est directement suivi de la commande. La commande est +un caractère alphabétique minuscule ou majuscule. + +Après la commande vient une liste de d'arguments. Les arguments sont codés en +hexadécimal. + +Par exemple : + +^<< +!z +!v03f5 +!c0094ffa8 +^>> + +On peut aussi envoyer directement un caractère ascii en paramètre en le +précédant d'une apostrophe, ce caractère devant être imprimable. + +Par exemple : + +^<< +!p'sa800 +^>> + +Enfin, on peut envoyer une chaine de caractères imprimables. + +Par exemple : + +^<< +!p"Hello World +^>> + +Attention, le point d'exclamation reste un caractère spécial. + +* Vérification d'erreur + +La vérification d'erreur n'est pas forcée par l'utilisation de ce module. En +règle générale, on utilisera le fonctionnement suivant : + + * pour un message fiable, le périphérique doit retourner la commande + dès réception ; + * pour un message non-fiable, le périphérique ne retourne rien. + +Par message non-fiable, on entend un message qui arrive en permanence, et dont +l'on a pas besoin de vérifier la bonne réception. En effet, une valeur plus à +jour est préférable à une réémission. + +Seul le périphérique renvois des messages de vérification ou des messages +d'erreur. Le protocole d'échange doit être prévu en prenant cela en compte. Il +n'est par exemple pas conseillé de déclencher des messages non demandé depuis +le périphérique, en effet, il n'y a aucun moyen de vérifier s'il est arrivé +correctement. Des messages envoyés sous l'initiative du périphérique doivent +donc être des messages périodiques, pas événementiels. + +* Utilisation + +On doit définir une fonction de callback afin de traiter les messages arrivant +et une fonction d'envois de caractère utilisée dans les fonctions d'envois. Le +nom de ces deux fonctions est défini dans |avrconfig.h| + +Pour chaque caractère reçu, on appelle |proto_accept|. Pour envoyer des +commandes, on utilise les fonctions |proto_send...|. + +Regarder le programme de test pour avoir un example. + +* Doc + +*File: proto.exd diff --git a/digital/avr/modules/proto/proto_inline.c b/digital/avr/modules/proto/proto_inline.c new file mode 100644 index 00000000..1a9e9406 --- /dev/null +++ b/digital/avr/modules/proto/proto_inline.c @@ -0,0 +1,303 @@ +/* proto_inline.c */ +/* {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * 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 "modules/utils/byte.h" + +/** Send a command with no argument. */ +extern inline void +proto_send0 (uint8_t cmd) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 1 byte argument. */ +extern inline void +proto_send1b (uint8_t cmd, uint8_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 1 word argument. */ +extern inline void +proto_send1w (uint8_t cmd, uint16_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 1 double word argument. */ +extern inline void +proto_send1d (uint8_t cmd, uint32_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 2 bytes arguments. */ +extern inline void +proto_send2b (uint8_t cmd, uint8_t arg0, uint8_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 2 words arguments. */ +extern inline void +proto_send2w (uint8_t cmd, uint16_t arg0, uint16_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 2 double words arguments. */ +extern inline void +proto_send2d (uint8_t cmd, uint32_t arg0, uint32_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 3 bytes arguments. */ +extern inline void +proto_send3b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 3 words arguments. */ +extern inline void +proto_send3w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 3 double words arguments. */ +extern inline void +proto_send3d (uint8_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + proto_arg (v32_to_v8 (arg2, 3)); + proto_arg (v32_to_v8 (arg2, 2)); + proto_arg (v32_to_v8 (arg2, 1)); + proto_arg (v32_to_v8 (arg2, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 4 bytes arguments. */ +extern inline void +proto_send4b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t + arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 4 words arguments. */ +extern inline void +proto_send4w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2, + uint16_t arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + proto_arg (v16_to_v8 (arg3, 1)); + proto_arg (v16_to_v8 (arg3, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 4 double words arguments. */ +extern inline void +proto_send4d (uint8_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, + uint32_t arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + proto_arg (v32_to_v8 (arg2, 3)); + proto_arg (v32_to_v8 (arg2, 2)); + proto_arg (v32_to_v8 (arg2, 1)); + proto_arg (v32_to_v8 (arg2, 0)); + proto_arg (v32_to_v8 (arg3, 3)); + proto_arg (v32_to_v8 (arg3, 2)); + proto_arg (v32_to_v8 (arg3, 1)); + proto_arg (v32_to_v8 (arg3, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 5 bytes arguments. */ +extern inline void +proto_send5b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 5 words arguments. */ +extern inline void +proto_send5w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2, + uint16_t arg3, uint16_t arg4) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + proto_arg (v16_to_v8 (arg3, 1)); + proto_arg (v16_to_v8 (arg3, 0)); + proto_arg (v16_to_v8 (arg4, 1)); + proto_arg (v16_to_v8 (arg4, 0)); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 6 bytes arguments. */ +extern inline void +proto_send6b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4, uint8_t arg5) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 7 bytes arguments. */ +extern inline void +proto_send7b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4, uint8_t arg5, uint8_t arg6) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + proto_arg (arg6); + AC_PROTO_PUTC ('\r'); +} + +/** Send a command with 8 bytes arguments. */ +extern inline void +proto_send8b (uint8_t cmd, + uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t arg3, + uint8_t arg4, uint8_t arg5, uint8_t arg6, uint8_t arg7) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + proto_arg (arg6); + proto_arg (arg7); + AC_PROTO_PUTC ('\r'); +} + diff --git a/digital/avr/modules/proto/test/Makefile b/digital/avr/modules/proto/test/Makefile new file mode 100644 index 00000000..801870af --- /dev/null +++ b/digital/avr/modules/proto/test/Makefile @@ -0,0 +1,12 @@ +BASE = ../../.. +PROGS = test_proto +test_proto_SOURCES = test_proto.c +MODULES = proto uart utils +CONFIGFILE = avrconfig.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/proto/test/avrconfig.h b/digital/avr/modules/proto/test/avrconfig.h new file mode 100644 index 00000000..8a514104 --- /dev/null +++ b/digital/avr/modules/proto/test/avrconfig.h @@ -0,0 +1,86 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.proto - Protocol AVR 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 PTS + +/* 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 1 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/proto/test/test_proto.c b/digital/avr/modules/proto/test/test_proto.c new file mode 100644 index 00000000..21edaf59 --- /dev/null +++ b/digital/avr/modules/proto/test/test_proto.c @@ -0,0 +1,84 @@ +/* test_proto.c */ +/* {{{ + * + * Copyright (C) 2004 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * 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 "io.h" +#include "modules/uart/uart.h" +#include "modules/proto/proto.h" +#include "modules/utils/utils.h" + +void +proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ +/* This macro combine command and size in one integer. */ +#define c(cmd, size) (cmd << 8 | size) + switch (c (cmd, size)) + { + case c ('z', 0): + /* This should be generaly implemented. */ + utils_reset (); + break; + case c ('a', 1): + case c ('a', 4): + case c ('b', 2): + case c ('c', 3): + case c ('d', 4): + case c ('e', 5): + case c ('f', 6): + case c ('g', 7): + case c ('h', 8): + /* Accepts some command, and test some commands. */ + proto_send1b ('e', 0xf0); + proto_send2w ('l', 0x1234, 0x5678); + proto_send1d ('o', 0x12345678); + { + volatile uint32_t i = 0x12345678; + proto_send1d ('i', i); + } + break; + default: + /* This is to handle default commands, return an error. */ + 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 (); + /* This command should be generaly sent on reset. */ + proto_send0 ('z'); + /* This is to accept commands. */ + while (1) + { + uint8_t c = uart0_getc (); + proto_accept (c); + } +} diff --git a/digital/avr/modules/proto/utils/protodec b/digital/avr/modules/proto/utils/protodec new file mode 100755 index 00000000..014d119e --- /dev/null +++ b/digital/avr/modules/proto/utils/protodec @@ -0,0 +1,107 @@ +#!/usr/bin/perl -w +use strict; + +sub syntax +{ + print <= 2 ** ($b - 1)) { + return -(2 ** $b - $h); + } else { + return $h; + } +} + +# Process one proto packet. +sub prcmd +{ + my ($cmd, $c, @v) = @_; + # Return if not wanted. + return unless exists $$cmd{$c}; + print $c; + # Print each args. + for (@{$$cmd{$c}}) + { + /^(\d+)-(\d+)(?:\.(\d+))?(u?)$/o; + my $fp = 0; + $fp = $3 if $3; + if ($4 eq 'u') { + print ' ', (cvhexu @v[$1 - 1 .. $2 - 1]) / (1 << $fp); + } else { + print ' ', (cvhex @v[$1 - 1 .. $2 - 1]) / (1 << $fp); + } + } + print "\n"; +}; + +# Read command line. +my %cmd; +my ($acmd, @acmdl); + +while ($_ = shift) +{ + # Command char. + /^[a-zA-Z]$/ and do { + $cmd{$acmd} = [ @acmdl ] if defined $acmd; + @acmdl = (); + $acmd = $_; + next; + }; + # Single arg. + /^(\d+)(\.\d+)?(u?)$/ and do { + syntax if !defined $acmd; + push @acmdl, "$1-$1$2"; + next; + }; + # Range arg. + /^(\d+)-(\d+)(\.\d+)?(u?)$/ and do { + syntax if !defined $acmd; + syntax if $2 <= $1; + push @acmdl, $_; + next; + }; + syntax; +} +$cmd{$acmd} = [ @acmdl ] if defined $acmd; + +syntax if !scalar %cmd; + +# For each line. +while (<>) +{ + chomp; + # Match a proto packet. + if (/^!([a-zA-Z])(?:[a-f0-9]{2})*$/o) + { + my $c = $1; + s/^!([a-zA-Z])//; + my @args = /[a-f0-9]{2}/og; + prcmd \%cmd, $c, @args; + } + if (/^#.*$/o) + { + print "$_\n"; + } +} diff --git a/digital/avr/modules/twi/Makefile b/digital/avr/modules/twi/Makefile new file mode 100644 index 00000000..731c2ce3 --- /dev/null +++ b/digital/avr/modules/twi/Makefile @@ -0,0 +1,5 @@ +BASE = ../../.. +DOC = twi.html +EXTRACTDOC = twi.h avrconfig.h + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/twi/Makefile.module b/digital/avr/modules/twi/Makefile.module new file mode 100644 index 00000000..422cc96e --- /dev/null +++ b/digital/avr/modules/twi/Makefile.module @@ -0,0 +1 @@ +twi_SOURCES = twi.c diff --git a/digital/avr/modules/twi/README b/digital/avr/modules/twi/README new file mode 100644 index 00000000..8fd9677a --- /dev/null +++ b/digital/avr/modules/twi/README @@ -0,0 +1,23 @@ +avr.twi - TWI AVR module. + +Twi module for AVR. + +Copyright (C) 2005 Demonchy Clément + +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. diff --git a/digital/avr/modules/twi/avrconfig.h b/digital/avr/modules/twi/avrconfig.h new file mode 100644 index 00000000..638a773d --- /dev/null +++ b/digital/avr/modules/twi/avrconfig.h @@ -0,0 +1,31 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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. + * + * }}} */ + +#define TWI_SL_RCPT_SIZE 1 +#define TWI_SL_SEND_SIZE 1 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/twi/test/Makefile.master b/digital/avr/modules/twi/test/Makefile.master new file mode 100644 index 00000000..fa4f22ed --- /dev/null +++ b/digital/avr/modules/twi/test/Makefile.master @@ -0,0 +1,25 @@ +BASE = ../../.. +AVR_PROGS = test_twi_master +test_twi_master_SOURCES = test_twi_master.c +DOC = +EXTRACTDOC = +MODULES = twi uart proto + + +CONFIGFILE = avrconfig_master.h +TEST_CONFIGFILES = avrconfig_master.h + + +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8535 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +DEFS = +LIBS = + +# Test compilations. +TEST_MCU = atmega8535 atmega128 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/twi/test/Makefile.slave b/digital/avr/modules/twi/test/Makefile.slave new file mode 100644 index 00000000..306ee1cf --- /dev/null +++ b/digital/avr/modules/twi/test/Makefile.slave @@ -0,0 +1,24 @@ +BASE = ../../.. +AVR_PROGS = test_twi_sl +test_twi_sl_SOURCES = test_twi_sl.c +DOC = +EXTRACTDOC = +MODULES = twi uart + + +CONFIGFILE = avrconfig_slave.h +TEST_CONFIGFILES = avrconfig_slave.h + +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega128 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +DEFS = +LIBS = + +# Test compilations. +TEST_MCU = atmega8535 atmega128 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/twi/test/avrconfig_master.h b/digital/avr/modules/twi/test/avrconfig_master.h new file mode 100644 index 00000000..6496886d --- /dev/null +++ b/digital/avr/modules/twi/test/avrconfig_master.h @@ -0,0 +1,92 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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. + * + * }}} */ + +#define TWI_SL_RCPT_SIZE 1 +#define TWI_SL_SEND_SIZE 1 + +#define TWI_MASTER_ENABLE 1 + +/* 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 1 + +/* 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 9600 +/** Send mode: + * - POLLING: no interrupts. + * - RING: interrupts, ring buffer. */ +#define AC_UART0_SEND_MODE POLLING +/** Recv mode, same as send mode. */ +#define AC_UART0_RECV_MODE POLLING +/** 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 + + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/twi/test/avrconfig_slave.h b/digital/avr/modules/twi/test/avrconfig_slave.h new file mode 100644 index 00000000..6fdfd9ad --- /dev/null +++ b/digital/avr/modules/twi/test/avrconfig_slave.h @@ -0,0 +1,92 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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. + * + * }}} */ + +#define TWI_SL_RCPT_SIZE 1 +#define TWI_SL_SEND_SIZE 1 + +#define TWI_SLAVE_ENABLE 1 + +/* 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 1 + +/* 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 1 +/** Baudrate: 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800, + * 115200, 230400, 250000, 500000, 1000000. */ +#define AC_UART0_BAUDRATE 9600 +/** Send mode: + * - POLLING: no interrupts. + * - RING: interrupts, ring buffer. */ +#define AC_UART0_SEND_MODE POLLING +/** Recv mode, same as send mode. */ +#define AC_UART0_RECV_MODE POLLING +/** 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 + + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/twi/test/test_twi_master.c b/digital/avr/modules/twi/test/test_twi_master.c new file mode 100644 index 00000000..348ac950 --- /dev/null +++ b/digital/avr/modules/twi/test/test_twi_master.c @@ -0,0 +1,94 @@ +/* test_twi_master.c */ +/* avr.twi.master - TWI master module. {{{ + * + * Copyright (C) 2005 Clément Demonchy + * + * 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/uart/uart.h" +#include "modules/proto/proto.h" +#include "modules/twi/twi.h" +#include "modules/utils/utils.h" +#include "io.h" + +void proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ + uint8_t data[1] = {0x00}; + int8_t c; + switch (cmd) + { + case 's': + if (size == 2) + { + proto_send ('s', 0, 0); + twi_ms_send (args[0], &args[1], 1); + while (!twi_ms_is_finished ()) + ; + proto_send ('f', 0, 0); + } + else + proto_send ('e', 0, 0); + break; + case 'r': + if (size == 2) + { + uart0_putc ('r'); + c = twi_ms_read (args[0], data, 1); + if (c != 0) + proto_send ('e', 1 , 0); + else + { + while (!twi_ms_is_finished ()) + ; + proto_send ('f', 1, data); + } + } + else + proto_send ('e', 1, 0); + break; + case 'z': + utils_reset (); + break; + default: + proto_send ('e', 1, 0); + } +} + +int +main (void) +{ + uint8_t c; + sei (); + uart0_init (); + twi_init (0x04); + uart0_putc ('m'); + uart0_putc ('s'); + uart0_putc ('s'); + uart0_putc ('\r'); + while (42) + { + c = uart0_getc (); + proto_accept (c); + } + return 0; +} diff --git a/digital/avr/modules/twi/test/test_twi_sl.c b/digital/avr/modules/twi/test/test_twi_sl.c new file mode 100644 index 00000000..8672a6f7 --- /dev/null +++ b/digital/avr/modules/twi/test/test_twi_sl.c @@ -0,0 +1,51 @@ +/* test_twi_slave.c */ +/* avr.twi.slave - TWI slave module. {{{ + * + * Copyright (C) 2005 Clément Demonchy + * + * 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/twi/twi.h" +#include "modules/uart/uart.h" +#include "io.h" + +int +main (void) +{ + uint8_t data[TWI_SL_RCPT_SIZE]; + sei (); + uart0_init (); + uart0_putc ('s'); + uart0_putc ('s'); + uart0_putc ('s'); + twi_init (0x02); + data[0] = 0; + while (42) + { + if (twi_sl_poll (data, TWI_SL_RCPT_SIZE)) + { + twi_sl_update (data, TWI_SL_RCPT_SIZE); + } + } + return 0; +} diff --git a/digital/avr/modules/twi/twi.avr.c b/digital/avr/modules/twi/twi.avr.c new file mode 100644 index 00000000..3b2a8e66 --- /dev/null +++ b/digital/avr/modules/twi/twi.avr.c @@ -0,0 +1,363 @@ +/* twi.avr.c */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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 "twi.h" + +#include +#include +// #include "modules/uart/uart.h" + +// TODO mettre l'etat partout +// quand on fait les demandes, et les liberations qui vont bien dans +// l'interruption + +enum +{ + TWI_SUCCESS, + TWI_BUSY, + TWI_FREE, + TWI_FAILURE +}; + +#ifdef TWI_SLAVE_ENABLE +/* données reçues du master */ +static volatile uint8_t rcpt_buf_sl[TWI_SL_RCPT_SIZE]; +static volatile uint8_t data_ready_sl; +/* données à envoyer au master */ +/* 2 buffers 1 pour envoyer vers l'user et l'autre vers l'i2c */ +static volatile uint8_t send_buf_sl1[TWI_SL_SEND_SIZE]; +static volatile uint8_t send_buf_sl2[TWI_SL_SEND_SIZE]; +static volatile uint8_t *send_sys_sl, *send_user_sl; +static volatile uint8_t update_sl; /* lock pour savoir si on peut switcher les buffers sans risque */ +static volatile uint8_t send_switch_sl; +#endif /* TWI_SLAVE_ENABLE */ +#ifdef TWI_MASTER_ENABLE +static volatile int8_t state_ms; +static volatile int8_t nb_retry_ms = 5; // XXX utile ? +static volatile uint8_t dest_addr_ms; +static volatile uint8_t len_buf_ms; +static volatile uint8_t *send_buf_ms; +#endif /* TWI_MASTER_ENABLE */ + +void +twi_init (uint8_t addr) +{ +#ifdef TWI_SLAVE_ENABLE + data_ready_sl = 0; + send_switch_sl = 0; + update_sl = 0; + send_sys_sl = send_buf_sl1; + send_user_sl = send_buf_sl2; + TWAR = addr; + TWSR = 0x00; + TWCR = _BV(TWEA); +#endif /* TWI_SLAVE_ENABLE */ +#ifdef TWI_MASTER_ENABLE + #if defined(TWPS0) + TWSR = 0; + #endif + TWBR = (AC_FREQ / 100000UL - 16) / 2; + state_ms = TWI_FREE; +#endif /* TWI_MASTER_ENABLE */ + /* Active la twi et les interruptions de la twi */ + TWCR |= _BV (TWEN) | _BV (TWIE); +} + +#ifdef TWI_SLAVE_ENABLE +uint8_t +twi_sl_poll (uint8_t *buffer, uint8_t size) +{ + // XXX state + if (data_ready_sl) + { + data_ready_sl = 0; + while (size --) + buffer[size] = rcpt_buf_sl[size]; + /* de nouveau dispo pour traiter de nouvelles requetes */ + TWCR |= _BV (TWEA); + return 1; + } + else + return 0; +} +#endif /* TWI_SLAVE_ENABLE */ + +#ifdef TWI_SLAVE_ENABLE +void +twi_sl_update (uint8_t *buffer, uint8_t size) +{ + // XXX state + update_sl = 1; + send_switch_sl = 1; /* demander un swap des buffers */ + while (size --) + send_user_sl[size] = buffer[size]; + update_sl = 0; +} +#endif /* TWI_SLAVE_ENABLE */ + +#ifdef TWI_MASTER_ENABLE +int8_t +twi_ms_is_finished () +{ + if (state_ms == TWI_SUCCESS || state_ms == TWI_FAILURE) + { + state_ms = TWI_FREE; + return 1; + } + else + return 0; +} +#endif /* TWI_MASTER_ENABLE */ + +#ifdef TWI_MASTER_ENABLE +int8_t +twi_ms_send (uint8_t addr, uint8_t *data, uint8_t len) +{ + //uart0_putc ('a'); + if (state_ms != TWI_BUSY) + { + //uart0_putc ('b'); + state_ms = TWI_BUSY; + nb_retry_ms = 0; + dest_addr_ms = addr & 0xfe; + len_buf_ms = len; + send_buf_ms = data; + /* envoie du start */ + TWCR |= _BV(TWSTA) | _BV(TWINT); + return 0; + } + else + { + //uart0_putc ('c'); + return -1; + } +} +#endif /* TWI_MASTER_ENABLE */ + +#ifdef TWI_MASTER_ENABLE +int8_t +twi_ms_read (uint8_t addr, uint8_t *data, uint8_t len) +{ + + //uart0_putc ('z'); + if (state_ms != TWI_BUSY) + { + //uart0_putc ('y'); + state_ms = TWI_BUSY; + nb_retry_ms = 0; + dest_addr_ms = addr | 0x01; + len_buf_ms = len; + send_buf_ms = data; + TWCR |= _BV(TWSTA) | _BV (TWINT); + return 0; + } + else + { + //uart0_putc ('x'); + return -1; + } +} +#endif /* TWI_MASTER_ENABLE */ + +SIGNAL (SIG_2WIRE_SERIAL) +{ +#ifdef TWI_SLAVE_ENABLE + static uint8_t send_idx_sl = 0; + static uint8_t rcpt_idx_sl = 0; +#endif /* TWI_SLAVE_ENABLE */ +#ifdef TWI_MASTER_ENABLE + static uint8_t idx_ms; +#define NB_RETRY 5 +#endif /* TWI_MASTER_ENABLE */ + switch (TW_STATUS) + { +#ifdef TWI_SLAVE_ENABLE + /***** slave transmitter mode *****/ + /* START + SLA|W + ACK + * on a recu un start pour une ecriture et on a acquité + * choisi le buffer d'envoie + * envoie le premier byte + */ + case TW_ST_SLA_ACK: + case TW_ST_ARB_LOST_SLA_ACK: + if (send_switch_sl && !update_sl) + { + volatile uint8_t *tmp = send_sys_sl; + send_sys_sl = send_user_sl; + send_user_sl = tmp; + send_switch_sl = 0; + } + send_idx_sl = 0; + /* NO BREAK */ + /* Recu un ack apres l'envoie d'un bit */ + case TW_ST_DATA_ACK: + //uart0_putc ('p'); + TWDR = send_sys_sl[send_idx_sl++]; + if (send_idx_sl == TWI_SL_SEND_SIZE) + TWCR &= ~_BV(TWEA); + TWCR |= _BV(TWINT); + break; + case TW_ST_DATA_NACK: + case TW_ST_LAST_DATA: + //uart0_putc ('q'); + TWCR |= _BV (TWEA); + TWCR |= _BV(TWINT); + break; + /***** slave receiver mode *****/ + /* START + SLA|W + ACK */ + case TW_SR_SLA_ACK: + case TW_SR_ARB_LOST_SLA_ACK: + case TW_SR_GCALL_ACK: + case TW_SR_ARB_LOST_GCALL_ACK: + //uart0_putc ('u'); + data_ready_sl = 0; + rcpt_idx_sl = 0; + if (TWI_SL_RCPT_SIZE == 1) + TWCR &= ~_BV(TWEA); + TWCR |= _BV(TWINT); + break; + /* DATA + ACK */ + case TW_SR_DATA_ACK: + case TW_SR_GCALL_DATA_ACK: + //uart0_putc ('s'); + rcpt_buf_sl[rcpt_idx_sl++] = TWDR; + if (TWI_SL_RCPT_SIZE - rcpt_idx_sl == 1) + TWCR &= ~_BV(TWEA); + TWCR |= _BV(TWINT); + break; + /* DATA + NACK */ + case TW_SR_DATA_NACK: + case TW_SR_GCALL_DATA_NACK: + //uart0_putc ('o'); + rcpt_buf_sl[rcpt_idx_sl++] = TWDR; + /* NO BREAK */ + /* STOP */ + case TW_SR_STOP: + //uart0_putc ('q'); + data_ready_sl = 1; + TWCR |= _BV(TWINT); + break; +#endif /* TWI_SLAVE_ENABLE */ +#ifdef TWI_MASTER_ENABLE + /* Master */ + case TW_START: + case TW_REP_START: + //uart0_putc ('d'); + /* start transmis, on envoie l'adresse */ + TWCR &= ~ (_BV (TWSTA) | _BV (TWSTO) | _BV (TWINT)); + TWDR = dest_addr_ms; + idx_ms = 0; + TWCR |= _BV (TWINT); + break; + case TW_MT_ARB_LOST: /* valable pour le receiver aussi */ + /* todo */ + break; + /* Master Transmitter */ + case TW_MT_DATA_ACK: + case TW_MT_SLA_ACK: + //uart0_putc ('e'); + /* start transmis, on envoie l'adresse */ + /* slave ok + * On envoi des données si il en reste + */ + if (idx_ms < len_buf_ms) + { + TWDR = send_buf_ms[idx_ms ++]; + } + else + { + TWCR |= _BV (TWSTO); + state_ms = TWI_SUCCESS; + } + TWCR |= _BV (TWINT); + break; + case TW_MT_SLA_NACK: + //uart0_putc ('f'); + /* start transmis, on envoie l'adresse */ + /* le slave ne repond plus + * on essaye NB_RETRY avant d'arreter + */ + if (nb_retry_ms < NB_RETRY) + { + TWCR |= _BV (TWSTA); + nb_retry_ms ++; + } + else + { + TWCR |= _BV (TWSTO); + state_ms = TWI_FAILURE; + } + TWCR |= _BV (TWINT); + break; + case TW_MT_DATA_NACK: + //uart0_putc ('g'); + /* start transmis, on envoie l'adresse */ + /* le slave ne veut plus de donnée */ + TWCR |= _BV (TWSTO); + state_ms = TWI_SUCCESS; + TWCR |= _BV (TWINT); + break; + /* Master Receiver */ + case TW_MR_SLA_ACK: + //uart0_putc ('h'); + /* start transmis, on envoie l'adresse */ + if (len_buf_ms > 1) /* on recoit plusieurs octet */ + { + TWCR |= _BV (TWEA); + } + TWCR |= _BV (TWINT); + break; + case TW_MR_SLA_NACK: + /* start transmis, on envoie l'adresse */ + if (nb_retry_ms < NB_RETRY) + { + //uart0_putc ('i'); + TWCR |= _BV (TWEA); + } + else + { + //uart0_putc ('j'); + TWCR |= _BV (TWSTO); + state_ms = TWI_FAILURE; + } + TWCR |= _BV (TWINT); + break; + case TW_MR_DATA_ACK: + //uart0_putc ('k'); + send_buf_ms[idx_ms ++] = TWDR; + if (idx_ms == (len_buf_ms - 1)) + TWCR &= ~ _BV (TWEA); + TWCR |= _BV (TWINT); + break; + case TW_MR_DATA_NACK: /* dernier byte */ + //uart0_putc ('l'); + state_ms = TWI_SUCCESS; + send_buf_ms[idx_ms ++] = TWDR; + TWCR |= _BV (TWSTO); + TWCR |= _BV (TWINT); + break; +#endif/* TWI_MASTER_ENABLE */ + } +} diff --git a/digital/avr/modules/twi/twi.c b/digital/avr/modules/twi/twi.c new file mode 100644 index 00000000..e60bfa90 --- /dev/null +++ b/digital/avr/modules/twi/twi.c @@ -0,0 +1,33 @@ +/* twi.c */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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 "twi.h" + +#if defined (HOST) +# error "TO BE IMPLEMENTED" +#elif defined (SIMU) +# error "TO BE IMPLEMENTED" +#else +# include "twi.avr.c" +#endif diff --git a/digital/avr/modules/twi/twi.h b/digital/avr/modules/twi/twi.h new file mode 100644 index 00000000..f036417e --- /dev/null +++ b/digital/avr/modules/twi/twi.h @@ -0,0 +1,55 @@ +#ifndef twi_h +#define twi_h +/* twi.h */ +/* avr.twi - TWI AVR module. {{{ + * + * Copyright (C) 2005 Demonchy Clément + * + * 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 + +/** Initialise twi. */ +void +twi_init (uint8_t addr); + +#ifdef TWI_SLAVE_ENABLE +/** Récupère dans buffer les données recues en tant qu'esclave */ +uint8_t +twi_sl_poll (uint8_t *buffer, uint8_t size); +/** Met à jour le buffer de donnée à envoyer */ +void +twi_sl_update (uint8_t *buffer, uint8_t size); +#endif /* TWI_SLAVE_ENABLE */ + +#ifdef TWI_MASTER_ENABLE +/** Is the current transaction finished ? */ +int8_t +twi_ms_is_finished (void); +/** Send len bytes of data to address */ +int8_t +twi_ms_send (uint8_t address, uint8_t *data, uint8_t len); +/** Read len bytes at addresse en put them in data */ +int8_t +twi_ms_read (uint8_t address, uint8_t *data, uint8_t len); +#endif /* TWI_MASTER_ENABLE */ + +#endif /* twi_h */ diff --git a/digital/avr/modules/uart/Makefile b/digital/avr/modules/uart/Makefile new file mode 100644 index 00000000..f0f25611 --- /dev/null +++ b/digital/avr/modules/uart/Makefile @@ -0,0 +1,5 @@ +BASE = ../.. +DOC = uart.html +EXTRACTDOC = uart.h avrconfig.h + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/uart/Makefile.module b/digital/avr/modules/uart/Makefile.module new file mode 100644 index 00000000..09f3b60e --- /dev/null +++ b/digital/avr/modules/uart/Makefile.module @@ -0,0 +1,3 @@ +uart_SOURCES = uart0.c uart1.c +EXTRA_CLEAN_FILES += uart0.pts uart1.pts +HOST_LIBS += -lutil diff --git a/digital/avr/modules/uart/README b/digital/avr/modules/uart/README new file mode 100644 index 00000000..4ec8736a --- /dev/null +++ b/digital/avr/modules/uart/README @@ -0,0 +1,24 @@ +avr.uart - UART AVR module. + +Uart module for AVR. See modules README for more details about AVR modules. + + +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. diff --git a/digital/avr/modules/uart/avrconfig.h b/digital/avr/modules/uart/avrconfig.h new file mode 100644 index 00000000..d645e69a --- /dev/null +++ b/digital/avr/modules/uart/avrconfig.h @@ -0,0 +1,71 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h - UART module configuration template. */ +/* avr.uart - UART AVR 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. + * + * }}} */ + +/* 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 PTS +/** 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 PTS + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/uart/test/Makefile b/digital/avr/modules/uart/test/Makefile new file mode 100644 index 00000000..4f394f2a --- /dev/null +++ b/digital/avr/modules/uart/test/Makefile @@ -0,0 +1,18 @@ +BASE = ../../.. +PROGS = test_uart +SIMU_PROGS = test_uart +test_uart_SOURCES = test_uart.c +MODULES = uart utils +CONFIGFILE = avrconfig_ring.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +# Test compilations. +TEST_MCU = atmega8 atmega8535 atmega128 +TEST_CONFIGFILES = avrconfig_ring.h avrconfig_polling.h avrconfig_twoports.h +avrconfig_twoports_TEST_MCU = atmega128 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/uart/test/avrconfig_polling.h b/digital/avr/modules/uart/test/avrconfig_polling.h new file mode 100644 index 00000000..99b45147 --- /dev/null +++ b/digital/avr/modules/uart/test/avrconfig_polling.h @@ -0,0 +1,76 @@ +#ifndef avrconfig_polling_h +#define avrconfig_polling_h +/* avrconfig_polling.h - test_uart config file. */ +/* avr.uart - UART AVR 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 9600 +/** Send mode: + * - POLLING: no interrupts. + * - RING: interrupts, ring buffer. */ +#define AC_UART0_SEND_MODE POLLING +/** Recv mode, same as send mode. */ +#define AC_UART0_RECV_MODE POLLING +/** 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 + +#endif /* avrconfig_polling_h */ diff --git a/digital/avr/modules/uart/test/avrconfig_ring.h b/digital/avr/modules/uart/test/avrconfig_ring.h new file mode 100644 index 00000000..f35f9048 --- /dev/null +++ b/digital/avr/modules/uart/test/avrconfig_ring.h @@ -0,0 +1,76 @@ +#ifndef avrconfig_ring_h +#define avrconfig_ring_h +/* avrconfig_ring.h - test_uart config file. */ +/* avr.uart - UART AVR 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 PTS +/** 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 PTS + +#endif /* avrconfig_ring_h */ diff --git a/digital/avr/modules/uart/test/avrconfig_twoports.h b/digital/avr/modules/uart/test/avrconfig_twoports.h new file mode 100644 index 00000000..d4c8fa6c --- /dev/null +++ b/digital/avr/modules/uart/test/avrconfig_twoports.h @@ -0,0 +1,76 @@ +#ifndef avrconfig_twoports_h +#define avrconfig_twoports_h +/* avrconfig_twoports.h - test_uart config file. */ +/* avr.uart - UART AVR 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 POLLING +/** 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 DROP +/** In HOST compilation: + * - STDIO: use stdin/out. + * - PTS: use pseudo terminal. */ +#define AC_UART0_HOST_DRIVER PTS +/** Same thing for secondary port. */ +#define AC_UART1_PORT 1 +#define AC_UART1_BAUDRATE 115200 +#define AC_UART1_SEND_MODE POLLING +#define AC_UART1_RECV_MODE RING +#define AC_UART1_CHAR_SIZE 8 +#define AC_UART1_PARITY ODD +#define AC_UART1_STOP_BITS 2 +#define AC_UART1_SEND_BUFFER_SIZE 32 +#define AC_UART1_RECV_BUFFER_SIZE 16 +#define AC_UART1_SEND_BUFFER_FULL DROP +#define AC_UART1_HOST_DRIVER PTS + +#endif /* avrconfig_twoports_h */ diff --git a/digital/avr/modules/uart/test/test_uart.c b/digital/avr/modules/uart/test/test_uart.c new file mode 100644 index 00000000..86b20581 --- /dev/null +++ b/digital/avr/modules/uart/test/test_uart.c @@ -0,0 +1,70 @@ +/* test_uart.c */ +/* avr.uart - UART AVR 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/uart/uart.h" +#include "modules/utils/utils.h" +#include "io.h" + +int +main (int argc, char **argv) +{ + avr_init (argc, argv); + sei (); + uart0_init (); + uart0_putc ('N'); + uart0_putc ('i'); + uart0_putc ('0'); + uart0_putc ('!'); + uart0_putc ('\r'); +#if AC_UART1_PORT != -1 + uart1_init (); + uart1_putc ('N'); + uart1_putc ('i'); + uart1_putc ('1'); + uart1_putc ('!'); + uart1_putc ('\r'); + while (1) + { + utils_delay (0.1); + if (uart0_poll ()) + { + char c = uart0_getc (); + if (c == 'z') + utils_reset (); + uart0_putc (c); + } + if (uart1_poll ()) + uart1_putc (uart1_getc ()); + } +#else + while (1) + { + char c = uart0_getc (); + if (c == 'z') + utils_reset (); + uart0_putc (c); + } +#endif +} diff --git a/digital/avr/modules/uart/uart.avr.c b/digital/avr/modules/uart/uart.avr.c new file mode 100644 index 00000000..1282ad80 --- /dev/null +++ b/digital/avr/modules/uart/uart.avr.c @@ -0,0 +1,299 @@ +/* uart.avr.c */ +/* avr.uart - UART AVR 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 "uart.h" + +#include "uart_common.h" + +#if AC_UART (PORT) != -1 + +#include "io.h" + +/* Tested AVR check. */ +#if defined (__AVR_ATmega8__) +#elif defined (__AVR_ATmega8535__) +#elif defined (__AVR_ATmega128__) +# define PE UPE +#elif defined (__AVR_ATmega64__) +# define PE UPE +#else +# warning "uart: not tested on this chip" +#endif + +/* UART port number. */ +#if AC_UART (PORT) == 0 +# if !defined (UBRRH) +# if defined (UBRR0H) +# define UBRRH UBRR0H +# define UBRRL UBRR0L +# define UCSRA UCSR0A +# define UCSRB UCSR0B +# define UCSRC UCSR0C +# define UDR UDR0 +# define SIG_UART_RECV SIG_UART0_RECV +# define SIG_UART_DATA SIG_UART0_DATA +# else +# error "uart: can not find uart 0" +# endif /* defined (UBRR0H) */ +# endif /* !defined (UBRRH) */ +#else /* AC_UART (PORT) == 1 */ +# if defined (UBRR1H) +# define UBRRH UBRR1H +# define UBRRL UBRR1L +# define UCSRA UCSR1A +# define UCSRB UCSR1B +# define UCSRC UCSR1C +# define UDR UDR1 +# define SIG_UART_RECV SIG_UART1_RECV +# define SIG_UART_DATA SIG_UART1_DATA +# else +# error "uart: can not find uart 1" +# endif /* defined (UBRR1H) */ +#endif /* AC_UART (PORT) == 1 */ + +/* UR selector (UCSRC & UBRRH multiplexed). */ +#if defined (URSEL) +# define SELECTOR _BV (URSEL) +#else +# define SELECTOR 0 +#endif + +/* Baud rate error check. */ +#define UBRR_VAL (AC_FREQ / 16 / AC_UART (BAUDRATE) - 1) +#define BAUDRATE_VAL (AC_FREQ / 16 / (UBRR_VAL + 1)) + +#if BAUDRATE_VAL - AC_UART (BAUDRATE) > 2 +#warning "uart: baud rate error > 2" +#elif BAUDRATE_VAL - AC_UART (BAUDRATE) > 1 +#warning "uart: baud rate error > 1" +#elif BAUDRATE_VAL - AC_UART (BAUDRATE) > 0 +#warning "uart: baud rate error > 0" +#endif + +/* Mode. */ +#define POLLING 1 +#define RING 2 +#define SEND_MODE AC_UART (SEND_MODE) +#define RECV_MODE AC_UART (RECV_MODE) +#if RECV_MODE == POLLING +# define RECV_IE 0 +#elif RECV_MODE == RING +# define RECV_IE _BV (RXCIE) +#else +# error "uart: bad mode" +#endif + +/* Parity. */ +#define ODD (_BV (UPM1) | _BV (UPM0)) +#define EVEN _BV (UPM1) +#define NONE 0 +#define PARITY AC_UART (PARITY) + +/* Stop bits. */ +#if AC_UART (STOP_BITS) == 1 +#define STOP_BITS 0 +#elif AC_UART (STOP_BITS) == 2 +#define STOP_BITS _BV (USBS) +#else +#error "uart: bad stop bits value" +#endif + +/* Character size. */ +#define CHAR_SIZE (_BV (UCSZ1) | _BV (UCSZ0)) + +/* Buffers. */ +#if SEND_MODE == RING +# define SEND_BUFFER_SIZE AC_UART (SEND_BUFFER_SIZE) +# define SEND_BUFFER_MASK (SEND_BUFFER_SIZE - 1) +# if SEND_BUFFER_SIZE & SEND_BUFFER_MASK +# error "uart: send buffer size must be a power of 2" +# endif +#endif +#if RECV_MODE == RING +# define RECV_BUFFER_SIZE AC_UART (RECV_BUFFER_SIZE) +# define RECV_BUFFER_MASK (RECV_BUFFER_SIZE - 1) +# if RECV_BUFFER_SIZE & RECV_BUFFER_MASK +# error "uart: recv buffer size must be a power of 2" +# endif +#endif + +/* Send buffer. */ +#if SEND_MODE == RING +static uint8_t uart_send_buffer[SEND_BUFFER_SIZE]; +static volatile uint8_t uart_send_head, uart_send_tail; +#endif + +/* Recv buffer. */ +#if RECV_MODE == RING +static uint8_t uart_recv_buffer[RECV_BUFFER_SIZE]; +static volatile uint8_t uart_recv_head, uart_recv_tail; +#endif + +/* Full buffer politic. */ +#define DROP 1 +#define WAIT 2 +#define SEND_BUFFER_FULL AC_UART (SEND_BUFFER_FULL) +#if SEND_BUFFER_FULL != DROP && SEND_BUFFER_FULL != WAIT +# error "uart: bad full buffer politic" +#endif + +/* Error code. */ +#define ERROR_BITS (_BV (FE) | _BV (DOR) | _BV (PE)) + +/* +AutoDec */ +/* -AutoDec */ + +/** Initialise uart. */ +void +uart_init (void) +{ + /* Set baud rate. */ +#if (UBRR_VAL >> 8) != 0 + UBRRH = UBRR_VAL >> 8; +#endif + UBRRL = UBRR_VAL & 0xff; + UCSRA = 0; + /* Set format and enable uart. */ + UCSRC = SELECTOR | PARITY | STOP_BITS | CHAR_SIZE; + UCSRB = RECV_IE | _BV (RXEN) | _BV (TXEN); +#if RECV_MODE == RING + uart_recv_head = 0; + uart_recv_tail = 0; +#endif +#if SEND_MODE == RING + uart_send_head = 0; + uart_send_tail = 0; +#endif +} + +/** Read a char. */ +uint8_t +uart_getc (void) +{ +#if RECV_MODE == POLLING + uint8_t tmperr, c; + loop_until_bit_is_set (UCSRA, RXC); + tmperr = UCSRA & ERROR_BITS; + c = UDR; + if (tmperr) + return 0xff; + else + return c; +#elif RECV_MODE == RING + uint8_t tmptail = uart_recv_tail; + while (uart_recv_head == tmptail) + ; + tmptail = (tmptail + 1) & RECV_BUFFER_MASK; + uart_recv_tail = tmptail; + return uart_recv_buffer[tmptail]; +#endif +} + +/** Write a char. */ +void +uart_putc (uint8_t c) +{ +#if SEND_MODE == POLLING +# if SEND_BUFFER_FULL == WAIT + loop_until_bit_is_set (UCSRA, UDRE); +# else + if (!(UCSRA & _BV (UDRE))) + return; +# endif + UDR = c; +#elif SEND_MODE == RING + uint8_t tmphead; + tmphead = (uart_send_head + 1) & SEND_BUFFER_MASK; +# if SEND_BUFFER_FULL == WAIT + while (tmphead == uart_send_tail) + ; +# else + if (tmphead == uart_send_tail) + return; +# endif + uart_send_buffer[tmphead] = c; + uart_send_head = tmphead; + UCSRB |= _BV (UDRIE); +#endif +} + +/** Retrieve availlable chars. */ +uint8_t +uart_poll (void) +{ +#if RECV_MODE == POLLING + return UCSRA & _BV (RXC); +#elif RECV_MODE == RING + return (uart_recv_head - uart_recv_tail) & RECV_BUFFER_MASK; +#endif +} + +#if RECV_MODE == RING + +/* Handle received char for ring buffer. */ +SIGNAL (SIG_UART_RECV) +{ + uint8_t c; + uint8_t tmphead; + uint8_t tmperr; + tmperr = UCSRA & ERROR_BITS; + c = UDR; + if (tmperr) + c = 0xff; + tmphead = (uart_recv_head + 1) & RECV_BUFFER_MASK; + uart_recv_head = tmphead; + /* If overflowed, clear the receive buffer. */ + if (tmphead == uart_recv_tail) + { + tmphead = (tmphead + 1) & RECV_BUFFER_MASK; + uart_recv_head = tmphead; + c = 0xff; + } + uart_recv_buffer[tmphead] = c; +} + +#endif /* RECV_MODE == RING */ + +#if SEND_MODE == RING + +/** Handle data register empty for ring buffer. */ +SIGNAL (SIG_UART_DATA) +{ + uint8_t tmptail; + if (uart_send_head != uart_send_tail) + { + tmptail = (uart_send_tail + 1) & SEND_BUFFER_MASK; + uart_send_tail = tmptail; + UDR = uart_send_buffer[tmptail]; + } + else + { + UCSRB &= ~_BV (UDRIE); + } +} + +#endif /* SEND_MODE == RING */ + +#endif /* AC_UART (PORT) != -1 */ diff --git a/digital/avr/modules/uart/uart.h b/digital/avr/modules/uart/uart.h new file mode 100644 index 00000000..f510a01d --- /dev/null +++ b/digital/avr/modules/uart/uart.h @@ -0,0 +1,60 @@ +#ifndef uart_h +#define uart_h +/* uart.h */ +/* avr.uart - UART AVR 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. + * + * }}} */ + +/** Initialise uart. */ +void +uart0_init (void); + +/** Read a char. */ +uint8_t +uart0_getc (void); + +/** Write a char. */ +void +uart0_putc (uint8_t c); + +/** Retrieve availlable chars. */ +uint8_t +uart0_poll (void); + +/** Initialise uart. */ +void +uart1_init (void); + +/** Read a char. */ +uint8_t +uart1_getc (void); + +/** Write a char. */ +void +uart1_putc (uint8_t c); + +/** Retrieve availlable chars. */ +uint8_t +uart1_poll (void); + +#endif /* uart_h */ diff --git a/digital/avr/modules/uart/uart.host.c b/digital/avr/modules/uart/uart.host.c new file mode 100644 index 00000000..9a335b2a --- /dev/null +++ b/digital/avr/modules/uart/uart.host.c @@ -0,0 +1,175 @@ +/* uart.host.c */ +/* avr.uart - UART AVR 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. + * + * }}} */ +#define _GNU_SOURCE +#include "common.h" +#include "uart.h" +#include "modules/host/host.h" + +#include "uart_common.h" + +#if AC_UART (PORT) != -1 + +#include +#include +#include +#include +#include +#include +#include + +/* Check uart driver. */ +#if UART_N == 0 +# define STDIO 1 +# define PTS 2 +# if AC_UART (HOST_DRIVER) == STDIO +# define DRIVER_STDIO +# elif AC_UART (HOST_DRIVER) == PTS +# else +# error "uart: invalid host driver" +# endif +#endif + +#ifndef DRIVER_STDIO + +/* Pseudo terminal file descriptor. */ +static int uart_pt_fd; + +/** Setup a non canonical mode. */ +static void +setup_raw (int fd) +{ + struct termios tc; + tcgetattr (fd, &tc); + tc.c_iflag &= ~(IGNPAR | PARMRK | ISTRIP | IGNBRK | BRKINT | IGNCR | + ICRNL | INLCR | IXON | IXOFF | IXANY | IMAXBEL); + tc.c_iflag |= INPCK; + tc.c_oflag &= ~(OPOST); + tc.c_cflag &= ~(HUPCL | CSTOPB | PARENB | PARODD | CSIZE); + tc.c_cflag |= CS8 | CLOCAL | CREAD; + tc.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN | NOFLSH | TOSTOP); + tc.c_cc[VTIME] = 0; + tc.c_cc[VMIN] = 1; + tcflush (fd, TCIFLUSH); + tcsetattr (fd, TCSANOW, &tc); +} + +#endif /* DRIVER_STDIO */ + +/** Initialise uart. */ +void +uart_init (void) +{ +#ifdef DRIVER_STDIO + int r; +# define uart_pt_fd_in 0 +# define uart_pt_fd_out 1 + /* Always use line buffering. */ + r = setvbuf (stdout, 0, _IOLBF, BUFSIZ); + assert (r == 0); +#else +# define uart_pt_fd_in uart_pt_fd +# define uart_pt_fd_out uart_pt_fd + int slave_fd; + const char *name; +#define STRINGIFY(x) #x +#define FILE_NAME(x) "uart" STRINGIFY(x) ".pts" + /* Try to access an already opened pts. */ + uart_pt_fd = host_fetch_integer (FILE_NAME (UART_N)); + if (uart_pt_fd == -1) + { + /* Open and unlock pt. */ + if (openpty (&uart_pt_fd, &slave_fd, 0, 0, 0) == -1 + || grantpt (uart_pt_fd) == -1 + || unlockpt (uart_pt_fd) == -1) + assert_perror (errno); + /* Make a link to the slave pts. */ + unlink (FILE_NAME (UART_N)); + name = ptsname (uart_pt_fd); + assert (name); + if (symlink (name, FILE_NAME (UART_N)) == -1) + assert_perror (errno); + /* Register the file descriptor in case of reset. */ + host_register_integer (FILE_NAME (UART_N), uart_pt_fd); + /* Make slave raw. */ + setup_raw (slave_fd); + /* slave_fd is left open. */ + } +#endif +} + +/** Read a char. */ +uint8_t +uart_getc (void) +{ + uint8_t c; + int n; + n = read (uart_pt_fd_in, &c, 1); + if (n == -1) + assert_perror (errno); +#ifdef DRIVER_STDIO + /* Quit if EOF from stdin. */ + if (n == 0) + exit (0); + if (c == '\n') + c = '\r'; +#else + /* This is a quite unusual and dangerous behavior... */ + if (n == 0) + return 0xff; +#endif + return c; +} + +/** Write a char. */ +void +uart_putc (uint8_t c) +{ +#ifdef DRIVER_STDIO + if (c == '\r') + c = '\n'; +#endif + write (uart_pt_fd_out, &c, 1); +} + +/** Retrieve availlable chars. */ +uint8_t +uart_poll (void) +{ + fd_set fds; + struct timeval tv; + int r; + /* Use select to poll. */ + FD_ZERO (&fds); + FD_SET (uart_pt_fd_in, &fds); + tv.tv_sec = 0; + tv.tv_usec = 0; + r = select (FD_SETSIZE, &fds, 0, 0, &tv); + /* Check result. */ + if (r == -1) + assert_perror (errno); + return r; +} + +#endif /* AC_UART (PORT) != -1 */ diff --git a/digital/avr/modules/uart/uart.simu.c b/digital/avr/modules/uart/uart.simu.c new file mode 100644 index 00000000..e8605790 --- /dev/null +++ b/digital/avr/modules/uart/uart.simu.c @@ -0,0 +1,78 @@ +/* uart.simu.c - used for simulavrxx pseudo ports. */ +/* avr.uart - UART AVR 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 "uart.h" + +#include "uart_common.h" + +#if AC_UART (PORT) != -1 + +int uart (eof); + +/** Initialise uart. */ +void +uart_init (void) +{ + uart (eof) = 0; +} + +/** Use this as exit point. */ +void +uart (exit) (void) +{ + uart (eof) = 1; +} + +/** Read a char. */ +uint8_t +uart_getc (void) +{ + uint8_t c; + if (uart (eof)) + return 0xff; + c = *(uint8_t *) 0x20; + if (!c) + { + uart (exit) (); + c = 0xff; + } + return c; +} + +/** Write a char. */ +void +uart_putc (uint8_t c) +{ + *(uint8_t *) 0x22 = c; +} + +/** Retrieve availlable chars. */ +uint8_t +uart_poll (void) +{ + return !uart (eof); +} + +#endif /* AC_UART (PORT) != -1 */ diff --git a/digital/avr/modules/uart/uart.txt b/digital/avr/modules/uart/uart.txt new file mode 100644 index 00000000..b6f1129f --- /dev/null +++ b/digital/avr/modules/uart/uart.txt @@ -0,0 +1,26 @@ +*Title: Module AVR UART +*Author: Ni + +* Utilisation + +Rien de plus simple. Appeler la fonction |uart0_init| au démarrage, puis +|uart0_putc| pour envoyer un caractère, |uart0_getc| pour en recevoir. La +fonction |uart0_poll| permet de connaître à l'avance si des caractère sont +disponibles. + +En cas d'erreur de réception, la fonction |uart0_getc| renvois 0xff. Ce n'est +pas forcément adapté à une transmission binaire car on ne peut pas distinguer +un 0xff légitime d'une erreur de transmission. + +On peut configurer deux uarts, dans ce cas les fonctions sont en double. + +Comme pour tous les modules, copier la partie concernant l'uart depuis +|avrconfig.h|. + +Dans le cas de la compilation en host, un pseudo-terminal est ouvert pour les +communications, un lien vers le pseudo-terminal est crée en |uart0.pts|. Dans +le futur, on pourra peut-être configurer ce fichier par la ligne de commande. + +* Doc + +*File: uart.exd diff --git a/digital/avr/modules/uart/uart0.c b/digital/avr/modules/uart/uart0.c new file mode 100644 index 00000000..4a8fb358 --- /dev/null +++ b/digital/avr/modules/uart/uart0.c @@ -0,0 +1,34 @@ +/* uart0.c - Compile primary port. */ +/* avr.uart - UART AVR 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. + * + * }}} */ + +#define UART_N 0 + +#if defined (HOST) +# include "uart.host.c" +#elif defined (SIMU) +# include "uart.simu.c" +#else +# include "uart.avr.c" +#endif diff --git a/digital/avr/modules/uart/uart1.c b/digital/avr/modules/uart/uart1.c new file mode 100644 index 00000000..c3915278 --- /dev/null +++ b/digital/avr/modules/uart/uart1.c @@ -0,0 +1,34 @@ +/* uart1.c - Compile secondary port. */ +/* avr.uart - UART AVR 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. + * + * }}} */ + +#define UART_N 1 + +#if defined (HOST) +# include "uart.host.c" +#elif defined (SIMU) +# include "uart.simu.c" +#else +# include "uart.avr.c" +#endif diff --git a/digital/avr/modules/uart/uart_common.h b/digital/avr/modules/uart/uart_common.h new file mode 100644 index 00000000..8f5a3af4 --- /dev/null +++ b/digital/avr/modules/uart/uart_common.h @@ -0,0 +1,87 @@ +#ifndef uart_common_h +#define uart_common_h +/* uart_common.h - UART module common part. */ +/* avr.uart - UART AVR 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. + * + * }}} */ + +/* This symbol should be 0 or 1. */ +#ifndef UART_N +# error "uart: UART_N missing" +#endif + +/* Utility macros. */ +#define PASTE4_SUB(a, b, c, d) a ## b ## c ## d +#define PASTE4(a, b, c, d) PASTE4_SUB (a, b, c, d) + +/* Port selection macros. */ +#define AC_UART(x) PASTE4(AC_UART, UART_N, _, x) +#define uart(x) PASTE4(uart, UART_N, _, x) + +/* Define uart symbols. */ +#define uart_error uart (error) +#define uart_error_code uart (error_code) +#define uart_getc uart (getc) +#define uart_init uart (init) +#define uart_poll uart (poll) +#define uart_putc uart (putc) +#define uart_recv_buffer uart (recv_buffer) +#define uart_recv_head uart (recv_head) +#define uart_recv_tail uart (recv_tail) +#define uart_send_buffer uart (send_buffer) +#define uart_send_head uart (send_head) +#define uart_send_tail uart (send_tail) + +/* Unimplemented features. */ +#if AC_UART (CHAR_SIZE) != 8 +# error "uart: char size != 8 not implemented" +#endif + +/* Test that everythings is configured. */ +#if !defined (AC_UART0_PORT) \ + || !defined (AC_UART0_BAUDRATE) \ + || !defined (AC_UART0_SEND_MODE) \ + || !defined (AC_UART0_RECV_MODE) \ + || !defined (AC_UART0_CHAR_SIZE) \ + || !defined (AC_UART0_PARITY) \ + || !defined (AC_UART0_STOP_BITS) \ + || !defined (AC_UART0_SEND_BUFFER_SIZE) \ + || !defined (AC_UART0_RECV_BUFFER_SIZE) \ + || !defined (AC_UART0_SEND_BUFFER_FULL) \ + || !defined (AC_UART0_HOST_DRIVER) \ + || !defined (AC_UART1_PORT) \ + || !defined (AC_UART1_BAUDRATE) \ + || !defined (AC_UART1_SEND_MODE) \ + || !defined (AC_UART1_RECV_MODE) \ + || !defined (AC_UART1_CHAR_SIZE) \ + || !defined (AC_UART1_PARITY) \ + || !defined (AC_UART1_STOP_BITS) \ + || !defined (AC_UART1_SEND_BUFFER_SIZE) \ + || !defined (AC_UART1_RECV_BUFFER_SIZE) \ + || !defined (AC_UART1_SEND_BUFFER_FULL) \ + || !defined (AC_UART1_HOST_DRIVER) \ + || AC_UART0_PORT == AC_UART1_PORT +# error "uart: error in configuration" +#endif + +#endif /* uart_common_h */ diff --git a/digital/avr/modules/utils/Makefile b/digital/avr/modules/utils/Makefile new file mode 100644 index 00000000..72c9ce66 --- /dev/null +++ b/digital/avr/modules/utils/Makefile @@ -0,0 +1,5 @@ +BASE = ../.. +DOC = utils.html +EXTRACTDOC = utils.h byte.h avrconfig.h + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/utils/Makefile.module b/digital/avr/modules/utils/Makefile.module new file mode 100644 index 00000000..935499a1 --- /dev/null +++ b/digital/avr/modules/utils/Makefile.module @@ -0,0 +1 @@ +utils_SOURCES = utils.host.c diff --git a/digital/avr/modules/utils/README b/digital/avr/modules/utils/README new file mode 100644 index 00000000..ac30e972 --- /dev/null +++ b/digital/avr/modules/utils/README @@ -0,0 +1,25 @@ +avr.utils - Utilities AVR module. + +Utilities module for AVR. Provide services like delay or reset. See modules +README for more details about AVR modules. + + +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. diff --git a/digital/avr/modules/utils/avrconfig.h b/digital/avr/modules/utils/avrconfig.h new file mode 100644 index 00000000..f3ace725 --- /dev/null +++ b/digital/avr/modules/utils/avrconfig.h @@ -0,0 +1,33 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h - Utilities module configuration template. */ +/* avr.utils - Utilities AVR 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 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/utils/byte.h b/digital/avr/modules/utils/byte.h new file mode 100644 index 00000000..436e0054 --- /dev/null +++ b/digital/avr/modules/utils/byte.h @@ -0,0 +1,100 @@ +#ifndef byte_h +#define byte_h +/* byte.h */ +/* avr.utils - Utilities AVR 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. + * + * }}} */ + +/** WARNING: Theses functions only works on little endian processor, do not + * use them on other processors, prefer the portable bit shifts and or. This + * file only exist to overide bad code production with avr-gcc in the bit + * shifts idiom. */ + +/* Union needed for byte access. */ +union _utils_byte_access +{ + uint8_t v8[4]; + uint16_t v16[2]; + uint32_t v32; +}; + +/** Byte packing macro, pack 4 bytes into a double word. */ +extern inline uint32_t +v8_to_v32 (uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) +{ + union _utils_byte_access ba; + ba.v8[0] = b0; + ba.v8[1] = b1; + ba.v8[2] = b2; + ba.v8[3] = b3; + return ba.v32; +} + +/** Byte packing macro, pack 2 bytes into a word. */ +extern inline uint16_t +v8_to_v16 (uint8_t b1, uint8_t b0) +{ + union _utils_byte_access ba; + ba.v8[0] = b0; + ba.v8[1] = b1; + return ba.v16[0]; +} + +/** Word packing macro, pack 2 words into a double word. */ +extern inline uint32_t +v16_to_v32 (uint16_t w1, uint16_t w0) +{ + union _utils_byte_access ba; + ba.v16[0] = w0; + ba.v16[1] = w1; + return ba.v32; +} + +/** Byte unpacking macro, extract one specified byte from a double word. */ +extern inline uint8_t +v32_to_v8 (uint32_t d, int pos) +{ + union _utils_byte_access ba; + ba.v32 = d; + return ba.v8[pos]; +} + +/** Byte unpacking macro, extract one specified byte from a word. */ +extern inline uint8_t +v16_to_v8 (uint16_t w, int pos) +{ + union _utils_byte_access ba; + ba.v16[0] = w; + return ba.v8[pos]; +} + +/** Word unpacking macro, extract one specified word from a double word. */ +extern inline uint16_t +v32_to_v16 (uint32_t d, int pos) +{ + union _utils_byte_access ba; + ba.v32 = d; + return ba.v16[pos]; +} + +#endif /* byte_h */ diff --git a/digital/avr/modules/utils/test/Makefile b/digital/avr/modules/utils/test/Makefile new file mode 100644 index 00000000..783d7922 --- /dev/null +++ b/digital/avr/modules/utils/test/Makefile @@ -0,0 +1,15 @@ +BASE = ../../.. +PROGS = test_utils test_byte +AVR_PROGS = test_byte_methods +test_utils_SOURCES = test_utils.c +test_byte_SOURCES = test_byte.c +test_byte_methods_SOURCES = test_byte_methods.c +MODULES = utils +CONFIGFILE = avrconfig.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega128 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/utils/test/avrconfig.h b/digital/avr/modules/utils/test/avrconfig.h new file mode 100644 index 00000000..f1b0e6f6 --- /dev/null +++ b/digital/avr/modules/utils/test/avrconfig.h @@ -0,0 +1,33 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.utils - Utilities AVR 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 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/utils/test/test_byte.c b/digital/avr/modules/utils/test/test_byte.c new file mode 100644 index 00000000..8f4770bf --- /dev/null +++ b/digital/avr/modules/utils/test/test_byte.c @@ -0,0 +1,39 @@ +/* test_byte.c */ +/* n.avr.utils - AVR utilities module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * 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/utils/byte.h" + +/* +AutoDec */ +/* -AutoDec */ + +int +main (void) +{ + volatile uint32_t d; + volatile uint8_t b0 = 1, b1 = 2, b2 = 3, b3 = 4; + d = v8_to_v32 (b3, b2, b1, b0); + b2 = v32_to_v8 (d, 2); + return 0; +} diff --git a/digital/avr/modules/utils/test/test_byte_methods.c b/digital/avr/modules/utils/test/test_byte_methods.c new file mode 100644 index 00000000..adf6d05e --- /dev/null +++ b/digital/avr/modules/utils/test/test_byte_methods.c @@ -0,0 +1,67 @@ +/* test_byte.c */ +/* n.avr.utils - AVR utilities module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * 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 "io.h" + +/* +AutoDec */ +/* -AutoDec */ + +#define nop() asm volatile ("nop" ::) + +/* Union for byte access. */ +union _utils_byte_access +{ + uint8_t v8[4]; + uint16_t v16[2]; + uint32_t v32; +}; + +int +main (void) +{ + union _utils_byte_access ba; + volatile uint32_t d = 0; + volatile uint8_t b0 = 1, b1 = 2, b2 = 3, b3 = 4; + nop (); // join union method. + ba.v8[0] = b0; ba.v8[1] = b1; ba.v8[2] = b2; ba.v8[3] = b3; + d = ba.v32; + nop (); // join asm method. + asm ("mov %A0, %1" "\r\n" + "mov %B0, %2" "\r\n" + "mov %C0, %3" "\r\n" + "mov %D0, %4" "\r\n" + : "=d" (d) : "r" (b0), "r" (b1), "r" (b2), "r" (b3)); + nop (); // split union method. + ba.v32 = d; + b2 = ba.v8[2]; + nop (); // split asm method. + asm ("mov %0, %A1" : "=r" (b2) : "d" (d)); + nop (); // b2 = d >> 16; + b2 = d >> 16; + nop (); // b2 = ((uint8_t *) &d)[2]; + b2 = ((uint8_t *) &d)[2]; + nop (); + return 0; +} diff --git a/digital/avr/modules/utils/test/test_utils.c b/digital/avr/modules/utils/test/test_utils.c new file mode 100644 index 00000000..d4df7b9e --- /dev/null +++ b/digital/avr/modules/utils/test/test_utils.c @@ -0,0 +1,49 @@ +/* test_utils.c */ +/* avr.utils - Utilities AVR 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/utils/utils.h" +#include "io.h" + +int +main (int argc, char **argv) +{ + avr_init (argc, argv); +#ifndef HOST + /* Test regv, the first one should generate a warning. */ + TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS00, CS01, + 0, 0, 0, 0, 0, 1, 1, 1); + TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS01, CS00, + 0, 0, 0, 0, 0, 1, 1, 1); +#endif + /* Test delays, use sei to separate loops in assembly listing. */ + sei (); utils_delay_ns (1); + sei (); utils_delay_ns (1000); + sei (); utils_delay_ns (1000000); + sei (); utils_delay (1); + sei (); utils_delay (4); + sei (); + /* Same player, play again. */ + utils_reset (); +} diff --git a/digital/avr/modules/utils/utils.avr.h b/digital/avr/modules/utils/utils.avr.h new file mode 100644 index 00000000..bdba7f6f --- /dev/null +++ b/digital/avr/modules/utils/utils.avr.h @@ -0,0 +1,105 @@ +#ifndef utils_avr_h +#define utils_avr_h +/* utils.avr.h */ +/* avr.utils - Utilities AVR 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 + +/** Helper macro to build register value. Call it like this : + * + * TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS01, CS00, + * 0, 0, 0, 0, 0, 1, 1, 1); + * + * The macro check that the bits are given in the right order and compute the + * register value. If the bits are false, the compiler will generate an + * warning about a constant being to large. + */ +#define regv(b7, b6, b5, b4, b3, b2, b1, b0, v7, v6, v5, v4, v3, v2, v1, v0) \ + ((b7) == 7 && (b6) == 6 && (b5) == 5 && (b4) == 4 \ + && (b3) == 3 && (b2) == 2 && (b1) == 1 && (b0) == 0 \ + ? (v7) << 7 | (v6) << 6 | (v5) << 5 | (v4) << 4 \ + | (v3) << 3 | (v2) << 2 | (v1) << 1 | (v0) << 0 \ + : -1024 * 1024) + +/** Delay in seconds. Do not call this function with a variable parameter. + * If you want a variable delay, prefer looping over a fixed delay. + * Maximum is about 4 seconds at 20MHz. */ +extern inline void +utils_delay (double s) __attribute__ ((always_inline)); + +extern inline void +utils_delay (double s) +{ + double cycles = (double) AC_FREQ * s; + if (cycles <= 1.0) + { + /* Delay shorter than 1 instruction. */ + asm volatile ("nop" : :); + } + else if (cycles <= 2.0) + { + /* Delay shorter than 2 instruction. */ + asm volatile ("nop\n\tnop" : :); + } + else if (cycles <= 3.0) + { + /* Delay shorter than 3 instruction. */ + asm volatile ("nop\n\tnop\n\tnop" : :); + } + else if (cycles <= 255 * 3) + { + uint8_t i = cycles / 3; + asm volatile ("1: dec %0\n\tbrne 1b" : "=r" (i) : "0" (i)); + } + else if (cycles <= 65535 * 4) + { + uint16_t i = cycles / 4; + asm volatile ("1: sbiw %0,1\n\tbrne 1b" : "=w" (i) : "0" (i)); + } + else + { + uint8_t j = (cycles + (65535 * 4 - 1)) / (65535 * 4); + uint16_t iv = cycles / (j * 4); + while (j--) + { + uint16_t i = iv; + asm volatile ("1: sbiw %0,1\n\tbrne 1b" : "=w" (i) : "0" (i)); + } + } +} + +extern inline void +utils_reset (void) __attribute__ ((noreturn)); + +/** Reset the avr using the watchdog. */ +extern inline void +utils_reset (void) +{ + wdt_enable (WDTO_15MS); + while (1) + ; +} + +#endif /* utils_avr_h */ diff --git a/digital/avr/modules/utils/utils.h b/digital/avr/modules/utils/utils.h new file mode 100644 index 00000000..e4e4c10b --- /dev/null +++ b/digital/avr/modules/utils/utils.h @@ -0,0 +1,82 @@ +#ifndef utils_h +#define utils_h +/* utils.h */ +/* avr.utils - Utilities AVR 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. + * + * }}} */ + +#ifndef HOST +# include "utils.avr.h" +#else +# include "utils.host.h" +#endif + +/** Shortcut for delay (ns * 1e-9). */ +extern inline void +utils_delay_ns (double ns) __attribute__ ((always_inline)); +extern inline void +utils_delay_ns (double ns) +{ + utils_delay (ns * 1e-9); +} + +/** Shortcut for delay (us * 1e-6). */ +extern inline void +utils_delay_us (double us) __attribute__ ((always_inline)); +extern inline void +utils_delay_us (double us) +{ + utils_delay (us * 1e-6); +} + +/** Shortcut for delay (ms * 1e-3). */ +extern inline void +utils_delay_ms (double ms) __attribute__ ((always_inline)); +extern inline void +utils_delay_ms (double ms) +{ + utils_delay (ms * 1e-3); +} + +/** Bound a value between MIN and MAX. */ +#define UTILS_BOUND(v, min, max) \ + do { \ + if ((v) < (min)) \ + (v) = (min); \ + else if ((v) > (max)) \ + (v) = (max); \ + } while (0) + +/** Return maximum of two values. */ +#define UTILS_MAX(a, b) ((a) > (b) ? (a) : (b)) + +/** Return minimum of two values. */ +#define UTILS_MIN(a, b) ((a) < (b) ? (a) : (b)) + +/** Absolute value. */ +#define UTILS_ABS(v) ((v) > 0 ? (v) : -(v)) + +/** Count the number of element in an array. */ +#define UTILS_COUNT(a) (sizeof (a) / sizeof ((a)[0])) + +#endif /* utils_h */ diff --git a/digital/avr/modules/utils/utils.host.c b/digital/avr/modules/utils/utils.host.c new file mode 100644 index 00000000..54dda954 --- /dev/null +++ b/digital/avr/modules/utils/utils.host.c @@ -0,0 +1,50 @@ +/* utils.host.c */ +/* avr.utils - Utilities AVR 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 "utils.h" +#include "modules/host/host.h" + +#include +#include + +/** Delay in seconds. */ +void +utils_delay (double s) +{ + struct timespec ts; + assert (s > 0.0); + ts.tv_sec = (long int) s; + ts.tv_nsec = (long int) (s - (long int) s) * 1000000000l; + while (nanosleep (&ts, &ts) == -1 && errno == EINTR) + ; +} + +/** Reset. */ +void +utils_reset (void) +{ + host_reset (); +} + diff --git a/digital/avr/modules/utils/utils.host.h b/digital/avr/modules/utils/utils.host.h new file mode 100644 index 00000000..2e73dc4b --- /dev/null +++ b/digital/avr/modules/utils/utils.host.h @@ -0,0 +1,36 @@ +#ifndef utils_host_h +#define utils_host_h +/* utils.host.h */ +/* avr.utils - Utilities AVR 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. + * + * }}} */ + +/** Delay in seconds. */ +void +utils_delay (double s); + +/** Reset. */ +void +utils_reset (void) __attribute__ ((noreturn)); + +#endif /* utils_host_h */ diff --git a/digital/avr/modules/utils/utils.txt b/digital/avr/modules/utils/utils.txt new file mode 100644 index 00000000..4aa9a571 --- /dev/null +++ b/digital/avr/modules/utils/utils.txt @@ -0,0 +1,6 @@ +*Title: Module AVR Utilitaires +*Author: Ni + +* Doc + +*File: utils.exd -- cgit v1.2.3