Revision: 7968
http://playerstage.svn.sourceforge.net/playerstage/?rev=7968&view=rev
Author: gbiggs
Date: 2009-07-10 00:36:53 +0000 (Fri, 10 Jul 2009)
Log Message:
-----------
Applied patch #2816667
Modified Paths:
--------------
code/player/trunk/server/drivers/dio/CMakeLists.txt
Added Paths:
-----------
code/player/trunk/server/drivers/dio/bitlogic/
code/player/trunk/server/drivers/dio/bitlogic/CMakeLists.txt
code/player/trunk/server/drivers/dio/bitlogic/bitlogic.cc
Modified: code/player/trunk/server/drivers/dio/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/dio/CMakeLists.txt 2009-07-10 00:34:17 UTC
(rev 7967)
+++ code/player/trunk/server/drivers/dio/CMakeLists.txt 2009-07-10 00:36:53 UTC
(rev 7968)
@@ -1,2 +1,2 @@
+ADD_SUBDIRECTORY (bitlogic)
ADD_SUBDIRECTORY (serio)
-
Added: code/player/trunk/server/drivers/dio/bitlogic/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/dio/bitlogic/CMakeLists.txt
(rev 0)
+++ code/player/trunk/server/drivers/dio/bitlogic/CMakeLists.txt
2009-07-10 00:36:53 UTC (rev 7968)
@@ -0,0 +1,2 @@
+PLAYERDRIVER_OPTION (bitlogic build_bitlogic ON)
+PLAYERDRIVER_ADD_DRIVER (bitlogic build_bitlogic SOURCES bitlogic.cc)
Added: code/player/trunk/server/drivers/dio/bitlogic/bitlogic.cc
===================================================================
--- code/player/trunk/server/drivers/dio/bitlogic/bitlogic.cc
(rev 0)
+++ code/player/trunk/server/drivers/dio/bitlogic/bitlogic.cc 2009-07-10
00:36:53 UTC (rev 7968)
@@ -0,0 +1,428 @@
+/*
+ * Player - One Hell of a Robot Server
+ * Copyright (C) 2004 Brian Gerkey [email protected]
+ *
+ * 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
+ *
+ */
+
+/*
+ *
+ * Bitwise logic functions for dio interface.
+ */
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_bitlogic bitlogic
+ * @brief Bitwise logic functions for dio interface.
+
+...@par Provides
+
+- @ref interface_dio
+
+...@par Requires
+
+- @ref interface_dio (optionally)
+ - If set, results are sent as commands
+
+...@par Configuration requests
+
+- None
+
+...@par Configuration file options
+
+- function (string)
+ - Default: "NONE"
+ - One of: "and", "or", "xor", "nand", "nor", "nxor" (case sensitive)
+- slots
+ - Default: 1
+ - Number of slots (greater than 0)
+- init_bits (string)
+ - Default: "00000000000000000000000000000000"
+ - Initial bits for each slot, last character is the lowest bit (length
greater than 0, max. 32 characters)
+- wait_for_all (integer)
+ - Default: 1
+ - If set to 1, this driver waits for data from all slots before issuing a
command to subscribed dio interface
+
+...@par Example
+
+...@verbatim
+driver
+(
+ name "bitlogic"
+ function "and"
+ slots 2
+ provides ["0:::dio:0" "1:::dio:1"]
+ init_bits "101"
+)
+...@endverbatim
+
+...@author Paul Osmialowski
+
+*/
+
+/** @} */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <libplayercore/playercore.h>
+
+#define MAX_SLOTS 16
+
+class Bitlogic : public Driver
+{
+ public:
+ Bitlogic(ConfigFile * cf, int section);
+ virtual ~Bitlogic();
+ virtual int Setup();
+ virtual int Shutdown();
+ virtual int Subscribe(player_devaddr_t addr);
+ virtual int ProcessMessage(QueuePointer & resp_queue,
+ player_msghdr * hdr,
+ void * data);
+ private:
+ uint32_t bits[MAX_SLOTS];
+ player_devaddr_t dio_provided_addrs[MAX_SLOTS];
+ player_devaddr_t dio_required_addr;
+ Device * dio_required_dev;
+ size_t slots;
+ uint32_t init_bits;
+ uint32_t init_count;
+ uint32_t count;
+ int cmd_mode;
+ enum { AND = 0, OR = 1, XOR = 2, NAND = 3, NOR = 4, NXOR = 5 } function;
+ int wait_for_all;
+ bool data_valid[MAX_SLOTS];
+ int ith;
+ int jth;
+ uint32_t compute() const throw (const char *);
+};
+
+Bitlogic::Bitlogic(ConfigFile * cf, int section) : Driver(cf, section, true,
PLAYER_MSGQUEUE_DEFAULT_MAXLEN)
+{
+ const char * _init_bits;
+ const char * fun;
+ char key[7];
+ int i;
+
+ memset(this->bits, 0, sizeof this->bits);
+ memset(this->dio_provided_addrs, 0, sizeof this->dio_provided_addrs);
+ memset(&(this->dio_required_addr), 0, sizeof(player_devaddr_t));
+ this->dio_required_dev = NULL;
+ this->slots = 0;
+ this->init_bits = 0;
+ this->init_count = 0;
+ this->count = 0;
+ this->cmd_mode = 0;
+ this->function = AND;
+ for (i = 0; i < MAX_SLOTS; i++) this->data_valid[i] = false;
+ this->ith = 0;
+ this->jth = 0;
+ if (cf->ReadDeviceAddr(&(this->dio_required_addr), section, "requires",
PLAYER_DIO_CODE, -1, NULL))
+ {
+ PLAYER_WARN("ignore \"missing field [requires]\" error message");
+ } else
+ {
+ this->cmd_mode = !0;
+ }
+ this->slots = static_cast<size_t>(cf->ReadInt(section, "slots", 1));
+ if ((!((this->slots) > 0)) || ((this->slots) > MAX_SLOTS))
+ {
+ PLAYER_ERROR("invalid number of slots");
+ this->SetError(-1);
+ return;
+ }
+ for (i = 0; i < static_cast<int>(this->slots); i++)
+ {
+ snprintf(key, sizeof key, "%d", i);
+ if (cf->ReadDeviceAddr(&(this->dio_provided_addrs[i]), section,
"provides", PLAYER_DIO_CODE, -1, key))
+ {
+ this->SetError(-1);
+ return;
+ }
+ if (this->AddInterface(this->dio_provided_addrs[i]))
+ {
+ this->SetError(-1);
+ return;
+ }
+ }
+ _init_bits = cf->ReadString(section, "init_bits",
"00000000000000000000000000000000");
+ if (!_init_bits)
+ {
+ this->SetError(-1);
+ return;
+ }
+ this->init_count = strlen(_init_bits);
+ if ((!((this->init_count) > 0)) || ((this->init_count) > 32))
+ {
+ PLAYER_ERROR("invalit length of init_bits string");
+ this->SetError(-1);
+ return;
+ }
+ this->count = this->init_count;
+ this->init_bits = 0;
+ for (i = 0; _init_bits[i]; i++)
+ {
+ if (i) ((this->init_bits) <<= 1);
+ switch(_init_bits[i])
+ {
+ case '0':
+ break;
+ case '1':
+ ((this->init_bits) |= 1);
+ break;
+ default:
+ PLAYER_ERROR("invalud init_bits string");
+ this->SetError(-1);
+ return;
+ }
+ }
+ fun = cf->ReadString(section, "function", "NONE");
+ if (!(strcmp(fun, "and")))
+ {
+ this->function = AND;
+ } else if (!(strcmp(fun, "or")))
+ {
+ this->function = OR;
+ } else if (!(strcmp(fun, "xor")))
+ {
+ this->function = XOR;
+ } else if (!(strcmp(fun, "namd")))
+ {
+ this->function = NAND;
+ } else if (!(strcmp(fun, "nor")))
+ {
+ this->function = NOR;
+ } else if (!(strcmp(fun, "nxor")))
+ {
+ this->function = NXOR;
+ } else
+ {
+ PLAYER_ERROR1("unknown function [%s]", fun);
+ this->SetError(-1);
+ return;
+ }
+ this->wait_for_all = cf->ReadInt(section, "wait_for_all", 1);
+}
+
+Bitlogic::~Bitlogic() { }
+
+int Bitlogic::Setup()
+{
+ int i;
+
+ this->count = this->init_count;
+ for (i = 0; i < MAX_SLOTS; i++) this->data_valid[i] = false;
+ this->ith = 0;
+ this->jth = 0;
+ for (i = 0; i < static_cast<int>(this->slots); i++)
+ {
+ this->bits[i] = this->init_bits;
+ if (this->cmd_mode)
+ {
+ if (Device::MatchDeviceAddress(this->dio_required_addr,
this->dio_provided_addrs[i]))
+ {
+ PLAYER_ERROR("attempt to subscribe to self");
+ return -1;
+ }
+ }
+ }
+ this->dio_required_dev = NULL;
+ if (this->cmd_mode)
+ {
+ this->dio_required_dev = deviceTable->GetDevice(this->dio_required_addr);
+ if (!(this->dio_required_dev))
+ {
+ PLAYER_ERROR("unable to locate suitable dio device");
+ return -1;
+ }
+ if (this->dio_required_dev->Subscribe(this->InQueue))
+ {
+ PLAYER_ERROR("unable to subscribe to dio device");
+ this->dio_required_dev = NULL;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int Bitlogic::Shutdown()
+{
+ if ((this->cmd_mode) && (this->dio_required_dev))
+ {
+ this->dio_required_dev->Unsubscribe(this->InQueue);
+ }
+ this->dio_required_dev = NULL;
+ return 0;
+}
+
+int Bitlogic::Subscribe(player_devaddr_t addr)
+{
+ player_dio_data_t dio_data;
+ int retval;
+
+ retval = this->Driver::Subscribe(addr);
+ if (retval) return retval;
+ if (!(this->cmd_mode))
+ {
+ memset(&dio_data, 0, sizeof dio_data);
+ dio_data.count = this->count;
+ try
+ {
+ dio_data.bits = this->compute();
+ } catch (const char * e)
+ {
+ PLAYER_ERROR1("%s", e);
+ return -1;
+ }
+ this->Publish(addr,
+ PLAYER_MSGTYPE_DATA, PLAYER_DIO_DATA_VALUES,
+ reinterpret_cast<void *>(&dio_data), 0, NULL, true); // copy
= true, do not dispose data placed on local stack!
+ }
+ return 0;
+}
+
+uint32_t Bitlogic::compute() const throw (const char *)
+{
+ uint32_t b;
+ int i;
+
+ b = this->bits[0];
+ for (i = 1; i < static_cast<int>(this->slots); i++)
+ {
+ switch (this->function)
+ {
+ case AND:
+ case NAND:
+ b &= this->bits[i];
+ break;
+ case OR:
+ case NOR:
+ b |= this->bits[i];
+ break;
+ case XOR:
+ case NXOR:
+ b ^= this->bits[i];
+ break;
+ default:
+ throw "unknown function";
+ }
+ }
+ switch (this->function)
+ {
+ case NAND:
+ case NOR:
+ case NXOR:
+ b = ~b;
+ default:
+ b = b; // prevents warnings
+ }
+ return b;
+}
+
+int Bitlogic::ProcessMessage(QueuePointer &resp_queue,
+ player_msghdr * hdr,
+ void * data)
+{
+ int i;
+ player_msghdr newhdr;
+ player_dio_cmd_t cmd;
+ player_dio_data_t dio_data;
+
+ if (!hdr) return -1;
+ if (this->cmd_mode)
+ {
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
+ -1, // -1 means 'all message subtypes'
+ this->dio_required_addr))
+ {
+ if (!data) return -1;
+ newhdr = *hdr;
+ newhdr.addr = this->dio_provided_addrs[this->ith];
+ this->Publish(&newhdr, data); // *data remains unchanged
+ this->ith++;
+ if ((this->ith) >= (static_cast<int>(this->slots)))
+ {
+ this->ith = 0;
+ }
+ return 0;
+ }
+ }
+ for (i = 0; i < static_cast<int>(this->slots); i++)
+ {
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD, PLAYER_DIO_CMD_VALUES,
this->dio_provided_addrs[i]))
+ {
+ if (!data) return -1;
+ cmd = *(reinterpret_cast<player_dio_cmd_t *>(data));
+ if ((cmd.count) > (this->count)) this->count = cmd.count;
+ this->bits[i] = cmd.digout;
+ this->data_valid[i] = true;
+ memset(&cmd, 0, sizeof cmd);
+ memset(&dio_data, 0, sizeof dio_data);
+ cmd.count = this->count;
+ try
+ {
+ cmd.digout = this->compute();
+ } catch (const char * e)
+ {
+ PLAYER_ERROR1("%s", e);
+ return -1;
+ }
+ dio_data.count = cmd.count;
+ dio_data.bits = cmd.digout;
+ if (this->cmd_mode)
+ {
+ for (i = 0; i < static_cast<int>(this->slots); i++) if
(!(this->data_valid[i])) break;
+ if ((!(this->wait_for_all)) || (i >= static_cast<int>(this->slots)))
+ {
+ this->dio_required_dev->PutMsg(this->InQueue, PLAYER_MSGTYPE_CMD,
PLAYER_DIO_CMD_VALUES, reinterpret_cast<void *>(&cmd), 0, NULL);
+ for (i = 0; i < static_cast<int>(this->slots); i++)
this->data_valid[i] = false;
+ }
+ } else
+ {
+ this->Publish(this->dio_provided_addrs[this->jth],
+ PLAYER_MSGTYPE_DATA, PLAYER_DIO_DATA_VALUES,
+ reinterpret_cast<void *>(&dio_data), 0, NULL, true); //
copy = true, do not dispose data placed on local stack!
+ this->jth++;
+ if ((this->jth) >= (static_cast<int>(this->slots)))
+ {
+ this->jth = 0;
+ }
+ }
+ return 0;
+ }
+ }
+ return -1;
+}
+
+// A factory creation function, declared outside of the class so that it
+// can be invoked without any object context (alternatively, you can
+// declare it static in the class). In this function, we create and return
+// (as a generic Driver*) a pointer to a new instance of this driver.
+Driver * Bitlogic_Init(ConfigFile * cf, int section)
+{
+ // Create and return a new instance of this driver
+ return reinterpret_cast<Driver *>(new Bitlogic(cf, section));
+}
+
+// A driver registration function, again declared outside of the class so
+// that it can be invoked without object context. In this function, we add
+// the driver into the given driver table, indicating which interface the
+// driver can support and how to create a driver instance.
+void bitlogic_Register(DriverTable * table)
+{
+ table->AddDriver("bitlogic", Bitlogic_Init);
+}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit