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 --- .../modules/motor/output/pwm_mp/Makefile.module | 1 + .../avr/modules/motor/output/pwm_mp/avrconfig.h | 37 +++++ .../motor/output/pwm_mp/output_pwm_mp.avr.c | 165 +++++++++++++++++++++ .../modules/motor/output/pwm_mp/output_pwm_mp.h | 37 +++++ 4 files changed, 240 insertions(+) create mode 100644 digital/avr/modules/motor/output/pwm_mp/Makefile.module create mode 100644 digital/avr/modules/motor/output/pwm_mp/avrconfig.h create mode 100644 digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.avr.c create mode 100644 digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.h (limited to 'digital/avr/modules/motor/output/pwm_mp') diff --git a/digital/avr/modules/motor/output/pwm_mp/Makefile.module b/digital/avr/modules/motor/output/pwm_mp/Makefile.module new file mode 100644 index 00000000..e08ad057 --- /dev/null +++ b/digital/avr/modules/motor/output/pwm_mp/Makefile.module @@ -0,0 +1 @@ +motor_output_pwm_mp_SOURCES = output_pwm_mp.avr.c diff --git a/digital/avr/modules/motor/output/pwm_mp/avrconfig.h b/digital/avr/modules/motor/output/pwm_mp/avrconfig.h new file mode 100644 index 00000000..e4d2ffb2 --- /dev/null +++ b/digital/avr/modules/motor/output/pwm_mp/avrconfig.h @@ -0,0 +1,37 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h - motor/output/pwm_mp configuration template. */ +/* 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. + * + * }}} */ + +/* 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 + +#endif /* avrconfig_h */ diff --git a/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.avr.c b/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.avr.c new file mode 100644 index 00000000..4e644da9 --- /dev/null +++ b/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.avr.c @@ -0,0 +1,165 @@ +/* output_pwm_mp.avr.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 "output_pwm_mp.h" + +#include "modules/spi/spi.h" +#include "io.h" + +/** Define the maximum PWM value for motor power. + * This value is lowered until the bug relatives to maximum value is fixed + * (rounding after shifting bug). */ +#define OUTPUT_PWM_MP_MAX 0x3f0 + +/* Test given configuration. */ +#if AC_OUTPUT_PWM_MP_NB != 2 && AC_OUTPUT_PWM_MP_NB != 4 +# error "motor/output/pwm_mp: unsupported configuration" +#endif + +/* Define test macro. */ +#define IF_MP(mp) (AC_OUTPUT_PWM_MP_NB >= ((mp) + 1) * 2) + +/** Output information. */ +struct output_pwm_mp_t +{ + /** Associated output state. */ + struct output_t *output; +}; +typedef struct output_pwm_mp_t output_pwm_mp_t; + +/** Global output information. */ +output_pwm_mp_t output_pwm_mp[AC_OUTPUT_PWM_MP_NB]; + +/** Global enable flag. */ +uint8_t output_pwm_mp_go; + +static void +output_pwm_mp_update_single (int16_t value1, int16_t value2); + +/** Initialize hardware, to be done once. */ +static void +output_pwm_mp_init_hardware (void) +{ + static uint8_t inited; + if (!inited) + { +#if IF_MP (0) && SPI0_DRIVER != SPI_DRIVER_HARD + /* This is done in spi_init for hardware driver. */ + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); + IO_OUTPUT (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); +#endif +#if IF_MP (1) + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); + IO_OUTPUT (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); +#endif + /* Initialise SPI. */ + spi_init (SPI_MASTER, SPI_CPOL_FALLING | SPI_CPHA_SETUP, + SPI_MSB_FIRST, SPI_FOSC_DIV16); + /* Reset PWM values at reset. */ +#if IF_MP (0) + IO_CLR (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); + output_pwm_mp_update_single (0, 0); + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); +#endif +#if IF_MP (1) + IO_CLR (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); + output_pwm_mp_update_single (0, 0); + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); +#endif + /* Done. */ + inited = 1; + } +} + +void +output_pwm_mp_init (uint8_t index, output_t *output) +{ + /* Need initialized hardware. */ + output_pwm_mp_init_hardware (); + /* Keep output structure for future usage. */ + output_pwm_mp[index].output = output; + /* Reduce maximum output if needed. */ + if (output->max > OUTPUT_PWM_MP_MAX) + output->max = OUTPUT_PWM_MP_MAX; +} + +/** Transmit value to currently selected slave. */ +static void +output_pwm_mp_update_single (int16_t value1, int16_t value2) +{ + uint8_t v; + uint8_t cks; + /* Convert to 12 bits. */ + int16_t pwm1c = value1 << 1; + int16_t pwm2c = value2 << 1; + /* Send, computing checksum on the way. */ + cks = 0x42; + v = ((pwm1c >> 4) & 0xf0) | ((pwm2c >> 8) & 0x0f); + spi_send (v); + cks ^= v; + v = pwm1c; + spi_send (v); + cks ^= v; + v = pwm2c; + spi_send (v); + cks ^= v; + spi_send (cks); +} + +void +output_pwm_mp_update (void) +{ + uint8_t i; + /* Activate output at first non zero value. */ + if (!output_pwm_mp_go) + { + for (i = 0; i < AC_OUTPUT_PWM_MP_NB; i++) + if (output_pwm_mp[i].output->cur) + output_pwm_mp_go = 1; + } + /* Update each output. */ + if (output_pwm_mp_go) + { +#if IF_MP (0) + /* Slave select. */ + IO_CLR (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); + /* Transmit values. */ + output_pwm_mp_update_single (output_pwm_mp[0].output->cur, + output_pwm_mp[1].output->cur); + /* Slave deselect. */ + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_0); +#endif +#if IF_MP (1) + /* Slave select. */ + IO_CLR (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); + /* Transmit values. */ + output_pwm_mp_update_single (output_pwm_mp[2].output->cur, + output_pwm_mp[3].output->cur); + /* Slave deselect. */ + IO_SET (AC_OUTPUT_PWM_MP_SPI_SS_IO_1); +#endif + } +} + diff --git a/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.h b/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.h new file mode 100644 index 00000000..9aa0f6ad --- /dev/null +++ b/digital/avr/modules/motor/output/pwm_mp/output_pwm_mp.h @@ -0,0 +1,37 @@ +#ifndef output_pwm_mp_h +#define output_pwm_mp_h +/* output_pwm_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. + * + * }}} */ +#include "modules/motor/output/output.h" + +/** See output_init. */ +void +output_pwm_mp_init (uint8_t index, output_t *output); + +/** See output_update. */ +void +output_pwm_mp_update (void); + +#endif /* output_pwm_mp_h */ -- cgit v1.2.3