From b1f14380727106642388a6d32baa3a4103a03a9b Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 3 Oct 2011 21:03:58 +0200 Subject: digital/avr/modules/motor: add new output module --- digital/avr/modules/motor/output/test/Makefile | 23 +++ .../avr/modules/motor/output/test/avrconfig_both.h | 136 ++++++++++++++++++ .../avr/modules/motor/output/test/avrconfig_mp.h | 109 +++++++++++++++ .../avr/modules/motor/output/test/avrconfig_ocr.h | 117 ++++++++++++++++ .../avr/modules/motor/output/test/test_output.c | 154 +++++++++++++++++++++ 5 files changed, 539 insertions(+) create mode 100644 digital/avr/modules/motor/output/test/Makefile create mode 100644 digital/avr/modules/motor/output/test/avrconfig_both.h create mode 100644 digital/avr/modules/motor/output/test/avrconfig_mp.h create mode 100644 digital/avr/modules/motor/output/test/avrconfig_ocr.h create mode 100644 digital/avr/modules/motor/output/test/test_output.c (limited to 'digital/avr/modules/motor/output/test') diff --git a/digital/avr/modules/motor/output/test/Makefile b/digital/avr/modules/motor/output/test/Makefile new file mode 100644 index 00000000..33c13d9c --- /dev/null +++ b/digital/avr/modules/motor/output/test/Makefile @@ -0,0 +1,23 @@ +BASE = ../../../.. +PROGS = test_output +test_output_SOURCES = test_output.c +MODULES = utils uart proto motor/output $(OUTPUT_MODULE) +CONFIGFILE = avrconfig_ocr.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega32 +# -O2 : speed +# -Os : size +OPTIMIZE = -Os + +ifeq ($(CONFIGFILE),avrconfig_ocr.h) +OUTPUT_MODULE = motor/output/pwm_ocr +else ifeq ($(CONFIGFILE),avrconfig_mp.h) +OUTPUT_MODULE = motor/output/pwm_mp spi +else +OUTPUT_MODULE = motor/output/pwm_ocr motor/output/pwm_mp spi +endif + +TEST_MCU = atmega128 +TEST_CONFIGFILES = avrconfig_mp.h avrconfig_both.h + +include $(BASE)/make/Makefile.gen diff --git a/digital/avr/modules/motor/output/test/avrconfig_both.h b/digital/avr/modules/motor/output/test/avrconfig_both.h new file mode 100644 index 00000000..7ef23ac3 --- /dev/null +++ b/digital/avr/modules/motor/output/test/avrconfig_both.h @@ -0,0 +1,136 @@ +#ifndef avrconfig_both_h +#define avrconfig_both_h +/* avrconfig_both.h */ +/* motor - Motor control module. {{{ + * + * Copyright (C) 2011 Nicolas Schodet + * + * APBTeam: + * 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. + * + * }}} */ + +/* 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 38400 +/** 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 DROP +/** 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 + +/* motor/output - Output module. */ +/** Use Output Compare PWM output. */ +#define AC_OUTPUT_USE_PWM_OCR 1 +/** Use Motor Power PWM output. */ +#define AC_OUTPUT_USE_PWM_MP 1 +/** Define module and module index for each output. */ +#define AC_OUTPUT_LIST \ + (pwm_ocr, 0), (pwm_ocr, 1), (pwm_ocr, 2), (pwm_ocr, 3), \ + (pwm_mp, 0), (pwm_mp, 1), (pwm_mp, 2), (pwm_mp, 3) + +/* motor/output/pwm_ocr - Output Compare PWM output module. */ +/** For each output, define output parameters: + * + * (timer, ocr, pwm_io, dir_io[, brake_io]) + * + * With: + * - timer: timer number (ex: 1 for TIMER1) + * - ocr: output compare (ex: A for output compare A) + * - mode: compare output mode (ex: 2, see datasheet) + * - pwm_io: corresponding io port (ex: B, 1) + * - dir_io: io port used for direction (ex: B, 2) + * - brake_io: optional io port used for brake (ex: B, 3) + */ +#define AC_OUTPUT_PWM_OCR_LIST \ + (1, B, 2, B,6, B,4), \ + (1, C, 2, B,7, B,5), \ + (3, B, 2, E,4, E,2), \ + (3, C, 2, E,5, E,3) +/** Clock select for each used timer. */ +#define AC_OUTPUT_PWM_OCR_CS_1 0b0001 +/** Waveform Generation Mode for each used timer. */ +#define AC_OUTPUT_PWM_OCR_WGM_1 0b0111 +/** Offset added to PWM value to compensate for H-bridge weakness. */ +#define AC_OUTPUT_PWM_OCR_OFFSET 0 + +/* motor/output/pwm_mp - Motor Power board PWM output module. */ +/** Number of outputs, there is two outputs per board. */ +#define AC_OUTPUT_PWM_MP_NB 4 +/** Slave select for first Motor Power board. + * WARNING: this must match hardware SS pin if using hardware SPI! */ +#define AC_OUTPUT_PWM_MP_SPI_SS_IO_0 B, 0 +/** Slave select for next Motor Power boards. */ +#define AC_OUTPUT_PWM_MP_SPI_SS_IO_1 E, 4 + +/* spi - SPI module. */ +/** Select driver: HARD, SOFT, or NONE. */ +#define AC_SPI0_DRIVER HARD +/** Same thing for an optionnal second SPI driver. */ +#define AC_SPI1_DRIVER NONE + +#endif /* avrconfig_both_h */ diff --git a/digital/avr/modules/motor/output/test/avrconfig_mp.h b/digital/avr/modules/motor/output/test/avrconfig_mp.h new file mode 100644 index 00000000..1cafe775 --- /dev/null +++ b/digital/avr/modules/motor/output/test/avrconfig_mp.h @@ -0,0 +1,109 @@ +#ifndef avrconfig_mp_h +#define avrconfig_mp_h +/* avrconfig_mp.h */ +/* motor - Motor control module. {{{ + * + * Copyright (C) 2011 Nicolas Schodet + * + * APBTeam: + * 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. + * + * }}} */ + +/* 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 38400 +/** 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 DROP +/** 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 + +/* motor/output - Output module. */ +/** Use Output Compare PWM output. */ +#define AC_OUTPUT_USE_PWM_OCR 0 +/** Use Motor Power PWM output. */ +#define AC_OUTPUT_USE_PWM_MP 1 +/** Define module and module index for each output. */ +#define AC_OUTPUT_LIST (pwm_mp, 0), (pwm_mp, 1), (pwm_mp, 3), (pwm_mp, 2) + +/* motor/output/pwm_mp - Motor Power board PWM output module. */ +/** Number of outputs, there is two outputs per board. */ +#define AC_OUTPUT_PWM_MP_NB 4 +/** Slave select for first Motor Power board. + * WARNING: this must match hardware SS pin if using hardware SPI! */ +#define AC_OUTPUT_PWM_MP_SPI_SS_IO_0 B, 0 +/** Slave select for next Motor Power boards. */ +#define AC_OUTPUT_PWM_MP_SPI_SS_IO_1 E, 4 + +/* spi - SPI module. */ +/** Select driver: HARD, SOFT, or NONE. */ +#define AC_SPI0_DRIVER HARD +/** Same thing for an optionnal second SPI driver. */ +#define AC_SPI1_DRIVER NONE + +#endif /* avrconfig_mp_h */ diff --git a/digital/avr/modules/motor/output/test/avrconfig_ocr.h b/digital/avr/modules/motor/output/test/avrconfig_ocr.h new file mode 100644 index 00000000..0eb3463a --- /dev/null +++ b/digital/avr/modules/motor/output/test/avrconfig_ocr.h @@ -0,0 +1,117 @@ +#ifndef avrconfig_ocr_h +#define avrconfig_ocr_h +/* avrconfig_ocr.h */ +/* motor - Motor control module. {{{ + * + * Copyright (C) 2011 Nicolas Schodet + * + * APBTeam: + * 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. + * + * }}} */ + +/* 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 38400 +/** 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 DROP +/** 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 + +/* motor/output - Output module. */ +/** Use Output Compare PWM output. */ +#define AC_OUTPUT_USE_PWM_OCR 1 +/** Use Motor Power PWM output. */ +#define AC_OUTPUT_USE_PWM_MP 0 +/** Define module and module index for each output. */ +#define AC_OUTPUT_LIST (pwm_ocr, 0), (pwm_ocr, 1) + +/* motor/output/pwm_ocr - Output Compare PWM output module. */ +/** For each output, define output parameters: + * + * (timer, ocr, pwm_io, dir_io[, brake_io]) + * + * With: + * - timer: timer number (ex: 1 for TIMER1) + * - ocr: output compare (ex: A for output compare A) + * - mode: compare output mode (ex: 2, see datasheet) + * - pwm_io: corresponding io port (ex: B, 1) + * - dir_io: io port used for direction (ex: B, 2) + * - brake_io: optional io port used for brake (ex: B, 3) + */ +#define AC_OUTPUT_PWM_OCR_LIST \ + (1, A, 2, D,5, D,3, A,4), \ + (1, B, 2, D,4, D,2, A,5) +/** Clock select for each used timer. */ +#define AC_OUTPUT_PWM_OCR_CS_1 0b0001 +/** Waveform Generation Mode for each used timer. */ +#define AC_OUTPUT_PWM_OCR_WGM_1 0b0011 +/** Offset added to PWM value to compensate for H-bridge weakness. */ +#define AC_OUTPUT_PWM_OCR_OFFSET 0x40 + +#endif /* avrconfig_ocr_h */ diff --git a/digital/avr/modules/motor/output/test/test_output.c b/digital/avr/modules/motor/output/test/test_output.c new file mode 100644 index 00000000..f38c7383 --- /dev/null +++ b/digital/avr/modules/motor/output/test/test_output.c @@ -0,0 +1,154 @@ +/* test_output.c */ +/* motor - Motor control module. {{{ + * + * Copyright (C) 2011 Nicolas Schodet + * + * APBTeam: + * 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 "common.h" + +#include "modules/utils/utils.h" +#include "modules/uart/uart.h" +#include "modules/proto/proto.h" + +#include "modules/motor/output/output.h" + +#include "io.h" + +output_t output[OUTPUT_NB]; + +int16_t target[OUTPUT_NB]; +int16_t current[OUTPUT_NB]; + +uint16_t output_speed_cpt = 1, output_speed = 250; +uint16_t output_stat_cpt, output_stat; + +int +main (void) +{ + uint8_t i; + for (i = 0; i < OUTPUT_NB; i++) + { + output[i].min = 0x10; + output[i].max = OUTPUT_MAX; + output_init (i, &output[i]); + } + uart0_init (); + proto_send0 ('z'); + sei (); + while (1) + { + utils_delay_ms (4); + if (output_speed && !--output_speed_cpt) + { + for (i = 0; i < OUTPUT_NB; i++) + { + if (target[i] < current[i]) + current[i]--; + else if (target[i] > output[i].cur) + current[i]++; + output_set (&output[i], current[i]); + } + output_speed_cpt = output_speed; + } + if (output_stat && !--output_stat_cpt) + { + proto_send2w ('W', output[0].cur, output[1].cur); + output_stat_cpt = output_stat; + } + while (uart0_poll ()) + proto_accept (uart0_getc ()); + } +} + +/** Handle incoming messages. */ +void +proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ + uint8_t i; + uint8_t ok = 1; + uint8_t index = args[0]; + int16_t value = v8_to_v16 (args[1], args[2]); +#define c(cmd, size) (cmd << 8 | size) + switch (c (cmd, size)) + { + case c ('z', 0): + /* Reset. */ + utils_reset (); + break; + case c ('w', 0): + /* Set zero value. */ + for (i = 0; i < OUTPUT_NB; i++) + { + output_set (&output[index], 0); + current[index] = target[index] = 0; + } + case c ('w', 3): + /* Set direct value. + * - b: output index. + * - w: output value. */ + if (index < OUTPUT_NB) + { + output_set (&output[index], value); + target[index] = current[index]; + } + else + ok = 0; + break; + case c ('t', 3): + /* Set target. + * - b: output index. + * - w: output target. */ + if (index < OUTPUT_NB) + { + current[index] = output[index].cur; + target[index] = value; + } + else + ok = 0; + break; + case c ('s', 2): + /* Set targeting speed. + * - w: loops between update. */ + output_speed_cpt = output_speed = v8_to_v16 (args[0], args[1]); + break; + case c ('r', 2): + /* Set reverse flag. + * - b: output index. + * - b: reverse flag. */ + if (index < OUTPUT_NB) + output_set_reverse (&output[index], args[1]); + else + ok = 0; + break; + case c ('W', 2): + /* Output stats. */ + output_stat_cpt = output_stat = v8_to_v16 (args[0], args[1]); + break; + default: + ok = 0; + break; + } + if (ok) + proto_send (cmd, size, args); + else + proto_send0 ('?'); +#undef c +} -- cgit v1.2.3