From c34c7f4b78ddf31d422454cb440ed31647d9b964 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 2 May 2011 23:28:00 +0200 Subject: digital/{ai,io}: move timer and chrono to ai --- digital/ai/src/utils/chrono.c | 150 +++++++++++++++++++++++++++++++++++++++ digital/ai/src/utils/chrono.h | 99 ++++++++++++++++++++++++++ digital/ai/src/utils/timer.avr.c | 59 +++++++++++++++ digital/ai/src/utils/timer.h | 68 ++++++++++++++++++ 4 files changed, 376 insertions(+) create mode 100644 digital/ai/src/utils/chrono.c create mode 100644 digital/ai/src/utils/chrono.h create mode 100644 digital/ai/src/utils/timer.avr.c create mode 100644 digital/ai/src/utils/timer.h (limited to 'digital/ai') diff --git a/digital/ai/src/utils/chrono.c b/digital/ai/src/utils/chrono.c new file mode 100644 index 00000000..a1212e19 --- /dev/null +++ b/digital/ai/src/utils/chrono.c @@ -0,0 +1,150 @@ +/* chrono.c */ +/* ai - Robot Artificial Intelligence. {{{ + * + * Copyright (C) 2008 Dufour Jérémy + * + * 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 "timer.h" +#include "asserv.h" +#include "twi_master.h" + +#include "modules/utils/utils.h" +#include "modules/host/mex.h" + +#include "chrono.h" + +/** + * Implementation notes. + * This module compute the number of tic of the main loop it should count + * before the match is over (chrono_init). Every tic of the main loop, it + * decrements the counter (chrono_update). When the counter is zero, the + * match is over (chrono_is_match_over, chrono_end_match). + */ + +/** Number of overflows of the timer to wait before the match is over. */ +#define CHRONO_MATCH_OVERFLOW_COUNT \ + (CHRONO_MATCH_DURATION_MS / TIMER_PERIOD_MS) + +/** + * Duration of a loop to emulate from the original behaviour, in ms. + */ +#define CHRONO_LOOP_DURATION_MS 4 + +/** + * Time to wait before resetting slaves board, in ms. + */ +#define CHRONO_WAIT_BEFORE_RESET_MS 1000 + +/** + * Number of time to overflow before the end of the match. + */ +static uint32_t chrono_ov_count_; + +/** + * Status of the chrono module. + * Set to 0 if the module is disabled, otherwise set to a non 0 value. + */ +static uint8_t chrono_enabled_ = 0; + + +void +chrono_init (void) +{ + /* Enable chrono. */ + chrono_enable (); + /* Set the overflow counter to the maximum of overflow before the end of + * the match. */ + chrono_ov_count_ = CHRONO_MATCH_OVERFLOW_COUNT; +} + +void +chrono_update (void) +{ + /* Decrement overflow counter if it is possible. */ + if (chrono_enabled_ && chrono_ov_count_) + chrono_ov_count_--; +} + +uint8_t +chrono_is_match_over (void) +{ + if (!chrono_enabled_ || chrono_ov_count_) + return 0; + else + return 1; +} + +void +chrono_enable (void) +{ + chrono_enabled_ = 1; +} + +void +chrono_disable (void) +{ + chrono_enabled_ = 0; +} + +uint8_t +chrono_enabled (void) +{ + return chrono_enabled_; +} + +uint32_t +chrono_remaining_time (void) +{ + return chrono_ov_count_ * TIMER_PERIOD_MS; +} + +void +chrono_end_match (uint8_t block) +{ + /* Make sure previous command has been acknowledged. If not, retransmit + * until acknowledged */ + while (!twi_master_sync ()) + utils_delay_ms (CHRONO_LOOP_DURATION_MS); + + /* Make the bot stop moving */ + asserv_stop_motor (); + + /* Wait until complete */ + while (!twi_master_sync ()) + utils_delay_ms (CHRONO_LOOP_DURATION_MS); + + /* Wait CHRONO_WAIT_BEFORE_RESET ms before reseting */ + utils_delay_ms (CHRONO_WAIT_BEFORE_RESET_MS); + /* Reset the asserv board */ + asserv_reset (); + /* Block indefinitely */ + if (block) + while (42) +#ifdef HOST + { + mex_node_wait (); + } +#else + ; +#endif +} diff --git a/digital/ai/src/utils/chrono.h b/digital/ai/src/utils/chrono.h new file mode 100644 index 00000000..38bf3d61 --- /dev/null +++ b/digital/ai/src/utils/chrono.h @@ -0,0 +1,99 @@ +#ifndef chrono_h +#define chrono_h +/* chrono.h */ +/* ai - Robot Artificial Intelligence. {{{ + * + * Copyright (C) 2008 Dufour Jérémy + * + * 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. + * + * }}} */ + +/** + * @file Module to manage the chrono responsible to stop the bot after 90s. + * + * It is based on the main timer to know when to stop the bot. + * + * The main loop should never last more than the 4.44ms defined, otherwise, + * this module will not be precise at all! + */ + +/** Duration of a match in milliseconds, with margin. */ +#define CHRONO_MATCH_DURATION_MS (90000 - 2500) + +/** + * Initialize the chrono module. + * It setups it for a duration of CHRONO_MATCH_DURATION_MS. + */ +void +chrono_init (void); + +/** + * Update chrono module. + * You must call this function every overflow of the main timer. + */ +void +chrono_update (void); + +/** + * Enable chrono module. + * You should call this function when a match start. + */ +void +chrono_enable (void); + +/** + * Disable chrono module. + */ +void +chrono_disable (void); + +/** + * Is chrono module enabled? + * @return 0 if not enabled, other values otherwise. + */ +uint8_t +chrono_enabled (void); + +/** + * Match over? + * @return + * - 0 if the match is not finished yet. + * - 1 if the match is over. + */ +uint8_t +chrono_is_match_over (void); + +/** + * How much time remains before the end of the match. + * @return remaining time in ms. + */ +uint32_t +chrono_remaining_time (void); + +/** + * End the match. + * This function is responsible of resetting the asserv board to stop the bot + * from moving and put the io board in a state where it will not do something. + * @param block blocking function until hardware reset? + */ +void +chrono_end_match (uint8_t block); + +#endif /* chrono_h */ diff --git a/digital/ai/src/utils/timer.avr.c b/digital/ai/src/utils/timer.avr.c new file mode 100644 index 00000000..b8756d88 --- /dev/null +++ b/digital/ai/src/utils/timer.avr.c @@ -0,0 +1,59 @@ +/* timer.avr.c */ +/* ai - Robot Artificial Intelligence. {{{ + * + * Copyright (C) 2009 Dufour Jérémy + * + * 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 "timer.h" + +#include "modules/utils/utils.h" +#include "io.h" + +void +timer_init (void) +{ + /* Configuration of the timer/counter 0: + * - top = 0xff, + * - prescaler = 256, + * -> Fov = F_io / (prescaler * (TOP + 1)) + * -> Tov = 1 / Fov + * Note: if you change the TCCR0 register value, please also update + * TIMER_TC0_PRESCALER and TIMER_TC0_TOP. */ + TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS01, CS00, + 0, 0, 0, 0, 0, 1, 1, 0); +} + +uint8_t +timer_wait (void) +{ + /* Let's pretend we have reached overflow before calling this function. */ + uint8_t count_before_ov = 1; + /* Loop until an overflow of the timer occurs. */ + while (!(TIFR & _BV (TOV0))) + /* We have not reached overflow. */ + count_before_ov = 0; + /* Write 1 to clear overflow. */ + TIFR = _BV (TOV0); + return count_before_ov; +} + diff --git a/digital/ai/src/utils/timer.h b/digital/ai/src/utils/timer.h new file mode 100644 index 00000000..e085b86e --- /dev/null +++ b/digital/ai/src/utils/timer.h @@ -0,0 +1,68 @@ +#ifndef timer_h +#define timer_h +/* timer.h */ +/* ai - Robot Artificial Intelligence. {{{ + * + * Copyright (C) 2009 Dufour Jérémy + * + * 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. + * + * }}} */ + +/** + * Tick timer, used to slow down the main loop to a given rate. + */ + +/** + * Prescaler configured for timer/counter 0. + * If you want to change this value, you also need to change the TCCR0 + * register. + */ +#define TIMER_TC0_PRESCALER 256L + +/** + * Top configured for timer/counter 0. + * If you want to change this value, you also need to change the TCCR0 + * register. + */ +#define TIMER_TC0_TOP 255 + +/** Period of timer, ms. */ +#define TIMER_PERIOD_MS \ + (1000.0 / (AC_FREQ / (TIMER_TC0_PRESCALER * (TIMER_TC0_TOP + 1)))) + +/** Initialise timer. */ +void +timer_init (void); + +/** + * Wait until the timer overflows. + * @return + * - 0 if we are on time (we have not reached overflow before calling this + * function). + * - 1 if we have already reached overflow. + * @warning if this function return 1, it means we are late and the main loop + * is lasting more than the time configured. Consequence, some important + * functions (like the chronometer for match duration) will not work + * correctly! + */ +uint8_t +timer_wait (void); + +#endif /* timer_h */ -- cgit v1.2.3