From 737e4f3e487c8849aab3900625ee64edb02ec263 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 14 Apr 2008 00:53:22 +0200 Subject: * digital/asserv/src/asserv: - added motor-power-avr support. --- digital/asserv/src/asserv/pwm.avr.c | 220 ++---------------------------------- 1 file changed, 12 insertions(+), 208 deletions(-) (limited to 'digital/asserv/src/asserv/pwm.avr.c') diff --git a/digital/asserv/src/asserv/pwm.avr.c b/digital/asserv/src/asserv/pwm.avr.c index f2caa220..8d12cc8a 100644 --- a/digital/asserv/src/asserv/pwm.avr.c +++ b/digital/asserv/src/asserv/pwm.avr.c @@ -1,4 +1,4 @@ -/* pwm.avr.c */ +/* pwm.avr.c - Handle all PWM generators. */ /* asserv - Position & speed motor control on AVR. {{{ * * Copyright (C) 2005 Nicolas Schodet @@ -24,96 +24,21 @@ * }}} */ #include "common.h" #include "pwm.h" - -#include "modules/utils/utils.h" -#include "io.h" - -/** Assign PWM outputs. */ -#define PWM1 pwm_left -#define PWM2 pwm_right -#define PWM3 pwm_aux0 -#undef PWM4 - -#define PWM_REVERSE_BIT(x) PWM_REVERSE_BIT_ (x) -#define PWM_REVERSE_BIT_(x) PWM_REVERSE_BIT_ ## x -#define PWM_REVERSE_BIT_pwm_left _BV (0) -#define PWM_REVERSE_BIT_pwm_right _BV (1) -#define PWM_REVERSE_BIT_pwm_aux0 _BV (2) - -#define PWM1_OCR OCR1B -#define PWM1_OCR_BIT 6 -#define PWM1_DIR 4 -#define PWM2_OCR OCR1C -#define PWM2_OCR_BIT 7 -#define PWM2_DIR 5 -#define PWM3_OCR OCR3B -#define PWM3_OCR_BIT 4 -#define PWM3_DIR 2 -#define PWM4_OCR OCR3C -#define PWM4_OCR_BIT 5 -#define PWM4_DIR 3 - -/* Simplify conditionnal compilation. */ -#define PWM1or2 (defined (PWM1) || defined (PWM2)) -#define PWM3or4 (defined (PWM3) || defined (PWM4)) -#ifdef PWM1 -# define PWM1c(x) x -#else -# define PWM1c(x) 0 -#endif -#ifdef PWM2 -# define PWM2c(x) x -#else -# define PWM2c(x) 0 -#endif -#ifdef PWM3 -# define PWM3c(x) x -#else -# define PWM3c(x) 0 -#endif -#ifdef PWM4 -# define PWM4c(x) x -#else -# define PWM4c(x) 0 -#endif +#include "pwm_mp.avr.h" +#include "pwm_ocr.avr.h" /** PWM values, this is an error if absolute value is greater than the * maximum. */ int16_t pwm_left, pwm_right, pwm_aux0; /** PWM reverse directions. */ uint8_t pwm_reverse; -/** PWM reverse direction, port B. */ -static uint8_t pwm_dir_reverse_b; -/** PWM reverse direction, port E. */ -static uint8_t pwm_dir_reverse_e; -/** Initialise PWM generator. */ +/** Initialise PWM generators. */ void pwm_init (void) { - /* Fast PWM, TOP = 0x3ff, OCnB & OCnC with positive logic. - f_IO without prescaler. - Fpwm = f_IO / (prescaler * (1 + TOP)) = 14400 Hz. */ -#if PWM1or2 - TCCR1A = - regv (COM1A1, COM1A0, COM1B1, COM1B0, COM1C1, COM1C0, WGM11, WGM10, - 0, 0, 1, 0, 1, 0, 1, 1); - TCCR1B = regv (ICNC1, ICES1, 5, WGM13, WGM12, CS12, CS11, CS10, - 0, 0, 0, 0, 1, 0, 0, 1); - /* Enable pwm and direction outputs in DDRB. */ - DDRB |= PWM1c (_BV (PWM1_OCR_BIT) | _BV (PWM1_DIR)) - | PWM2c (_BV (PWM2_OCR_BIT) | _BV (PWM2_DIR)); -#endif -#if PWM3or4 - TCCR3A = - regv (COM3A1, COM3A0, COM3B1, COM3B0, COM3C1, COM3C0, WGM31, WGM30, - 0, 0, 1, 0, 1, 0, 1, 1); - TCCR3B = regv (ICNC3, ICES3, 5, WGM33, WGM32, CS32, CS31, CS30, - 0, 0, 0, 0, 1, 0, 0, 1); - /* Enable pwm and direction outputs in DDRE. */ - DDRE |= PWM3c (_BV (PWM3_OCR_BIT) | _BV (PWM3_DIR)) - | PWM4c (_BV (PWM4_OCR_BIT) | _BV (PWM4_DIR)); -#endif + pwm_mp_init (); + pwm_ocr_init (); } /** Update the hardware PWM values. */ @@ -121,138 +46,17 @@ void pwm_update (void) { /* Some assumption checks. */ - assert (!PWM1c (PWM1 < -PWM_MAX || PWM1 > PWM_MAX)); - assert (!PWM2c (PWM2 < -PWM_MAX || PWM2 > PWM_MAX)); - assert (!PWM3c (PWM3 < -PWM_MAX || PWM3 > PWM_MAX)); - assert (!PWM4c (PWM4 < -PWM_MAX || PWM4 > PWM_MAX)); -#if PWM1or2 - uint8_t dir_b; - /* Sample port B. */ - dir_b = PORTB & ~(PWM1c (_BV (PWM1_DIR)) | PWM2c (_BV (PWM2_DIR))); -# ifdef PWM1 - uint16_t pwm1; - /* Set PWM1. */ - if (PWM1 == 0) - { - pwm1 = 0; - } - else if (PWM1 < 0) - { - pwm1 = -PWM1; - } - else - { - dir_b |= _BV (PWM1_DIR); - pwm1 = PWM1; - } -# endif /* PWM1 */ -# ifdef PWM2 - uint16_t pwm2; - /* Set PWM2. */ - if (PWM2 == 0) - { - pwm2 = 0; - } - else if (PWM2 < 0) - { - pwm2 = -PWM2; - } - else - { - dir_b |= _BV (PWM2_DIR); - pwm2 = PWM2; - } -# endif /* PWM2 */ -#endif /* PWM1or2 */ -#if PWM3or4 - uint8_t dir_e; - /* Sample port E. */ - dir_e = PORTE & ~(PWM3c (_BV (PWM3_DIR)) | PWM4c (_BV (PWM4_DIR))); -# ifdef PWM3 - uint16_t pwm3; - /* Set PWM3. */ - if (PWM3 == 0) - { - pwm3 = 0; - } - else if (PWM3 < 0) - { - pwm3 = -PWM3; - } - else - { - dir_e |= _BV (PWM3_DIR); - pwm3 = PWM3; - } -# endif /* PWM3 */ -# ifdef PWM4 - uint16_t pwm4; - /* Set PWM4. */ - if (PWM4 == 0) - { - pwm4 = 0; - } - else if (PWM4 < 0) - { - pwm4 = -PWM4; - } - else - { - dir_e |= _BV (PWM4_DIR); - pwm4 = PWM4; - } -# endif /* PWM4 */ -#endif /* PWM3or4 */ - /* Setup registers. */ - /* Here, there could be a problem because OCRx are double buffered, not - * PORTx! */ - /* Another problem arise if the OCR sampling is done between left and - * right OCR: the right PWM is one cycle late. */ - /* A solution could be to use interrupts to update PWM or to synchronise - * general timer with PWM. */ -#if PWM1or2 - dir_b ^= pwm_dir_reverse_b; - PORTB = dir_b; -# ifdef PWM1 - PWM1_OCR = pwm1; -# endif -# ifdef PWM2 - PWM2_OCR = pwm2; -# endif -#endif /* PWM1or2 */ -#if PWM3or4 - dir_e ^= pwm_dir_reverse_e; - PORTE = dir_e; -# ifdef PWM3 - PWM3_OCR = pwm3; -# endif -# ifdef PWM4 - PWM4_OCR = pwm4; -# endif -#endif /* PWM3or4 */ + assert (pwm_left > -PWM_MAX && pwm_left < PWM_MAX); + assert (pwm_right > -PWM_MAX && pwm_right < PWM_MAX); + assert (pwm_aux0 > -PWM_MAX && pwm_aux0 < PWM_MAX); + pwm_mp_update (); + pwm_ocr_update (); } void pwm_set_reverse (uint8_t reverse) { pwm_reverse = reverse; - pwm_dir_reverse_b = 0; - pwm_dir_reverse_e = 0; -#ifdef PWM1 - if (reverse & PWM_REVERSE_BIT (PWM1)) - pwm_dir_reverse_b |= _BV (PWM1_DIR); -#endif -#ifdef PWM2 - if (reverse & PWM_REVERSE_BIT (PWM2)) - pwm_dir_reverse_b |= _BV (PWM2_DIR); -#endif -#ifdef PWM3 - if (reverse & PWM_REVERSE_BIT (PWM3)) - pwm_dir_reverse_e |= _BV (PWM3_DIR); -#endif -#ifdef PWM4 - if (reverse & PWM_REVERSE_BIT (PWM4)) - pwm_dir_reverse_e |= _BV (PWM4_DIR); -#endif + pwm_ocr_set_reverse (reverse); } -- cgit v1.2.3