// gpio_concat.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_concat.h" /// Constructeur. GpioConcat::GpioConcat (Gpio &io0, Gpio &io1, int nSep) : io0_ (io0), io1_ (io1), nSep_ (nSep) { } /// Change plusieurs sorties. void GpioConcat::set (int n, unsigned int bits, int nb) { if (n < nSep_) { int n0, bits0, nb0; n0 = n; nb0 = n + nb > nSep_ ? nSep_ - n : nb; bits0 = bits & ((1 << nb0) - 1); io0_.set (n0, bits0, nb0); } if (n + nb > nSep_) { int n1, bits1, nb1; n1 = n < nSep_ ? 0 : n - nSep_; nb1 = n < nSep_ ? nb - nSep_ + n : nb; bits1 = n < nSep_ ? bits >> (nSep_ - n) : bits; bits1 &= ((1 << nb1) - 1); io1_.set (n1, bits1, nb1); } } /// Lit plusieurs entrées. unsigned int GpioConcat::get (int n, int nb) { int n0, bits0 = 0, nb0; int n1, bits1 = 0, nb1; if (n < nSep_) { n0 = n; nb0 = n + nb > nSep_ ? nSep_ - n : nb; bits0 = io0_.get (n0, nb0); bits0 &= ((1 << nb0) - 1); } if (n + nb > nSep_) { n1 = n < nSep_ ? 0 : n - nSep_; nb1 = n < nSep_ ? nb - nSep_ + n : nb; bits1 = io1_.get (n1, nb1); bits1 &= ((1 << nb1) - 1); bits1 = n < nSep_ ? bits1 << (nSep_ - n) : bits1; } return bits0 | bits1; } /// Change la direction de plusieurs I/O. void GpioConcat::dir (int n, unsigned int bits, int nb) { if (n < nSep_) { int n0, bits0, nb0; n0 = n; nb0 = n + nb > nSep_ ? nSep_ - n : nb; bits0 = bits & ((1 << nb0) - 1); io0_.dir (n0, bits0, nb0); } if (n + nb > nSep_) { int n1, bits1, nb1; n1 = n < nSep_ ? 0 : n - nSep_; nb1 = n < nSep_ ? nb - nSep_ + n : nb; bits1 = n < nSep_ ? bits >> (nSep_ - n) : bits; bits1 &= ((1 << nb1) - 1); io1_.dir (n1, bits1, nb1); } } /// Met à jour. void GpioConcat::update (void) { io0_.update (); io1_.update (); } /// Récupère le nombre d'entrées/sorties. int GpioConcat::getNbIo (void) { return io0_.getNbIo () + io1_.getNbIo (); } /// Récupère une entrée/sortie par son nom. int GpioConcat::getByName (const std::string &name) const { int n = io0_.getByName (name); return n == -1 ? io1_.getByName (name) + nSep_ : n; }