From 65baffda4311b55c9d4026d84c1c1544d0ee7aa4 Mon Sep 17 00:00:00 2001 From: Guillaume Chevillot Date: Thu, 13 Mar 2008 10:34:32 +0100 Subject: - Add current limitation management (not tested yet !) : - Add current limitation PWM generation - Add external current limitation interrupts management - Update current limitation software part - Update TODO list (try to reduce it...) --- analog/motor-power-avr/src/TODO.txt | 5 +- analog/motor-power-avr/src/main.c | 14 ++-- analog/motor-power-avr/src/mp_pwm_LR_.c | 29 ++++++-- analog/motor-power-avr/src/mp_pwm_LR_.h | 26 +++++-- analog/motor-power-avr/src/mp_pwm_L_.c | 10 ++- analog/motor-power-avr/src/pwm.avr.c | 127 -------------------------------- 6 files changed, 61 insertions(+), 150 deletions(-) delete mode 100644 analog/motor-power-avr/src/pwm.avr.c (limited to 'analog/motor-power-avr') diff --git a/analog/motor-power-avr/src/TODO.txt b/analog/motor-power-avr/src/TODO.txt index eb5e6fda..490817e1 100644 --- a/analog/motor-power-avr/src/TODO.txt +++ b/analog/motor-power-avr/src/TODO.txt @@ -2,7 +2,6 @@ TOTOlist pour le programe avr de motor-power - peaufiner la boucle de mesure automatique de la température et de la batterie - souder le deuxième pont -- implémenter la limitation en courant - implémenter la mesure de température et l'abaissement automatique de la limitation en courant - implémenter la mesure de tension de batterie et l'abaissement automatique @@ -13,8 +12,8 @@ entre les PWM des deux ponts Tester : - la génération de la PWM de la limitation de courant -- le protocole -- mesurer la linéarité, les valeurs PWM min et max, la période +- le protocole (commandes 'l', 'r', 'L', 'R', et 'w' testées OK) +- mesurer la linéarité du PWM - tester la limitation en courant. Attention : la carte actuelle ne supportera pas plus de 10A. Pour celà, mettre la PWM à une valeur entre 50% et 90% sur une charge qui débite environt 3 à 8A (oui... il faut trouver la diff --git a/analog/motor-power-avr/src/main.c b/analog/motor-power-avr/src/main.c index c5ce6581..4a9b453e 100644 --- a/analog/motor-power-avr/src/main.c +++ b/analog/motor-power-avr/src/main.c @@ -91,9 +91,9 @@ main (int argc, char **argv) /* Pull-ups. */ //PORTA = 0xff; + uart0_init (); init_timer_LR_ (); init_curLim (); - uart0_init (); //postrack_init (); envTest_period = 200; @@ -137,16 +137,16 @@ main_loop (void) { /* Uart */ if (uart0_poll ()) - proto_accept (uart0_getc ()); + proto_accept (uart0_getc ()); /* Counter for launching environemental tests */ if (!(envTest_cpt --)) { - envTest_cpt = envTest_period; + envTest_cpt = envTest_period; - launch_envTest (); - curLim_temp = get_curLim_temp (temperature); - curLim_bat= get_curLim_bat (battery); - update_curLim (); + launch_envTest (); + curLim_temp = get_curLim_temp (temperature); + curLim_bat= get_curLim_bat (battery); + update_curLim (); } } diff --git a/analog/motor-power-avr/src/mp_pwm_LR_.c b/analog/motor-power-avr/src/mp_pwm_LR_.c index e3ec252c..c35dc5df 100644 --- a/analog/motor-power-avr/src/mp_pwm_LR_.c +++ b/analog/motor-power-avr/src/mp_pwm_LR_.c @@ -13,6 +13,7 @@ static uint8_t curLim_soft; // state_L_ : x - Inhib - changeDir - Dir - x - x - x - x // Timer_L_ : timer dedicated to Left side +/** Initialize timers for left and right side PWM generation */ void init_timer_LR_(void) { init_pwm_L_(); init_pwm_R_(); @@ -31,11 +32,22 @@ void init_timer_LR_(void) { TCCR_R_ = TCCR_LR_CFG; } +/** Initialize the timer for left and right current limitation */ void init_curLim (void) { - // TODO : set interrupts - curLim_soft = 0x80; - curLim_bat = 0x00; - curLim_temp = 0x00; + curLim_soft = CURLIM_MAX; + curLim_bat = CURLIM_MAX; + curLim_temp = CURLIM_MAX; + + // Configure and run current limit PWM + TCCR1A = TCCRA_LR_CFG; + TCCR1B = TCCRB_LR_CFG; + + // Configure and enable INT0 and INT1 + MCUCR |= MCUCR_LR_CFG; + GICR |= GICR_LR_CFG; + + // Apply the current limitation + update_curLim(); } uint8_t get_curLim_temp (uint8_t temperature) { @@ -46,13 +58,15 @@ uint8_t get_curLim_bat (uint8_t battery) { return (battery - 40) >> 2; // TODO : ajuster la fonction de transfert } -// this function shall be called after each adjustment of any current limit -void update_curLim(void) { +/** Update the current limitation PWM + * this function shall be called after each adjustment of any current limit */ +inline void update_curLim(void) { uint8_t curLim_tmp; // search for MIN(curLim_soft, curLim_temp, curLim_bat) curLim_tmp = curLim_soft; + /* TODO: implement curLim_temp and curLim_bat if (curLim_tmp > curLim_temp) { curLim_tmp = curLim_temp; @@ -62,6 +76,7 @@ void update_curLim(void) { { curLim_tmp = curLim_bat; } + */ if (curLim_tmp > CURLIM_MAX) { @@ -83,7 +98,7 @@ void launch_envTest(void) { update_curLim(); } -// set the software-programmed current limit +/* Set the software-programmed current limitation */ void setCurLim_soft(uint8_t curLim) { curLim_soft = curLim; update_curLim(); diff --git a/analog/motor-power-avr/src/mp_pwm_LR_.h b/analog/motor-power-avr/src/mp_pwm_LR_.h index 32a0f08a..b8c6887f 100644 --- a/analog/motor-power-avr/src/mp_pwm_LR_.h +++ b/analog/motor-power-avr/src/mp_pwm_LR_.h @@ -98,16 +98,32 @@ #define TCCR_L_ TCCR0 #define TCCR_R_ TCCR2 -// timer configuration -// for 57.21kHz : prescaler = 0 : CSx2:0 = 0x01 -// for 7.68kHz : prescaler = 8 : CSx2:0 = 0x02 +/** Timer configuration for left and right side + * for 57.21kHz : prescaler = 0 : CSx2:0 = 0x01 + * for 7.68kHz : prescaler = 8 : CSx2:0 = 0x02 */ #define TCCR_LR_CFG (regv (FOC0, WGM00, COM01, COM00, WGM01, CS02, CS01, CS00, \ 0, 1, 0, 0, 1, 0, 1, 0)) -// timer interrupts configuration +/** Set timer interrupts configuration */ #define TIMSK_LR_CFG (regv (OCIE2, TOIE2, TICIE1, OCIE1A, OCIE1B, TOIE1, OCIE0, TOIE0, \ 1, 1, 0, 0, 0, 0, 1, 1)) +/** Defines timer control register for current limitation PWM (both side) + * toggle OC1x on compare, fast 8bit PWM mode, no prescaling */ +#define TCCRA_LR_CFG (regv (COM1A1, COM1A0, COM1B1, COM1B0, FOC1A, FOC1B, WGM11, WGM10, \ + 0, 1, 0, 1, 0, 0, 0, 1)) +#define TCCRB_LR_CFG (regv (ICNC1, ICES1, 5, WGM13, WGM12, CS12, CS11, CS10, \ + 0, 0, 0, 0, 1, 0, 0, 1)) + +/** Defines external interrupts level configuration : + * low level of INT0 and INT1 generates an interrup request */ +#define MCUCR_LR_CFG (regv (SM2, SE, SM1, SM0, ISC11, ISC10, ISC01, ISC00, \ + 0, 0, 0, 0, 0, 0, 0, 0)) + +/** Enable external interrupts INT1 and INT0 fir current limitation */ +#define GICR_LR_CFG (regv (INT1, INT0, INT2, 4, 3, 2, IVSEL, IVCE, \ + 1, 1, 0, 0, 0, 0, 0, 0)) + // PWM max, min, and offset values #define PWM_MIN_LR_ 0x10 #define PWM_MAX_LR_ 0xF0 @@ -137,7 +153,7 @@ void init_timer_LR_(void); void init_curLim (void); uint8_t get_curLim_temp (uint8_t temperature); uint8_t get_curLim_bat (uint8_t battery); -void update_curLim(void); +inline void update_curLim(void); void launch_envTest(void); void setCurLim_soft(uint8_t curLim); diff --git a/analog/motor-power-avr/src/mp_pwm_L_.c b/analog/motor-power-avr/src/mp_pwm_L_.c index 2ad3e329..ebd6429a 100644 --- a/analog/motor-power-avr/src/mp_pwm_L_.c +++ b/analog/motor-power-avr/src/mp_pwm_L_.c @@ -152,13 +152,21 @@ ISR(COMP_L_vect) { // overcurrent detected by comparators ISR(ILIM_L_vect) { + // Set outputs in High-Z _L_AL_0; _L_AH_0; _L_BL_0; _L_BH_0; - sei(); // set back interrupts + // following line orders to keep high Z state when faling edge will arrive state_L_ = CMD_STATE_HIGH_Z; + + sei(); // set back interrupts + + // Update LEDs + _L_LED0_0; + _L_LED1_0; + return; } diff --git a/analog/motor-power-avr/src/pwm.avr.c b/analog/motor-power-avr/src/pwm.avr.c deleted file mode 100644 index 01195a8e..00000000 --- a/analog/motor-power-avr/src/pwm.avr.c +++ /dev/null @@ -1,127 +0,0 @@ -/* pwm.avr.c */ -/* asserv - Position & speed motor control on AVR. {{{ - * - * 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 "modules/utils/utils.avr.h" - -/** Define the PWM output used for left motor. */ -#define PWM_LEFT_OCR OCR1C -/** Define the PWM output used for right motor. */ -#define PWM_RIGHT_OCR OCR1B -/** Define the direction output for left motor. */ -#define PWM_LEFT_DIR 3 -/** Define the direction output for right motor. */ -#define PWM_RIGHT_DIR 2 - -/** Define the absolute maximum PWM value. */ -#define PWM_MAX 0x3ff - -/** PWM values, this is an error if absolute value is greater than the - * maximum. */ -int16_t pwm_left, pwm_right; -/** PWM reverse direction, only set pwm dir bits or you will get weird results - * on port B. */ -uint8_t pwm_dir = _BV (PWM_LEFT_DIR); - -/* +AutoDec */ - -/** Initialise PWM generator. */ -static inline void -pwm_init (void); - -/** Update the hardware PWM values. */ -static inline void -pwm_update (void); - -/* -AutoDec */ - -/** Initialise PWM generator. */ -static inline void -pwm_init (void) -{ - /* Fast PWM, TOP = 0x3ff, OC1B & OC1C with positive logic. - f_IO without prescaler. - Fpwm = f_IO / (prescaler * (1 + TOP)) = 14400 Hz. */ - 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 |= _BV (7) | _BV (6) | _BV (PWM_LEFT_DIR) | _BV (PWM_RIGHT_DIR); -} - -/** Update the hardware PWM values. */ -static inline void -pwm_update (void) -{ - uint16_t left, right; - uint8_t dir; - /* Some assumption checks. */ - assert (pwm_left >= -PWM_MAX && pwm_left <= PWM_MAX); - assert (pwm_right >= -PWM_MAX && pwm_right <= PWM_MAX); - assert ((pwm_dir & ~(_BV (PWM_LEFT_DIR) | _BV (PWM_RIGHT_DIR))) == 0); - /* Sample port B. */ - dir = PORTB & ~(_BV (PWM_LEFT_DIR) | _BV (PWM_RIGHT_DIR)); - /* Set left PWM. */ - if (pwm_left == 0) - { - left = 0; - } - else if (pwm_left < 0) - { - left = -pwm_left; - } - else - { - dir |= _BV (PWM_LEFT_DIR); - left = pwm_left; - } - /* Set right PWM. */ - if (pwm_right == 0) - { - right = 0; - } - else if (pwm_right < 0) - { - right = -pwm_right; - } - else - { - dir |= _BV (PWM_RIGHT_DIR); - right = pwm_right; - } - /* Setup registers. */ - /* Here, there could be a problem because OCRx are double buffered, not - * PORTB! */ - /* 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. */ - dir ^= pwm_dir; - PORTB = dir; - PWM_LEFT_OCR = left; - PWM_RIGHT_OCR = right; -} - -- cgit v1.2.3