summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordufourj2006-05-08 13:36:09 +0000
committerdufourj2006-05-08 13:36:09 +0000
commite7fb4f1b6b94fbcbaf56bbd350e4d45c1d7eef39 (patch)
treed3b648c9cdc8189e7cbc299cc0d2c568bf7f5be5
parentbb2dc882b10243fb0301379be0f1dbd43a393f49 (diff)
ES :
- début d'intégration avec la futur PWM de marcel ; - meilleur gestion des interruptions qui pourraient se "chevaucher". TODO : - améliorer un if pour le décallage de bits ; - calculer le nombre d'overflow de manière dynamique.
-rw-r--r--n/es-2006/src/Makefile2
-rw-r--r--n/es-2006/src/es_config.c50
-rw-r--r--n/es-2006/src/es_config.h41
-rw-r--r--n/es-2006/src/main.c61
-rw-r--r--n/es-2006/src/sensor_rvb.c90
-rw-r--r--n/es-2006/src/sensor_rvb.h42
-rw-r--r--n/es-2006/src/timer_main.h (renamed from n/es-2006/src/timer.h)16
7 files changed, 224 insertions, 78 deletions
diff --git a/n/es-2006/src/Makefile b/n/es-2006/src/Makefile
index 0d16f6a..444347b 100644
--- a/n/es-2006/src/Makefile
+++ b/n/es-2006/src/Makefile
@@ -1,6 +1,6 @@
BASE = ../../avr
PROGS = es
-es_SOURCES = main.c sensor_rvb.c
+es_SOURCES = main.c sensor_rvb.c es_config.c
MODULES = proto uart utils
CONFIGFILE = avrconfig.h
# atmega8, atmega8535, atmega128...
diff --git a/n/es-2006/src/es_config.c b/n/es-2006/src/es_config.c
new file mode 100644
index 0000000..1342bea
--- /dev/null
+++ b/n/es-2006/src/es_config.c
@@ -0,0 +1,50 @@
+/* es_config.c */
+/* es - Input/Output general purpose board. {{{
+ *
+ * Copyright (C) 2006 Dufour Jérémy
+ *
+ * Robot APB Team/Efrei 2004.
+ * 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 "es_config.h"
+
+/** Initialisation of the shared register for the timer/counter 1. */
+inline void
+timer1_init (void)
+{
+ /* Initialisation of timer/counter 1 control register A :
+ * - pwm : TODO Fast PWM 10 bits.
+ */
+ TCCR1A =
+ regv (COM1A1, COM1A0, COM1B1, COM1B0, COM1C1, COM1C0, WGM11, WGM10,
+ 0, 0, 0, 0, 0, 0, 1, 1 );
+ /* Initialisation of timer/counter 1 control register B :
+ * - shared : 1 for prescaling ;
+ * - rvb : noise canceler, IC on falling edge ;
+ * - pwm : TODO Fast PWM 10 bits.
+ */
+ TCCR1B = regv (ICNC1, ICES1, 5, WGM13, WGM12, CS12, CS11, CS10,
+ 1, 0, 0, 0, 1, 0, 0, 1 );
+ /* Initialisation of timer/counter 1 control register C :
+ * - pwm : TODO.
+ */
+// TCCR1C = regv (F0C1A, FOC1B, FOC1C, 4, 3, 2, 1, 0,
+// 0, 0, 0, 0, 0, 0, 0, 0);
+}
+
diff --git a/n/es-2006/src/es_config.h b/n/es-2006/src/es_config.h
new file mode 100644
index 0000000..5a94c84
--- /dev/null
+++ b/n/es-2006/src/es_config.h
@@ -0,0 +1,41 @@
+#ifndef es_config_h
+#define es_config_h
+// es_config.h
+// es - Input/Output general purpose board. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// 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.h" /* regv */
+#include "common.h" /* TCCR1*... */
+
+/** Common defines shared between differents modules inside the ES program. */
+
+/** The TOP of the timer/counter 1.
+ * This define has to be update by hand every time you change the
+ * configuration of the timer/counter 1. */
+#define TC1_TOP 0x03FF
+
+/** Initialisation of the shared register for the timer/counter 1. */
+extern void timer1_init (void);
+
+#endif // es_config_h
diff --git a/n/es-2006/src/main.c b/n/es-2006/src/main.c
index a269dfe..f5e15a8 100644
--- a/n/es-2006/src/main.c
+++ b/n/es-2006/src/main.c
@@ -29,18 +29,20 @@
#include "modules/proto/proto.h"
#include "modules/utils/utils.h"
-#include "timer.h" /* main timer */
+#include "timer_main.h" /* main timer */
#include "sensor_rvb.h" /* RVB sensors management */
+#include "es_config.h" /* timer/counter 1 */
-/* Statistics for sensors */
-uint8_t sensor_rvb_stat_enable = 0;
-uint8_t sensor_rvb_stats = 0;
+/* Statistics for RVB sensors */
+uint8_t sensor_rvb_stat_enable[RVB_MAX_SENSOR] = { 0 };
+uint8_t sensor_rvb_stats[RVB_MAX_SENSOR] = { 0 };
/** Call when we receive some data from proto (uart) */
void
proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
{
+ uint8_t compt;
/* This macro combine command and size in one integer. */
#define c(cmd, size) (cmd << 8 | size)
switch (c (cmd, size))
@@ -49,13 +51,21 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
case c ('z', 0):
utils_reset ();
break;
- case c ('S', 1):
- sensor_rvb_stats = sensor_rvb_stat_enable = args[0];
+ /* RVB sensors stats */
+ case c ('S', 3):
+ for (compt = 0; compt < RVB_MAX_SENSOR; compt++)
+ // TODO improve this !
+ if ( ((compt >= 8) && (args[0] & _BV(compt)))
+ || ((compt < 8) && (args[1] & _BV(compt))) )
+ {
+ sensor_rvb_stat_enable[compt] = sensor_rvb_stats[compt] =
+ args[2];
+ }
break;
- case c ('s', 2):
- sensor_rvb_watch (args[0], args[1]);
- break;
- /* Unknown command */
+// case c ('s', 2):
+// sensor_rvb_watch (args[0], args[1]);
+// break;
+ /* Unknown commands */
default:
proto_send0 ('?');
return;
@@ -68,26 +78,43 @@ proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
int
main (void)
{
- int compt;
+ uint8_t compt;
+ /* Serial port */
uart0_init ();
- timer_init ();
+ /* Main timer init */
+ timer_main_init ();
+ /* Init timer/counter 1 for RVB & PWM
+ * /!\ Must be called before RVB/PWM init ! */
+ timer1_init ();
+ /* Init RVB sensors system */
sensor_rvb_init ();
+
+ /* Enable interrupts */
sei ();
+
+ /* We are ready ! */
proto_send0 ('z');
while (1)
{
- timer_wait ();
- if (sensor_rvb_stat_enable && !--sensor_rvb_stats)
+ /* Wait 4.44 ms */
+ timer_main_wait ();
+
+ /* RVB Sensors stats */
+ for (compt = 0; compt < RVB_MAX_SENSOR; compt++)
+ if (sensor_rvb_stat_enable[compt] && !--sensor_rvb_stats[compt])
{
- sensor_rvb_stats = sensor_rvb_stat_enable;
- for (compt = 0; compt < RVB_MAX_SENSOR; compt++)
- proto_send4w ('S', sensor_rvb_values[compt][0],
+ /* Re init stats system for this sensor */
+ sensor_rvb_stats[compt] = sensor_rvb_stat_enable[compt];
+ proto_send4w ('S', sensor_rvb_values[compt][0],
sensor_rvb_values[compt][1], sensor_rvb_values[compt][2],
sensor_rvb_values[compt][3]);
}
+ /* Update RVB sensors data. */
sensor_rvb_start_capture ();
+
+ /* Get data for serial port */
while (uart0_poll ())
proto_accept (uart0_getc ());
}
diff --git a/n/es-2006/src/sensor_rvb.c b/n/es-2006/src/sensor_rvb.c
index ac8b0aa..a354c53 100644
--- a/n/es-2006/src/sensor_rvb.c
+++ b/n/es-2006/src/sensor_rvb.c
@@ -23,26 +23,32 @@
*
* }}} */
#include "sensor_rvb.h"
+#include "es_config.h"
#include "io.h"
#include "modules/utils/utils.h" /* regv */
#include "modules/uart/uart.h"
+#include "modules/proto/proto.h"
/**
* Somes defines.
**/
-/** Color pins. */
+/** Colors selection pins. */
#define S1RVB 7
#define S0RVB 6
/** Max input capture before considering we can start the real capture. */
-#define RVB_MAX_FALSE_IC 3
+#define RVB_MAX_FALSE_IC 4
+/** Max overflow of the timer 1 before thinking the sensor is HS. */
+/* TODO Find a way to compute this value */
+#define RVB_MAX_OVERFLOW 250
/** Wait time between IO change in ns. */
#define RVB_SENSOR_DELAY_IO 125
-/** All the possible states */
+/** All the possible states. */
#define RVB_STATE_SLEEP 0 /* Doing nothing */
#define RVB_STATE_NEXT_SENSOR 1 /* Selecting a sensor */
#define RVB_STATE_WAIT_IC 20 /* Waiting for the first input capture */
-#define RVB_STATE_WAIT_IC2 (RVB_STATE_WAIT_IC + 1) /* 2nd input capture */
+#define RVB_STATE_WAIT_IC2 (RVB_STATE_WAIT_IC + 1) /* 2nd and more false
+ input captures */
#define RVB_STATE_START_CAPTURE 2 /* After waiting enough IC, starting capture */
#define RVB_STATE_STOP_CAPTURE 3 /* We can compute a value */
#define RVB_STATE_NEXT_COLOR 4 /* Selecting another color */
@@ -57,7 +63,7 @@ volatile uint8_t sensor_rvb_number_;
/** Color of the actual sensor. */
volatile uint8_t sensor_rvb_color_;
/** Number of overflow interruption since last edge change. */
-uint8_t sensor_rvb_overflow_count_;
+volatile uint8_t sensor_rvb_overflow_count_;
/** Results table for 9 RVB sensors (RVCB) */
volatile uint16_t sensor_rvb_values[RVB_MAX_SENSOR][4];
/** Geting stats only for one sensors and disabling computing the others. */
@@ -65,6 +71,9 @@ uint8_t sensor_rvb_enable;
/** Count the number of IC before starting a good capture. */
uint8_t sensor_rvb_ic_count_;
+/** Update everything for you. */
+void sensor_rvb_update (void);
+
/** Select a color :
* 0 : red ;
* 1 : blue ;
@@ -73,14 +82,22 @@ uint8_t sensor_rvb_ic_count_;
inline uint8_t
sensor_rvb_color_select (uint8_t sensor_rvb_color)
{
- /* Check */
- if (sensor_rvb_color > 3)
+ switch (sensor_rvb_color)
+ {
+ case RVB_INDEX_RED:
+ case RVB_INDEX_BLUE:
+ case RVB_INDEX_CLEAR:
+ case RVB_INDEX_GREEN:
+ /* Select the color */
+ PORTF = (PORTF & ~0xC0) | (sensor_rvb_color << 6);
+ /* Wait a little */
+ utils_delay_ns (RVB_SENSOR_DELAY_IO);
+ /* Color exists */
+ return 1;
+ default:
+ /* Error */
return 0;
- /* Select the color */
- PORTF = (PORTF & ~0xC0) | (sensor_rvb_color << 6);
- /* Wait a little */
- utils_delay_ns (RVB_SENSOR_DELAY_IO);
- return 1;
+ }
}
/** Enable a RVB sensor. */
@@ -117,9 +134,6 @@ sensor_rvb_sensor_select (uint8_t sensor_rvb_num)
return 1;
}
-/** Update everything for you. */
-void sensor_rvb_update (void);
-
/** Initialisation of the RVB sensors module. */
void
sensor_rvb_init (void)
@@ -133,14 +147,6 @@ sensor_rvb_init (void)
DDRD |= _BV(6);
/* Put color selector pins in output */
DDRF |= _BV(S0RVB) | _BV(S1RVB);
- /* Initialisation of counter :
- * Noise canceler, 1 for prescaling */
- TCCR1B |= _BV(ICNC1) | _BV(CS10);
- /* XXX Fast PWM 10-bit */
- TCCR1B |= _BV(WGM12);
- TCCR1A |= _BV(WGM11) | _BV(WGM10);
- /* XXX Overflow IR */
- TIMSK |= _BV (TOIE1);
/* Nothing to do for the moment */
sensor_rvb_state_ = RVB_STATE_SLEEP;
}
@@ -150,7 +156,7 @@ void
sensor_rvb_start_capture (void)
{
/* Are we already getting a sensor ? */
- if (!sensor_rvb_state_ && sensor_rvb_enable)
+ if ((sensor_rvb_state_ == RVB_STATE_SLEEP) && sensor_rvb_enable)
{
sensor_rvb_state_ = RVB_STATE_NEXT_SENSOR;
/* Start with sensor one */
@@ -165,6 +171,7 @@ void
sensor_rvb_watch (uint8_t sensor_num, uint8_t sensor_col)
{
// XXX Better approach.
+ return;
/* Disable all interrupt that could be enabled */
TIMSK &= ~_BV (TICIE1);
TIMSK &= ~_BV (TOIE1);
@@ -199,7 +206,7 @@ sensor_rvb_update (void)
else
{
sensor_rvb_state_ = RVB_STATE_WAIT_IC;
- /* Enable interrupt for IC1 and counter overflow */
+ /* Enable interrupt for IC1 */
TIMSK |= _BV (TICIE1);
}
}
@@ -210,30 +217,43 @@ sensor_rvb_update (void)
/* Select sensor */
if (!sensor_rvb_sensor_select (++sensor_rvb_number_))
{
- /* Disable IC interrupt */
+ /* Disable IC1 and TC1 overflow interrupts */
TIMSK &= ~_BV (TICIE1);
+ TIMSK &= ~_BV (TOIE1);
sensor_rvb_state_ = RVB_STATE_SLEEP;
return;
}
/* Start with first color */
sensor_rvb_color_select (sensor_rvb_color_ = 0);
sensor_rvb_state_ = RVB_STATE_WAIT_IC;
+ sensor_rvb_overflow_count_ = 0;
/* Enable interrupt for IC1 and counter overflow */
TIMSK |= _BV (TICIE1);
+ TIMSK |= _BV (TOIE1);
}
}
/** Timer 1 overflow. */
SIGNAL (SIG_OVERFLOW1)
{
- if ((sensor_rvb_state_ == RVB_STATE_STOP_CAPTURE) &&
- (++sensor_rvb_overflow_count_ == 4))
+ switch (sensor_rvb_state_)
{
- /* Disable IC interrupt */
- TIMSK &= ~_BV (TICIE1);
- /* Ask for next sensor */
- sensor_rvb_state_ = RVB_STATE_NEXT_SENSOR;
- sensor_rvb_update ();
+ case RVB_STATE_START_CAPTURE:
+ ++sensor_rvb_overflow_count_;
+ break;
+ case RVB_STATE_WAIT_IC:
+ case RVB_STATE_WAIT_IC2:
+ // XXX >= Sucks !
+ // TODO : check this >= and the IC2 used
+ if (++sensor_rvb_overflow_count_ >= RVB_MAX_OVERFLOW)
+ {
+ /* Disable IC interrupt */
+ TIMSK &= ~_BV (TICIE1);
+ /* Ask for next sensor */
+ sensor_rvb_state_ = RVB_STATE_NEXT_SENSOR;
+ sensor_rvb_update ();
+ }
+ break;
}
}
@@ -251,15 +271,17 @@ SIGNAL (SIG_INPUT_CAPTURE1)
sensor_rvb_state_ = RVB_STATE_START_CAPTURE;
break;
case RVB_STATE_START_CAPTURE:
+ sensor_rvb_overflow_count_ = 0;
/* Save capture start */
sensor_rvb_value_ = ICR1;
/* New capture */
- sensor_rvb_overflow_count_ = 0;
sensor_rvb_state_ = RVB_STATE_STOP_CAPTURE;
break;
case RVB_STATE_STOP_CAPTURE:
/* Disable IC interrupt */
TIMSK &= ~_BV (TICIE1);
+ /* Ensure we have no pending interrupt for IC1. */
+ TIFR = _BV (ICF1);
/* Compute value */
sensor_rvb_value_ = ICR1 + sensor_rvb_overflow_count_ * TC1_TOP -
sensor_rvb_value_;
diff --git a/n/es-2006/src/sensor_rvb.h b/n/es-2006/src/sensor_rvb.h
index c060f68..d138311 100644
--- a/n/es-2006/src/sensor_rvb.h
+++ b/n/es-2006/src/sensor_rvb.h
@@ -29,28 +29,33 @@
#include "io.h"
/** Manage all the RVB sensors.
-Connectors :
- ENARVB7 PORTC7
- ENARVB6 PORTC6
- ENARVB5 PORTC5
- ENARVB4 PORTC4
- ENARVB3 PORTC3
- ENARVB2 PORTC2
- ENARVB1 PORTC1
- ENANB1 PORTD6
- ENANB2 PORTC0
- OUTRVB PORTD7/PORTD4(IC1)
- S0RVB PORTF6
- S1RVB PORTF7
+ * Connectors used :
+ ENARVB7 PORTC7
+ ENARVB6 PORTC6
+ ENARVB5 PORTC5
+ ENARVB4 PORTC4
+ ENARVB3 PORTC3
+ ENARVB2 PORTC2
+ ENARVB1 PORTC1
+ ENANB1 PORTD6
+ ENANB2 PORTC0
+ OUTRVB PORTD7/PORTD4(IC1)
+ S0RVB PORTF6
+ S1RVB PORTF7
- Sensor actualy send us a frequency for a specific color. We have pins for
- selecting.
+ Sensors actualy send us a frequency for a specific color. We have pins
+ (ENA*) for selecting the sensor we want to use, some (S[01]RVB) for the
+ color we want to watch and one (OUTRVB) for the output frequency.
+ It uses the Input Capture and the Overflow interrupts.
*/
-/** Define of the TOP of the timer 1. */
-#define TC1_TOP 0x03FF
/** Maximum number of sensors we manage. */
#define RVB_MAX_SENSOR 9
+/** Define the colors indexes. */
+#define RVB_INDEX_RED 0
+#define RVB_INDEX_BLUE 1
+#define RVB_INDEX_CLEAR 2
+#define RVB_INDEX_GREEN 3
/** Results table for 9 RVB sensors (RVCB) :
* Values are in the folowing order : Red, Blue, Clear, Green. */
@@ -64,7 +69,8 @@ void sensor_rvb_init (void);
/** Start a capture RVBC values for sensors if we are not already doing one. */
void sensor_rvb_start_capture (void);
-/** Watch only one sensor. Usefull for debugging. */
+/** Watch only one sensor. Usefull for debugging.
+ * Does not work ! XXX */
void sensor_rvb_watch (uint8_t sensor_num, uint8_t color_num);
#endif // sensor_rvb_h
diff --git a/n/es-2006/src/timer.h b/n/es-2006/src/timer_main.h
index 70f2de6..458db2e 100644
--- a/n/es-2006/src/timer.h
+++ b/n/es-2006/src/timer_main.h
@@ -1,6 +1,6 @@
-#ifndef timer_h
-#define timer_h
-// timer.h
+#ifndef timer_main_h
+#define timer_main_h
+// timer_main.h
// es - Input/Output general purpose board. {{{
//
// Copyright (C) 2006 Dufour Jérémy
@@ -26,9 +26,9 @@
//
// }}}
-/** Initialise the timer. */
+/** Initialise the main timer. */
inline void
-timer_init (void)
+timer_main_init (void)
{
TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS01, CS00,
0, 0, 0, 0, 0, 1, 1, 0);
@@ -38,9 +38,9 @@ timer_init (void)
* Tov = 1 / Fov = 4.444 ms */
}
-/** Wait for timer overflow. */
+/** Wait for main timer overflow. */
inline void
-timer_wait (void)
+timer_main_wait (void)
{
while (!(TIFR & _BV (TOV0)))
;
@@ -48,4 +48,4 @@ timer_wait (void)
TIFR = _BV (TOV0);
}
-#endif // timer_h
+#endif // timer_main_h