From ec8d0c161152e7278e6b36fb70be762185ae0926 Mon Sep 17 00:00:00 2001 From: schodet Date: Sat, 8 May 2004 11:08:22 +0000 Subject: Gestions entrée/sortie. --- 2004/i/nono/src/io/Makefile.defs | 9 ++ 2004/i/nono/src/io/gpio.cc | 104 +++++++++++++++++++++ 2004/i/nono/src/io/gpio.h | 58 ++++++++++++ 2004/i/nono/src/io/gpio_servo_pp.cc | 175 ++++++++++++++++++++++++++++++++++++ 2004/i/nono/src/io/gpio_servo_pp.h | 84 +++++++++++++++++ 2004/i/nono/src/io/servo.h | 39 ++++++++ 2004/i/nono/src/io/test_io.cc | 107 ++++++++++++++++++++++ 7 files changed, 576 insertions(+) create mode 100644 2004/i/nono/src/io/Makefile.defs create mode 100644 2004/i/nono/src/io/gpio.cc create mode 100644 2004/i/nono/src/io/gpio.h create mode 100644 2004/i/nono/src/io/gpio_servo_pp.cc create mode 100644 2004/i/nono/src/io/gpio_servo_pp.h create mode 100644 2004/i/nono/src/io/servo.h create mode 100644 2004/i/nono/src/io/test_io.cc (limited to '2004/i') diff --git a/2004/i/nono/src/io/Makefile.defs b/2004/i/nono/src/io/Makefile.defs new file mode 100644 index 0000000..6927dc0 --- /dev/null +++ b/2004/i/nono/src/io/Makefile.defs @@ -0,0 +1,9 @@ +TARGETS += test_io +LIBS += io.a +test_io_SOURCES = test_io.cc io.a date.a serial.a +io_a_SOURCES = gpio.cc gpio_servo_pp.cc + +test_io: $(test_io_SOURCES:%.cc=%.o) + +io.a: ${io_a_SOURCES:%.cc=io.a(%.o)} + diff --git a/2004/i/nono/src/io/gpio.cc b/2004/i/nono/src/io/gpio.cc new file mode 100644 index 0000000..172394d --- /dev/null +++ b/2004/i/nono/src/io/gpio.cc @@ -0,0 +1,104 @@ +// gpio.cc +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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 "gpio.h" + +/// Destructeur. +Gpio::~Gpio (void) +{ +} + +/// Change plusieurs sorties. +void +Gpio::set (int n, unsigned int bits, int nb) +{ + for (int i = 0; i < nb; ++i) + { + set (n + i, bits & 1); + bits >>= 1; + } +} + +/// Change une sortie. +void +Gpio::set (int n, unsigned int bit) +{ +} + +/// Lit plusieurs entrées. +unsigned int +Gpio::get (int n, int nb) +{ + unsigned int bits = 0; + for (int i = nb - 1; i >= 0; --i) + { + bits <<= 1; + bits |= get (n + i) & 1; + } + return bits; +} + +/// Lit une entrée. +unsigned int +Gpio::get (int n) +{ + return 0; +} + +/// Pré-lit plusieurs entrées. +bool +Gpio::preget (int n, int nb) +{ + bool ok = true; + for (int i = nb - 1; i >= 0; --i) + { + ok &= preget (n + i); + } + return ok; +} + +/// Pré-lit une entrée. +bool +Gpio::preget (int n) +{ + return true; +} + +/// Change la direction de plusieurs I/O. +void +Gpio::dir (int n, unsigned int bits, int nb) +{ + for (int i = 0; i < nb; ++i) + { + dir (n + i, bits & 1); + bits >>= 1; + } +} + +/// Change la direction d'un I/O (1 pour I, 0 pour O). +void +Gpio::dir (int n, unsigned int bit) +{ +} + diff --git a/2004/i/nono/src/io/gpio.h b/2004/i/nono/src/io/gpio.h new file mode 100644 index 0000000..ecc63f0 --- /dev/null +++ b/2004/i/nono/src/io/gpio.h @@ -0,0 +1,58 @@ +#ifndef gpio_h +#define gpio_h +// gpio.h +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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. +// +// }}} + +/// General Purpose Input/Output. +class Gpio +{ + public: + /// Destructeur. + virtual ~Gpio (void); + /// Change plusieurs sorties. + virtual void set (int n, unsigned int bits, int nb); + /// Change une sortie. + virtual void set (int n, unsigned int bit); + /// Racourci pour mettre à 1. + void set (int n) + { set (n, 1); } + /// Racourci pour mettre à 0. + void reset (int n) + { set (n, 0); } + /// Lit plusieurs entrées. + virtual unsigned int get (int n, int nb); + /// Lit une entrée. + virtual unsigned int get (int n); + /// Pré-lit plusieurs entrées. + virtual bool preget (int n, int nb); + /// Pré-lit une entrée. + virtual bool preget (int n); + /// Change la direction de plusieurs I/O. + virtual void dir (int n, unsigned int bits, int nb); + /// Change la direction d'un I/O (1 pour I, 0 pour O). + virtual void dir (int n, unsigned int bit); +}; + +#endif // gpio_h diff --git a/2004/i/nono/src/io/gpio_servo_pp.cc b/2004/i/nono/src/io/gpio_servo_pp.cc new file mode 100644 index 0000000..36f9334 --- /dev/null +++ b/2004/i/nono/src/io/gpio_servo_pp.cc @@ -0,0 +1,175 @@ +// gpio_servo_pp.cc +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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 "gpio_servo_pp.h" +#include "config/config.h" + +#include + +/// Constructeur. +GpioServoPp::GpioServoPp (void) + : outputs_ (0), inputs_ (0), lastInputRequestSend_ (-10000), + lastInputRecv_ (-10000), serial_ (true), ttyspeed_ (0), + log_ ("io", "pp") +{ + Config rc ("rc/gpio_servo_pp"); + while (!rc.eof ()) + { + if (!( + rc.get ("tty", ttyname_) || + rc.get ("ttyspeed", ttyspeed_) || + )) + rc.noId (); + } + serial_.open (ttyname_, ttyspeed_); + for (int i = 0; i < nbServo_; ++i) + servoPos_[i] = 0; +} + +/// Destructeur. +GpioServoPp::~GpioServoPp (void) +{ +} + +/// Change plusieurs sorties. +void +GpioServoPp::set (int n, unsigned int bits, int nb) +{ + if (n < 0 || n + nb > nbOutputs_) + throw std::out_of_range ("GpioServoPp::set: Out of range."); + unsigned int mask = (1 << nb) - 1; + bits <<= n; + outputs_ = (outputs_ & ~mask) | (bits & mask) | 0x80; + serial.putchar (outputs_); + log_ (Log::debug) << "send " << std::hex << outputs_ << std::dec << + std::endl; +} + +/// Change une sortie. +void +GpioServoPp::set (int n, unsigned int bit) +{ + set (n, bit, 1); +} + +/// Lit plusieurs entrées. +unsigned int +GpioServoPp::get (int n, int nb) +{ + if (n < nbOutputs_ || n + nb > nbOutputs_ + nbInputs_) + throw std::out_of_range ("GpioServoPp::get: Out of range."); + unsigned int mask = 1 << (nb) - 1; + unsigned int bits = (inputs_ >> (n - nbOutputs_)) & mask; + return bits; +} + +/// Lit une entrée. +unsigned int +GpioServoPp::get (int n) +{ + return get (n, 1); +} + +/// Pré-lit plusieurs entrées. +bool +GpioServoPp::preget (int n, int nb) +{ + int date = Date::getInstance ().start (); + if (lastInputRecv_ + inputValidityTimeout_ > date) + { + // Donnée prête. + return true; + } + else + { + // Donnée périmée. + // Lit tout ce qui arrive du port serie. + int c; + while ((c = serial_.getchar ()) != -1) + { + log_ (Log::debug) << "recv " << std::hex << c << std::dec << + std::endl; + inputs_ = c; + lastInputRecv_ = date; + } + // Si le dernier envois est assez recent, on garde ce qu'on a recu. + if (lastInputRequestSend_ + inputRequestTimeout_ > date) + { + return true; + } + else + { + lastInputRecv_ = -10000; + lastInputRequestSend_ = date; + serial_.putchar (0xff); + log_ (Log::debug) << "recv " << std::hex << 0xff << std::dec << + std::endl; + return false; + } + } +} + +/// Pré-lit une entrée. +bool +GpioServoPp::preget (int n) +{ + return preget (n, 1); +} + +/// Change la direction de plusieurs I/O. +void +GpioServoPp::dir (int n, unsigned int bits, int nb) +{ + throw std::invalid_argument ("GpioServoPp::dir: Operation not supported"); +} + +/// Change la direction d'un I/O (1 pour I, 0 pour O). +void +GpioServoPp::dir (int n, unsigned int bit) +{ + dir (n, bit, 1); +} + +/// Bouge un servo de DIFF. +void +GpioServoPp::move (int n, int diff) +{ + n %= servoPos_; + servoPos_[n] += diff; + int v = n << 7 | servoPos_[n]; + serial.putchar (v); + log_ (Log::debug) << "send " << std::hex << v << std::dec << std::endl; +} + +/// Bouge un servo en position POS. +void +GpioServoPp::moveTo (int n, int pos) +{ + n %= servoPos_; + servoPos_[n] = pos; + int v = n << 7 | servoPos_[n]; + serial.putchar (v); + log_ (Log::debug) << "send " << std::hex << v << std::dec << std::endl; +} + diff --git a/2004/i/nono/src/io/gpio_servo_pp.h b/2004/i/nono/src/io/gpio_servo_pp.h new file mode 100644 index 0000000..5ece61f --- /dev/null +++ b/2004/i/nono/src/io/gpio_servo_pp.h @@ -0,0 +1,84 @@ +#ifndef gpio_servo_pp_h +#define gpio_servo_pp_h +// gpio_servo_pp.h +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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 "gpio.h" +#include "servo.h" +#include "serial/serial.h" +#include "logger/log.h" + +#include + +/// Classe pour la gestion de la carte servo à Pierre Prot. +class GpioServoPp : public Gpio, public Servo +{ + /// Nombre d'entrées/sorties. + static const int nbInputs_ = 6, nbOutputs_ = 6, nbServo_ = 2; + /// Sorties courantes. + unsigned int outputs_; + /// Dernière valeurs d'entrées. + unsigned int inputs_; + /// Timeouts. + static const int inputRequestTimeout_ = 100, inputValidityTimeout_ = 100; + /// Date du dernier envois. + int lastInputRequestSend_; + /// Date de la dernière reception. + int lastInputRecv_; + /// Position des servos. + int servoPos_[nbServo_]; + // Ligne série. + Serial serial_; + std::string ttyname_; + int ttyspeed_; + // Logger. + Log log_; + public: + /// Constructeur. + GpioServoPp (void); + /// Destructeur. + ~GpioServoPp (void); + /// Change plusieurs sorties. + void set (int n, unsigned int bits, int nb); + /// Change une sortie. + void set (int n, unsigned int bit); + /// Lit plusieurs entrées. + unsigned int get (int n, int nb); + /// Lit une entrée. + unsigned int get (int n); + /// Pré-lit plusieurs entrées. + bool preget (int n, int nb); + /// Pré-lit une entrée. + bool preget (int n); + /// Change la direction de plusieurs I/O. + void dir (int n, unsigned int bits, int nb); + /// Change la direction d'un I/O (1 pour I, 0 pour O). + void dir (int n, unsigned int bit); + /// Bouge un servo de DIFF. + void move (int n, int diff); + /// Bouge un servo en position POS. + void moveTo (int n, int pos); +}; + +#endif // gpio_servo_pp_h diff --git a/2004/i/nono/src/io/servo.h b/2004/i/nono/src/io/servo.h new file mode 100644 index 0000000..08c63cf --- /dev/null +++ b/2004/i/nono/src/io/servo.h @@ -0,0 +1,39 @@ +#ifndef servo_h +#define servo_h +// servo.h +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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. +// +// }}} + +/// Classe d'interfacage servo. +class Servo +{ + public: + /// Destructeur. + virtual ~Servo (void) { } + /// Bouge un servo de DIFF. + virtual void move (int n, int diff) = 0; + /// Bouge un servo en position POS. + virtual void moveTo (int n, int pos) = 0; +}; +#endif // servo_h diff --git a/2004/i/nono/src/io/test_io.cc b/2004/i/nono/src/io/test_io.cc new file mode 100644 index 0000000..8b01554 --- /dev/null +++ b/2004/i/nono/src/io/test_io.cc @@ -0,0 +1,107 @@ +// test_io.cc +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// 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 "gpio_servo_pp.h" +#include "servo.h" +#include "date/date.h" + +#include +#include + +void +syntax (void) +{ + std::cout << + "test_io - teste les entrées/sorties.\n" + " s set des sorties.\n" + " g get des entrées.\n" + " attend un certain temps (qui augmente avec timeout)\n" + " ? cet ecran d'aide" << std::endl; +} + +int +main (int argc, char **argv) +{ + try + { + GpioServoPp gspp; + int i = 1; + while (i < argc) + { + switch (argv[i][0]) + { + case 's': + i++; + int n, bits, nb; + if (i >= argc) break; + n = atoi (argv[i++]); + if (i >= argc) break; + bits = atoi (argv[i++]); + if (i >= argc) break; + nb = atoi (argv[i++]); + std::cout << "set " << n << ' ' << std::hex << bits << + std::dec << ' ' << nb << std::endl; + gspp.set (n, bits, nb); + break; + case 'g': + i++; + int n, bits, nb; + if (i >= argc) break; + n = atoi (argv[i++]); + if (i >= argc) break; + nb = atoi (argv[i++]); + for (int i = 0; i < 20; ++i) + { + std::cout << "preget " << n << ' ' << nb << std::endl; + if (gspp.preget (n, nb)) + { + bits = gspp.get (n, nb); + std::cout << "get " << std::hex << bits << std::dec << + std::endl; + break; + } + Date::wait (50); + } + break; + default: + int s; + s = atoi (argv[i++]); + if (s == 0) + { + syntax (); + return 1; + } + cout << "test: sleep " << s << endl; + Date::wait (s * 1000); + break; + } + } + return 0; + } + catch (const std::exception &e) + { + std::cerr << e.what () << std::endl; + return 1; + } +} -- cgit v1.2.3