summaryrefslogtreecommitdiff
path: root/analog
diff options
context:
space:
mode:
authorGuillaume Chevillot2008-03-13 10:34:32 +0100
committerGuillaume Chevillot2008-03-13 10:34:32 +0100
commit65baffda4311b55c9d4026d84c1c1544d0ee7aa4 (patch)
treecef12af16ced96358a4cbf163db674d8ba8a4f14 /analog
parent7e1e72e29349a8248901d4d4f466d1c9b556344d (diff)
- 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...)
Diffstat (limited to 'analog')
-rw-r--r--analog/motor-power-avr/src/TODO.txt5
-rw-r--r--analog/motor-power-avr/src/main.c14
-rw-r--r--analog/motor-power-avr/src/mp_pwm_LR_.c29
-rw-r--r--analog/motor-power-avr/src/mp_pwm_LR_.h26
-rw-r--r--analog/motor-power-avr/src/mp_pwm_L_.c10
-rw-r--r--analog/motor-power-avr/src/pwm.avr.c127
6 files changed, 61 insertions, 150 deletions
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;
-}
-