From 00d6ca44c5d8ac9a43223e6843fbc8e54a61b923 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 7 Oct 2007 22:33:46 +0200 Subject: Added counter decoder AVR implementation. --- digital/asserv/src/avrcounter/Makefile | 14 +++ digital/asserv/src/avrcounter/README | 31 ++++++ .../asserv/src/avrcounter/avrcounter-port-comb.c | 99 ++++++++++++++++++ .../asserv/src/avrcounter/avrcounter-port-one.c | 60 +++++++++++ .../asserv/src/avrcounter/avrcounter-port-two.c | 62 +++++++++++ .../asserv/src/avrcounter/avrcounter-spi-comb.c | 115 +++++++++++++++++++++ 6 files changed, 381 insertions(+) create mode 100644 digital/asserv/src/avrcounter/Makefile create mode 100644 digital/asserv/src/avrcounter/README create mode 100644 digital/asserv/src/avrcounter/avrcounter-port-comb.c create mode 100644 digital/asserv/src/avrcounter/avrcounter-port-one.c create mode 100644 digital/asserv/src/avrcounter/avrcounter-port-two.c create mode 100644 digital/asserv/src/avrcounter/avrcounter-spi-comb.c (limited to 'digital') diff --git a/digital/asserv/src/avrcounter/Makefile b/digital/asserv/src/avrcounter/Makefile new file mode 100644 index 00000000..d9de0177 --- /dev/null +++ b/digital/asserv/src/avrcounter/Makefile @@ -0,0 +1,14 @@ +BASE = ../../../avr +AVR_PROGS = avrcounter-port-comb avrcounter-port-one avrcounter-port-two \ + avrcounter-spi-comb +avrcounter-port-comb_SOURCES = avrcounter-port-comb.c +avrcounter-port-one_SOURCES = avrcounter-port-one.c +avrcounter-port-two_SOURCES = avrcounter-port-two.c +avrcounter-spi-comb_SOURCES = avrcounter-spi-comb.c +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 -mint8 + +include $(BASE)/make/Makefile.gen diff --git a/digital/asserv/src/avrcounter/README b/digital/asserv/src/avrcounter/README new file mode 100644 index 00000000..4c4350f2 --- /dev/null +++ b/digital/asserv/src/avrcounter/README @@ -0,0 +1,31 @@ +avrcounter - Incremental encoder counter on AVR microcontroller. + +Microcontrolers often have counter inputs, but they do not have any dedicated +inputs for incremental encoders which are therefore tendious to decode without +any external logic. + +The avrcounter implements this decoder in an AVR which must be dedicated to +this task. The number of encoders which can be decoded this way depends on the +encoders maximum frequency. More encoders means more instruction to decode, +and lower maximum frequency. + + +Copyright (C) 2007 Nicolas Schodet + +Robot APB Team 2008. + Web: http://apbteam.org/ + Email: team AT apbteam DOT org + +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/asserv/src/avrcounter/avrcounter-port-comb.c b/digital/asserv/src/avrcounter/avrcounter-port-comb.c new file mode 100644 index 00000000..1dd74555 --- /dev/null +++ b/digital/asserv/src/avrcounter/avrcounter-port-comb.c @@ -0,0 +1,99 @@ +/* avrcounter-port-comb.c - Combined table, port output. */ +/* avrcounter - Incremental encoder counter. {{{ + * + * Copyright (C) 2007 Nicolas Schodet + * + * Robot APB Team 2008. + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * 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 + +int +main (void) +{ + uint8_t count0 = 0, count1 = 0; + uint8_t state = 0; + /* Encoder signals: + * ____----____----____---- + * __----____----____----__ */ +#define trans_0 0 /* 00 -> 00 */ +#define trans_1 +1 /* 00 -> 01 */ +#define trans_2 -1 /* 00 -> 10 */ +#define trans_3 0 /* 00 -> 11, missed! */ +#define trans_4 -1 /* 01 -> 00 */ +#define trans_5 0 /* 01 -> 01 */ +#define trans_6 0 /* 01 -> 10, missed! */ +#define trans_7 +1 /* 01 -> 11 */ +#define trans_8 +1 /* 10 -> 00 */ +#define trans_9 0 /* 10 -> 01, missed! */ +#define trans_10 0 /* 10 -> 10 */ +#define trans_11 -1 /* 10 -> 11 */ +#define trans_12 0 /* 11 -> 00, missed! */ +#define trans_13 -1 /* 11 -> 01 */ +#define trans_14 +1 /* 11 -> 10 */ +#define trans_15 0 /* 11 -> 11 */ +#define trans_x_y(x, y) { trans_ ## x, trans_ ## y }, +#define trans_x_all(x) \ + trans_x_y (x, 0) \ + trans_x_y (x, 1) \ + trans_x_y (x, 2) \ + trans_x_y (x, 3) \ + trans_x_y (x, 4) \ + trans_x_y (x, 5) \ + trans_x_y (x, 6) \ + trans_x_y (x, 7) \ + trans_x_y (x, 8) \ + trans_x_y (x, 9) \ + trans_x_y (x, 10) \ + trans_x_y (x, 11) \ + trans_x_y (x, 12) \ + trans_x_y (x, 13) \ + trans_x_y (x, 14) \ + trans_x_y (x, 15) + static const struct + { + int8_t inc0; + int8_t inc1; + } inc[] = { + trans_x_all (0) + trans_x_all (1) + trans_x_all (2) + trans_x_all (3) + trans_x_all (4) + trans_x_all (5) + trans_x_all (6) + trans_x_all (7) + trans_x_all (8) + trans_x_all (9) + trans_x_all (10) + trans_x_all (11) + trans_x_all (12) + trans_x_all (13) + trans_x_all (14) + trans_x_all (15) + }; + DDRD = 0xff; + while (1) + { + state = (state << 4) | (PINC & 0x0f); + count0 += inc[state].inc0; + count1 += inc[state].inc1; + PORTD = (PINB & 1) ? count1 : count0; + } +} diff --git a/digital/asserv/src/avrcounter/avrcounter-port-one.c b/digital/asserv/src/avrcounter/avrcounter-port-one.c new file mode 100644 index 00000000..9341cb0c --- /dev/null +++ b/digital/asserv/src/avrcounter/avrcounter-port-one.c @@ -0,0 +1,60 @@ +/* avrcounter-port-one.c - Single encoder, port output. */ +/* avrcounter - Incremental encoder counter. {{{ + * + * Copyright (C) 2007 Nicolas Schodet + * + * Robot APB Team 2008. + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * 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 + +int +main (void) +{ + uint8_t count = 0; + uint8_t state = 0; + /* Encoder signals: + * ____----____----____---- + * __----____----____----__ */ + static const int8_t inc[] = { + 0, /* 00 -> 00 */ + +1, /* 00 -> 01 */ + -1, /* 00 -> 10 */ + 0, /* 00 -> 11, missed! */ + -1, /* 01 -> 00 */ + 0, /* 01 -> 01 */ + 0, /* 01 -> 10, missed! */ + +1, /* 01 -> 11 */ + +1, /* 10 -> 00 */ + 0, /* 10 -> 01, missed! */ + 0, /* 10 -> 10 */ + -1, /* 10 -> 11 */ + 0, /* 11 -> 00, missed! */ + -1, /* 11 -> 01 */ + +1, /* 11 -> 10 */ + 0, /* 11 -> 11 */ + }; + DDRD = 0xff; + while (1) + { + state = (state << 2) | (PINC & 0x03); + count += inc[state]; + PORTD = count; + } +} diff --git a/digital/asserv/src/avrcounter/avrcounter-port-two.c b/digital/asserv/src/avrcounter/avrcounter-port-two.c new file mode 100644 index 00000000..f934949b --- /dev/null +++ b/digital/asserv/src/avrcounter/avrcounter-port-two.c @@ -0,0 +1,62 @@ +/* avrcounter-port-two.c - Double encoder, port output. */ +/* avrcounter - Incremental encoder counter. {{{ + * + * Copyright (C) 2007 Nicolas Schodet + * + * Robot APB Team 2008. + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * 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 + +int +main (void) +{ + uint8_t count0 = 0, count1 = 0; + uint8_t state0 = 0, state1 = 0; + /* Encoder signals: + * ____----____----____---- + * __----____----____----__ */ + static const int8_t inc[] = { + 0, /* 00 -> 00 */ + +1, /* 00 -> 01 */ + -1, /* 00 -> 10 */ + 0, /* 00 -> 11, missed! */ + -1, /* 01 -> 00 */ + 0, /* 01 -> 01 */ + 0, /* 01 -> 10, missed! */ + +1, /* 01 -> 11 */ + +1, /* 10 -> 00 */ + 0, /* 10 -> 01, missed! */ + 0, /* 10 -> 10 */ + -1, /* 10 -> 11 */ + 0, /* 11 -> 00, missed! */ + -1, /* 11 -> 01 */ + +1, /* 11 -> 10 */ + 0, /* 11 -> 11 */ + }; + DDRD = 0xff; + while (1) + { + state0 = (state0 << 2) | (PINC & 0x03); + count0 += inc[state0]; + state1 = (state1 << 2) | ((PINC >> 2) & 0x03); + count1 += inc[state1]; + PORTD = (PINB & 1) ? count1 : count0; + } +} diff --git a/digital/asserv/src/avrcounter/avrcounter-spi-comb.c b/digital/asserv/src/avrcounter/avrcounter-spi-comb.c new file mode 100644 index 00000000..da3c8a9d --- /dev/null +++ b/digital/asserv/src/avrcounter/avrcounter-spi-comb.c @@ -0,0 +1,115 @@ +/* avrcounter-spi-comb.c - Combined table, SPI output. */ +/* avrcounter - Incremental encoder counter. {{{ + * + * Copyright (C) 2007 Nicolas Schodet + * + * Robot APB Team 2008. + * Web: http://apbteam.org/ + * Email: team AT apbteam DOT org + * + * 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 + +register volatile uint8_t count0 __asm__ ("r2"), count1 __asm__ ("r3"); +register volatile uint8_t int_tmp0 __asm__ ("r4"), int_tmp1 __asm__ ("r5"); + +void +SIG_SPI (void) __attribute__ ((naked)); +void +SIG_SPI (void) +{ + int_tmp0 = SPDR; + int_tmp1 = count0; + if (SPDR & 1) + int_tmp1 = count1; + SPDR = int_tmp1; + __asm__ __volatile__ ("reti"::); +} + +int +main (void) +{ + uint8_t state = 0; + count0 = 0; + count1 = 0; + /* Encoder signals: + * ____----____----____---- + * __----____----____----__ */ +#define trans_0 0 /* 00 -> 00 */ +#define trans_1 +1 /* 00 -> 01 */ +#define trans_2 -1 /* 00 -> 10 */ +#define trans_3 0 /* 00 -> 11, missed! */ +#define trans_4 -1 /* 01 -> 00 */ +#define trans_5 0 /* 01 -> 01 */ +#define trans_6 0 /* 01 -> 10, missed! */ +#define trans_7 +1 /* 01 -> 11 */ +#define trans_8 +1 /* 10 -> 00 */ +#define trans_9 0 /* 10 -> 01, missed! */ +#define trans_10 0 /* 10 -> 10 */ +#define trans_11 -1 /* 10 -> 11 */ +#define trans_12 0 /* 11 -> 00, missed! */ +#define trans_13 -1 /* 11 -> 01 */ +#define trans_14 +1 /* 11 -> 10 */ +#define trans_15 0 /* 11 -> 11 */ +#define trans_x_y(x, y) { trans_ ## x, trans_ ## y }, +#define trans_x_all(x) \ + trans_x_y (x, 0) \ + trans_x_y (x, 1) \ + trans_x_y (x, 2) \ + trans_x_y (x, 3) \ + trans_x_y (x, 4) \ + trans_x_y (x, 5) \ + trans_x_y (x, 6) \ + trans_x_y (x, 7) \ + trans_x_y (x, 8) \ + trans_x_y (x, 9) \ + trans_x_y (x, 10) \ + trans_x_y (x, 11) \ + trans_x_y (x, 12) \ + trans_x_y (x, 13) \ + trans_x_y (x, 14) \ + trans_x_y (x, 15) + static const struct + { + int8_t inc0; + int8_t inc1; + } inc[] = { + trans_x_all (0) + trans_x_all (1) + trans_x_all (2) + trans_x_all (3) + trans_x_all (4) + trans_x_all (5) + trans_x_all (6) + trans_x_all (7) + trans_x_all (8) + trans_x_all (9) + trans_x_all (10) + trans_x_all (11) + trans_x_all (12) + trans_x_all (13) + trans_x_all (14) + trans_x_all (15) + }; + DDRD = 0xff; + while (1) + { + state = (state << 4) | (PINC & 0x0f); + count0 += inc[state].inc0; + count1 += inc[state].inc1; + } +} -- cgit v1.2.3