15 #include <boost/property_tree/ptree.hpp> 18 namespace duds {
namespace hardware {
namespace interface {
23 const std::pair<const std::string, boost::property_tree::ptree> &item,
36 std::istringstream iss(str);
48 const boost::property_tree::ptree::value_type &item,
54 std::string val = item.second.get_value<std::string>();
61 if (!item.second.empty()) {
62 name = item.second.front().first;
70 const boost::property_tree::ptree::value_type &item
72 typeval = item.second.get_value<std::string>();
74 for (
auto const &subitem : item.second) {
75 if (subitem.first ==
"idoffset") {
76 idOffset = subitem.second.get_value<
unsigned int>();
80 PinConfiguration::Pins::index<index_gid>::type::iterator,
99 }
catch (boost::exception &be) {
105 unsigned int last = -1;
107 if (last == gpin.gid) {
117 const std::string &str
119 std::istringstream iss(str);
125 const PinConfiguration::Pins::index<index_name>::type &nameidx =
127 auto pi = nameidx.find(str);
129 if (pi == nameidx.end()) {
136 const PinConfiguration::Pins::index<index_gid>::type &gididx =
138 auto gi = gididx.find(ui);
139 if (gi == gididx.end()) {
146 usePort(nullptr), type(Unknown), selStates(0) { }
149 if ((val ==
"0") || (val ==
"low")) {
151 }
else if ((val ==
"1") || (val ==
"high")) {
159 const boost::property_tree::ptree::value_type &item,
163 std::string typestr = item.second.get_value<std::string>();
164 if (typestr ==
"Binary") {
166 }
else if (typestr ==
"Multiplexer") {
168 }
else if (typestr ==
"Pin") {
170 }
else if (typestr ==
"PinSet") {
183 std::string pid = item.second.get<std::string>(
"pin");
189 std::string low(item.second.get<std::string>(
"low",
""));
195 std::string high(item.second.get<std::string>(
"high",
""));
196 if (!high.empty() && (pinconf->
haveChipSelect(high) || (high == low))) {
213 boost::property_tree::ptree::const_assoc_iterator piter =
214 item.second.find(
"pins");
216 if (piter == item.second.not_found()) {
221 for (
auto const &pinitem : piter->second) {
223 std::string pn = pinitem.second.get_value<std::string>();
247 piter = item.second.find(
"selects");
249 if (piter != item.second.not_found()) {
251 for (
auto const &selitem : piter->second) {
253 if (
selNames.count(selitem.first) ||
261 selNames[selitem.first] = selitem.second.get_value<
unsigned int>();
268 std::string name = item.second.get<std::string>(
"name",
"");
282 item.second.get<std::string>(
"pin")
292 for (
auto const &selitem : item.second) {
294 if (
selNames.count(selitem.first) ||
302 std::string pn = selitem.second.get_value<std::string>();
305 pn = selitem.second.get<std::string>(
"pin", selitem.first);
308 selitem.second.get<std::string>(
"select",
"0")
341 const boost::property_tree::ptree::value_type &item,
343 ) : usePort(
nullptr) {
345 boost::property_tree::ptree::const_assoc_iterator piter =
346 item.second.find(
"pins");
347 bool toplevelpins = piter == item.second.not_found();
348 const boost::property_tree::ptree &pinlevel =
349 toplevelpins ? item.second : piter->second;
351 for (
auto const &pinitem : pinlevel) {
354 std::string pn = pinitem.second.get_value<std::string>();
361 pin.
name = pinitem.first;
368 }
else if (usePort != p.
parent) {
380 assert(pins.size() == pinlevel.size());
384 selName = item.second.get<std::string>(
"select",
"");
400 boost::property_tree::ptree::const_assoc_iterator citer = pt.find(
"ports");
401 if (citer != pt.not_found()) {
403 for (
auto const &subtree : citer->second) {
405 if (
ports.count(subtree.first)) {
414 Pins::index<index_seq>::type &seqpin =
416 seqidx.insert(seqidx.end(), seqpin.begin(), seqpin.end());
420 citer = pt.find(
"selects");
421 if (citer != pt.not_found()) {
422 for (
auto const &subtree : citer->second) {
424 if (
selMgrs.count(subtree.first)) {
432 std::pair<SelMgrMap::iterator, bool> itbo =
selMgrs.emplace(
433 SelMgrMap::value_type(subtree.first,
SelMgr(subtree,
this))
436 for (
auto &sni : itbo.first->second.selNames) {
438 &(itbo.first->second), sni.second
441 }
catch (boost::exception &be) {
448 citer = pt.find(
"sets");
449 if (citer != pt.not_found()) {
450 for (
auto const &subtree : citer->second) {
452 if (
pinSets.count(subtree.first)) {
460 std::pair<PinSetMap::iterator, bool> itbo =
pinSets.emplace(
461 PinSetMap::value_type(subtree.first,
PinSet(subtree,
this))
463 }
catch (boost::exception &be) {
472 const std::shared_ptr<DigitalPort> &dp,
473 const std::string &name
480 if (!
ports.count(name)) {
487 assert(dbgPort == &port);
489 Pins::index<index_gid>::type &gididx = port.
pins.get<
index_gid>();
490 for (
auto const &
pin : gididx) {
512 assert(!
mgr.second.
pins.empty());
521 mgr.second.
csm = std::make_shared<ChipBinarySelectManager>(
526 mgr.second.
csm = std::make_shared<ChipMultiplexerSelectManager>(
531 mgr.second.
csm = std::make_shared<ChipPinSelectManager>(
532 dp->access(
mgr.second.
pins.front()),
539 mgr.second.
csm = std::make_shared<ChipPinSetSelectManager>(
558 if (pset.second.usePort != &port) {
562 std::vector<unsigned int> pvec;
563 pvec.reserve(pset.second.pins.size());
564 for (
auto const &
pin : pset.second.seqIndex()) {
576 const std::string &name
578 PortMap::const_iterator iter =
ports.find(name);
579 if (iter ==
ports.end()) {
588 const std::string &name
590 PinSetMap::const_iterator iter =
pinSets.find(name);
600 const std::string &name
602 ChipSelMap::const_iterator iter =
chipSels.find(name);
612 const std::string &name
614 SelMgrMap::const_iterator iter =
selMgrs.find(name);
626 const std::string &setName
628 PinSetMap::const_iterator piter =
pinSets.find(setName);
632 if (!piter->second.dpSet.havePins()) {
635 dpset = piter->second.dpSet;
636 if (piter->second.selName.empty()) {
639 ChipSelMap::const_iterator siter =
chipSels.find(piter->second.selName);
645 if (!siter->second.sel.haveManager()) {
650 sel = siter->second.sel;
655 const std::string &setName
657 PinSetMap::const_iterator piter =
pinSets.find(setName);
661 if (!piter->second.dpSet.havePins()) {
664 return piter->second.dpSet;
668 const std::string &selName
670 ChipSelMap::const_iterator siter =
chipSels.find(selName);
674 if (!siter->second.sel.haveManager()) {
677 return siter->second.sel;
681 const std::string &pinName
683 const PinConfiguration::Pins::index<index_name>::type &nidx =
685 PinConfiguration::Pins::index<index_name>::type::iterator niter =
687 if (niter == nidx.end()) {
690 if (!niter->parent || !niter->parent->dport) {
693 return DigitalPin(niter->parent->dport, niter->gid);
698 const std::string &pinName
700 const PinConfiguration::Pins::index<index_name>::type &nidx =
702 PinConfiguration::Pins::index<index_name>::type::iterator niter =
704 if ((niter == nidx.end()) || !niter->parent || !niter->parent->dport) {
708 dest =
DigitalPin(niter->parent->dport, niter->gid);
713 const std::string &pinName
715 const PinConfiguration::Pins::index<index_name>::type &nidx =
717 PinConfiguration::Pins::index<index_name>::type::iterator niter =
719 return (niter != nidx.end()) && niter->parent && !niter->parent->dport;
PinConfiguration()=default
Make an empty configuration.
boost::error_info< struct Info_PortId, std::string > PinBadId
A pin name or number from the configuration that could not be used.
const PinConfiguration::Pins::index< index_gid >::type & gidIndex() const
Convenience function that provides the pin global ID index for the port's pins.
PortMap ports
Port configurations stored by name.
Holds configuration data for a single chip select manager.
Indicates the chip is selected when the pin is driven low, or doesn't drive the line if the output ty...
Represents a single pin on a DigitalPort.
A required DigitalPort object was not supplied.
boost::error_info< struct Info_PortPinId, unsigned int > PortPinId
The global ID of a pin from a configuration that is involved in the error.
A pin set was defined with pins from more than one port.
A required chip select manager has not yet been created most likely because the port providing its pi...
std::uint32_t selStates
Selection state bitmap for pin set manager.
unsigned int idOffset
The pin ID offset for the port; used to translate between global and port pin IDs.
A selection logic state in the configuration could not be parsed.
ChipSelect sel
The chip select object for this configuration.
PinSetMap pinSets
Pin set configurations stored by name.
unsigned int gid
Assigned global ID.
int chipId
The chip ID that is selected by this chip select.
Port * usePort
The port that will provide the pins for this select manager.
Holds configuration data for a single digital port.
boost::error_info< struct Info_SetName, std::string > SetName
The name of a pin set from a configuration.
A required pin set has not yet been created most likely because the port providing its pins has not y...
bool haveChipSelect(const std::string &name) const
True if the named chip select has been found in the already parsed configuration. ...
const PinSet & pinSet(const std::string &name) const
Finds the configuration data for the named DigitalPinSet.
Use ChipMultiplexerSelectManager.
A given pin ID cannot be used with the port, such as an ID that is less than the port's ID offset...
void modify(const std::shared_ptr< ChipSelectManager > &csm, int chipId)
Changes the manager and chip to select.
move_impl move(unsigned int c, unsigned int r)
Display stream manipulator that moves the display cursor to the given location.
std::shared_ptr< DigitalPort > dport
The attached DigitalPort.
SelMgrMap selMgrs
Select manager configurations stored by name.
Pins pins
The pins described by the configuration file.
MgrType type
The type of chip select manager requested.
const ChipSel & chipSelect(const std::string &name) const
Finds the configuration data for the named ChipSelect.
boost::error_info< struct Info_PinId, unsigned int > PinErrorId
The pin global ID involved in the error.
Use ChipPinSetSelectManager.
static unsigned int ParsePinId(const std::string &str)
Index in type Pins that is maintained by parsing order.
void reset()
Resets the shared pointer to the DigitalPort so that this object no longer represents a pin...
The configuration gives the same name to more than one chip select.
boost::error_info< struct Info_SelectBadState, std::string > SelectBadState
The string with a select logic state that could not be parsed.
std::string typeval
A hint as to what DigitalPort implementation should be used.
The configuration gives the same name to more than one chip select manager.
An object to wrap together a ChipSelectManager and chip ID to simplify code that needs to repeatedly ...
static bool ParseState(const std::string &val)
boost::error_info< struct Info_PortName, std::string > PortName
The name of the port as it appears in the configuration.
const Pin & pin(const std::string &str) const
Finds the pin from the given name or global ID according to this pin configuration.
void parse(const std::pair< const std::string, boost::property_tree::ptree > &item)
bool initSelHigh
True for high selection state with binary manager, or for initially selected state with pin manager...
Index in type Pins that is sorted by the optional pin name.
A chip selection manager was defined with pins from more than one port.
Port * parent
The Port object that supplies the pin.
bool havePin(const std::string &pinName) const
Returns true if the named pin is in the configuration.
The provided DigitalPort object lacks a required pin.
ChipSelMap chipSels
Chip select configurations stored by name.
Represents a set of pins on a single DigitalPort.
void attachPort(const std::shared_ptr< DigitalPort > &dp, const std::string &name="default")
Attaches the given DigitalPort to the named port in the configuration.
const ChipSelect & getSelect(const std::string &selName) const
Gets the ChipSelect object named in the configuration.
The configuration gives the same name to more than one port.
A select manager was given an unknown type, or no type.
Use ChipPinSelectManager.
std::shared_ptr< ChipSelectManager > csm
The select manager based on this configuration.
Parses configuration data for DigitalPort, DigitalPin, DigitalPinSet, ChipSelectManager, and ChipSelect objects.
const Port & port(const std::string &name="default") const
Finds the configuration data for the named DigitalPort.
void getPinSetAndSelect(DigitalPinSet &dpset, ChipSelect &sel, const std::string &setName) const
Gets the DigitalPinSet and ChipSelect objects that are attached to the named set configuration.
Index in type Pins that is sorted by pin global ID.
The provided DigitalPort object has a pin it is explicitly required to not have.
Use ChipBinarySelectManager.
A chip selection manager was defined without any pins.
The same pin global ID is used for more than one pin.
SelMgr * mgr
The chip select manager configuration for this object.
void parse(const std::pair< const std::string, boost::property_tree::ptree > &item, Port *owner)
Parse pin subtree data stored in a property tree.
Holds configuration data for a single digital I/O pin.
DigitalPin getPin(const std::string &pinName) const
Makes a DigitalPin object for the named pin in the configuration.
void reset() noexcept
Returns the object to the default constructed state of not having a manager or a valid chip ID...
static constexpr unsigned int NoPin
There is explicitly no pin connected to the corresponding global ID.
boost::error_info< struct Info_SelectManagerName, std::string > SelectManagerName
The name of a chip select manager from a configuration.
const DigitalPinSet & getPinSet(const std::string &setName) const
Gets the DigitalPinSet object named in the configuration.
std::string name
Optional pin name.
std::unordered_map< std::string, unsigned int > selNames
A mapping of a name for a chip select to the chip ID used by the select manager.
The requested chip select does not exist.
The requested chip select manager is not named in the configuration.
Holds configuration data for a single chip select.
boost::error_info< struct Info_SelectBadType, std::string > SelectBadType
The string with a chip selection manager type that is not valid.
Pins allpins
All pins mentioned in the confiuration across all ports.
Holds configuration data for a single digital pin set.
The configuration gives the same name to more than one pin set.
A given pin ID could not be parsed.
The requested pin set is not defined by the configuration.
boost::error_info< struct Info_SelectName, std::string > SelectName
The name of a chip select from a configuration.
std::vector< unsigned int > pins
The global IDs of the pins that this select manager should use.
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
void parse(const boost::property_tree::ptree &pt)
Parses the pin configuration that starts at the given subtree.
The requested port is not named in the configuration.
const SelMgr & selectManager(const std::string &name) const
Finds the configuration data for the named ChipSelectManager.
Indicates the chip is selected when the pin is driven high, or doesn't drive the line if the output t...