DUDS
Distributed Update of Data from Something
PinConfiguration.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2018 Jeff Jackowski
9  */
15 #include <boost/property_tree/ptree.hpp>
16 #include <cstdlib>
17 
18 namespace duds { namespace hardware { namespace interface {
19 
20 PinConfiguration::Pin::Pin() : parent(nullptr) { }
21 
23  const std::pair<const std::string, boost::property_tree::ptree> &item,
24  Port *owner
25 ) {
26  parse(item, owner);
27 }
28 
29 static unsigned int ParsePinId(const std::string &str) {
30  // check for "none"
31  if (str == "none") {
32  // explicitly no pin
34  }
35  // parse as a number; may be global or port ID
36  std::istringstream iss(str);
37  unsigned int ui;
38  iss >> ui;
39  // got something?
40  if (!iss.fail()) {
41  return ui;
42  }
43  // no real clue
45 }
46 
48  const boost::property_tree::ptree::value_type &item,
49  Port *owner
50 ) {
51  // read in key for port ID
52  pid = ParsePinId(item.first);
53  // read optional modified ID
54  std::string val = item.second.get_value<std::string>();
55  if (!val.empty()) {
56  gid = ParsePinId(val);
57  } else {
58  gid = pid + owner->idOffset;
59  }
60  // a name is in a child node
61  if (!item.second.empty()) {
62  name = item.second.front().first;
63  }
64  parent = owner;
65 }
66 
67 PinConfiguration::Port::Port() : idOffset(0) { }
68 
70  const boost::property_tree::ptree::value_type &item
71 ) {
72  typeval = item.second.get_value<std::string>();
73  try {
74  for (auto const &subitem : item.second) {
75  if (subitem.first == "idoffset") {
76  idOffset = subitem.second.get_value<unsigned int>();
77  } else {
78  // parse the pin data; may throw; then store it
79  std::pair<
80  PinConfiguration::Pins::index<index_gid>::type::iterator,
81  bool
82  > npin =
83  pins.insert(PinConfiguration::Pin(subitem, this));
84  // global ID must not be less than the port's ID offset
85  if (npin.first->gid < idOffset) {
87  PortName(item.first) <<
88  PortPinId(npin.first->gid)
89  );
90  }
91  if (npin.first->pid < idOffset) {
93  PortName(item.first) <<
94  PortPinId(npin.first->pid)
95  );
96  }
97  }
98  }
99  } catch (boost::exception &be) {
100  be << PortName(item.first);
101  throw;
102  }
103 
104  // check for duplicate IDs
105  unsigned int last = -1;
106  for (auto &gpin : gidIndex()) {
107  if (last == gpin.gid) {
109  PortName(item.first) << PortPinId(last)
110  );
111  }
112  last = gpin.gid;
113  }
114 }
115 
117  const std::string &str
118 ) const {
119  std::istringstream iss(str);
120  unsigned int ui;
121  iss >> ui;
122  // got nothing?
123  if (iss.fail()) {
124  // lookup name
125  const PinConfiguration::Pins::index<index_name>::type &nameidx =
126  allpins.get<index_name>();
127  auto pi = nameidx.find(str);
128  // check for non-existing pin
129  if (pi == nameidx.end()) {
131  }
132  // found it
133  return *pi;
134  }
135  // lookup GID to ensure it exists
136  const PinConfiguration::Pins::index<index_gid>::type &gididx =
137  allpins.get<index_gid>();
138  auto gi = gididx.find(ui);
139  if (gi == gididx.end()) {
141  }
142  return *gi;
143 }
144 
146 usePort(nullptr), type(Unknown), selStates(0) { }
147 
148 static bool ParseState(const std::string &val) {
149  if ((val == "0") || (val == "low")) {
150  return false;
151  } else if ((val == "1") || (val == "high")) {
152  return true;
153  }
154  // bad input
156 }
157 
159  const boost::property_tree::ptree::value_type &item,
160  const PinConfiguration *pinconf
161 ) : usePort(nullptr), selStates(0) {
162  { // parse type string
163  std::string typestr = item.second.get_value<std::string>();
164  if (typestr == "Binary") {
165  type = Binary;
166  } else if (typestr == "Multiplexer") {
167  type = Multiplexer;
168  } else if (typestr == "Pin") {
169  type = Pin;
170  } else if (typestr == "PinSet") {
171  type = PinSet;
172  } else {
173  // type affects parsing, so this must be an error
175  SelectBadType(typestr)
176  );
177  }
178  }
179  // parse based on chip select type
180  switch (type) {
181  case Binary: {
182  // find pin to use
183  std::string pid = item.second.get<std::string>("pin");
184  pins.reserve(1);
185  const PinConfiguration::Pin &p = pinconf->pin(pid);
186  usePort = p.parent;
187  pins.push_back(p.gid);
188  // parse the two select states and check for duplicates
189  std::string low(item.second.get<std::string>("low", ""));
190  if (!low.empty() && pinconf->haveChipSelect(low)) {
192  SelectName(low)
193  );
194  }
195  std::string high(item.second.get<std::string>("high", ""));
196  if (!high.empty() && (pinconf->haveChipSelect(high) || (high == low))) {
198  SelectName(high)
199  );
200  }
201  // parse initial state
202  initSelHigh = ParseState(item.second.get<std::string>("init", "0"));
203  // store data
204  if (!low.empty()) {
205  selNames[low] = 0;
206  }
207  if (!high.empty()) {
208  selNames[high] = 1;
209  }
210  }
211  break;
212  case Multiplexer: {
213  boost::property_tree::ptree::const_assoc_iterator piter =
214  item.second.find("pins");
215  // check for missing pins subtree
216  if (piter == item.second.not_found()) {
217  // the subtree is required
219  }
220  // inspect the pins subtree
221  for (auto const &pinitem : piter->second) {
222  // get the item's value
223  std::string pn = pinitem.second.get_value<std::string>();
224  // may have been ommitted
225  if (pn.empty()) {
226  // use the item's key instead
227  pn = pinitem.first;
228  }
229  // find the pin
230  const PinConfiguration::Pin &p = pinconf->pin(pn);
231  // port check
232  if (!usePort) {
233  usePort = p.parent;
234  } else if (usePort != p.parent) {
236  PortPinId(p.gid) << PinBadId(pn) // << port name(s) ??
237  );
238  }
239  // store pin
240  pins.push_back(p.gid);
241  }
242  // must have pin(s)
243  if (pins.empty()) {
245  }
246  // inspect the select
247  piter = item.second.find("selects");
248  // if "selects" is found . . .
249  if (piter != item.second.not_found()) {
250  // . . . iterate over its children
251  for (auto const &selitem : piter->second) {
252  // check for duplicates
253  if (selNames.count(selitem.first) ||
254  pinconf->haveChipSelect(selitem.first)
255  ) {
257  SelectName(selitem.first)
258  );
259  }
260  // store it
261  selNames[selitem.first] = selitem.second.get_value<unsigned int>();
262  }
263  }
264  }
265  break;
266  case Pin: {
267  // find optional name
268  std::string name = item.second.get<std::string>("name", "");
269  if (!name.empty()) {
270  // check for duplicates
271  if (pinconf->haveChipSelect(name)) {
273  SelectName(name)
274  );
275  }
276  // store name
277  selNames[name] = 1;
278  }
279  // parse the pin data
280  pins.reserve(1);
281  const PinConfiguration::Pin &p = pinconf->pin(
282  item.second.get<std::string>("pin")
283  );
284  usePort = p.parent;
285  pins.push_back(p.gid);
286  initSelHigh = ParseState(item.second.get<std::string>("select", "0"));
287  }
288  break;
289  case PinSet: {
290  // inspect the selections
291  int spot = 0;
292  for (auto const &selitem : item.second) {
293  // check for duplicates
294  if (selNames.count(selitem.first) ||
295  pinconf->haveChipSelect(selitem.first)
296  ) {
298  SelectName(selitem.first)
299  );
300  }
301  // get the pin name to use
302  std::string pn = selitem.second.get_value<std::string>();
303  // may be in a subtree
304  if (pn.empty()) {
305  pn = selitem.second.get<std::string>("pin", selitem.first);
306  // can also specify a non-default select state
307  bool sstate = ParseState(
308  selitem.second.get<std::string>("select", "0")
309  );
310  if (sstate) {
311  selStates |= 1 << spot;
312  }
313  }
314  // find the pin
315  const PinConfiguration::Pin &p = pinconf->pin(pn);
316  // port check
317  if (!usePort) {
318  usePort = p.parent;
319  } else if (usePort != p.parent) {
321  PortPinId(p.gid) << PinBadId(pn) // << port name(s) ??
322  );
323  }
324  // store pin
325  pins.push_back(p.gid);
326  // store select
327  selNames[selitem.first] = spot;
328  ++spot;
329  }
330  // must have pin(s)
331  if (pins.empty()) {
333  }
334  }
335  }
336 }
337 
338 PinConfiguration::ChipSel::ChipSel(SelMgr *m, int id) : mgr(m), chipId(id) { }
339 
341  const boost::property_tree::ptree::value_type &item,
342  const PinConfiguration *pinconf
343 ) : usePort(nullptr) {
344  // check for pins select line
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;
350  // iterate over pins
351  for (auto const &pinitem : pinlevel) {
352  Pin pin;
353  // get the item's value
354  std::string pn = pinitem.second.get_value<std::string>();
355  // may have been ommitted
356  if (pn.empty()) {
357  // use the item's key instead
358  pn = pinitem.first;
359  } else {
360  // the key is the name
361  pin.name = pinitem.first;
362  }
363  // find the pin
364  const PinConfiguration::Pin &p = pinconf->pin(pn);
365  // port check
366  if (!usePort) {
367  usePort = p.parent;
368  } else if (usePort != p.parent) {
370  PortPinId(p.gid) << PinBadId(pn) // << port name(s) ??
371  );
372  }
373  // finalize data using found pin
374  pin.parent = usePort;
375  pin.gid = p.gid;
376  pin.pid = p.pid; // probably not useful, but copy anyway
377  // store pin
378  pins.insert(std::move(pin));
379  }
380  assert(pins.size() == pinlevel.size());
381  assert(usePort);
382  if (!toplevelpins) {
383  // check for optional select line
384  selName = item.second.get<std::string>("select", "");
385  // see if it is specified, but does not exist
386  if (!selName.empty() && !pinconf->haveChipSelect(selName)) {
388  SelectName(selName)
389  );
390  }
391  }
392 }
393 
394 PinConfiguration::PinConfiguration(const boost::property_tree::ptree &pt) {
395  parse(pt);
396 }
397 
398 void PinConfiguration::parse(const boost::property_tree::ptree &pt) {
399  // parse the ports section
400  boost::property_tree::ptree::const_assoc_iterator citer = pt.find("ports");
401  if (citer != pt.not_found()) {
402  Pins::index<index_seq>::type &seqidx = allpins.get<index_seq>();
403  for (auto const &subtree : citer->second) {
404  // check for a repeated name
405  if (ports.count(subtree.first)) {
407  PortName(subtree.first)
408  );
409  }
410  // parse and store port data
411  Port &port = ports[subtree.first];
412  port.parse(subtree);
413  // populate all pins
414  Pins::index<index_seq>::type &seqpin =
415  port.pins.get<index_seq>();
416  seqidx.insert(seqidx.end(), seqpin.begin(), seqpin.end());
417  }
418  }
419  // parse the selects section
420  citer = pt.find("selects");
421  if (citer != pt.not_found()) {
422  for (auto const &subtree : citer->second) {
423  // check for a repeated name
424  if (selMgrs.count(subtree.first)) {
426  SelectManagerName(subtree.first)
427  );
428  }
429  // ensure all errors include select manager name
430  try {
431  // parse and store port data
432  std::pair<SelMgrMap::iterator, bool> itbo = selMgrs.emplace(
433  SelMgrMap::value_type(subtree.first, SelMgr(subtree, this))
434  );
435  // maintain all chip selects in this object
436  for (auto &sni : itbo.first->second.selNames) {
437  chipSels[sni.first] = ChipSel(
438  &(itbo.first->second), sni.second
439  );
440  }
441  } catch (boost::exception &be) {
442  be << SelectManagerName(subtree.first);
443  throw;
444  }
445  }
446  }
447  // parse the sets section
448  citer = pt.find("sets");
449  if (citer != pt.not_found()) {
450  for (auto const &subtree : citer->second) {
451  // check for a repeated name
452  if (pinSets.count(subtree.first)) {
454  SetName(subtree.first)
455  );
456  }
457  // ensure all errors include pin set name
458  try {
459  // parse and store port data
460  std::pair<PinSetMap::iterator, bool> itbo = pinSets.emplace(
461  PinSetMap::value_type(subtree.first, PinSet(subtree, this))
462  );
463  } catch (boost::exception &be) {
464  be << SetName(subtree.first);
465  throw;
466  }
467  }
468  }
469 }
470 
472  const std::shared_ptr<DigitalPort> &dp,
473  const std::string &name
474 ) {
475  // no port?
476  if (!dp) {
478  }
479  // check for named port not in the parsed config data
480  if (!ports.count(name)) {
482  PortName(name)
483  );
484  }
485  Port &port = ports[name];
486  Port *dbgPort = &(ports[name]);
487  assert(dbgPort == &port);
488  // check for a compatible set of pins (really just exist or not)
489  Pins::index<index_gid>::type &gididx = port.pins.get<index_gid>();
490  for (auto const &pin : gididx) {
491  // must not be present, but is?
492  if ((pin.pid == Pin::NoPin) && dp->exists(pin.gid)) {
494  PortName(name) << PinErrorId(pin.gid)
495  );
496  }
497  // must be present, but isn't?
498  else if ((pin.pid != Pin::NoPin) && !dp->exists(pin.gid)) {
500  PortName(name) << PinErrorId(pin.gid)
501  );
502  }
503  // if running here, must be ok so far
504  }
505  // attempt to create select managers and their select objects
506  for (auto &mgr : selMgrs) {
507  // skip if wrong port
508  if (mgr.second.usePort != &port) {
509  continue;
510  }
511  assert(!mgr.second.csm); // shouldn't already exist
512  assert(!mgr.second.pins.empty());
513  assert(
514  (mgr.second.type == SelMgr::Multiplexer) ||
515  (mgr.second.type == SelMgr::PinSet) ||
516  (mgr.second.pins.size() == 1)
517  );
518  // make the manager object and give it an access object from the port
519  switch (mgr.second.type) {
520  case SelMgr::Binary:
521  mgr.second.csm = std::make_shared<ChipBinarySelectManager>(
522  dp->access(mgr.second.pins.front()), mgr.second.initSelHigh
523  );
524  break;
525  case SelMgr::Multiplexer:
526  mgr.second.csm = std::make_shared<ChipMultiplexerSelectManager>(
527  dp->access(mgr.second.pins)
528  );
529  break;
530  case SelMgr::Pin:
531  mgr.second.csm = std::make_shared<ChipPinSelectManager>(
532  dp->access(mgr.second.pins.front()),
533  mgr.second.initSelHigh ?
536  );
537  break;
538  case SelMgr::PinSet:
539  mgr.second.csm = std::make_shared<ChipPinSetSelectManager>(
540  dp->access(mgr.second.pins),
541  mgr.second.selStates
542  );
543  break;
544  default:
545  // !!!! corrupt data
546  abort();
547  }
548  // create any chip selects
549  for (auto const &sel : mgr.second.selNames) {
550  ChipSel &cs = chipSels[sel.first];
551  assert(cs.chipId == sel.second);
552  cs.sel.modify(mgr.second.csm, sel.second);
553  }
554  }
555  // attempt to create pin set objects
556  for (auto &pset : pinSets) {
557  // skip if wrong port
558  if (pset.second.usePort != &port) {
559  continue;
560  }
561  // put pin IDs in a vector
562  std::vector<unsigned int> pvec;
563  pvec.reserve(pset.second.pins.size());
564  for (auto const &pin : pset.second.seqIndex()) {
565  assert(pin.parent == &port);
566  pvec.push_back(pin.gid);
567  }
568  // make the set
569  pset.second.dpSet = DigitalPinSet(dp, std::move(pvec));
570  }
571  // store port for later reference
572  port.dport = dp;
573 }
574 
576  const std::string &name
577 ) const {
578  PortMap::const_iterator iter = ports.find(name);
579  if (iter == ports.end()) {
581  PortName(name)
582  );
583  }
584  return iter->second;
585 }
586 
588  const std::string &name
589 ) const {
590  PinSetMap::const_iterator iter = pinSets.find(name);
591  if (iter == pinSets.end()) {
593  SetName(name)
594  );
595  }
596  return iter->second;
597 }
598 
600  const std::string &name
601 ) const {
602  ChipSelMap::const_iterator iter = chipSels.find(name);
603  if (iter == chipSels.end()) {
605  SelectName(name)
606  );
607  }
608  return iter->second;
609 }
610 
612  const std::string &name
613 ) const {
614  SelMgrMap::const_iterator iter = selMgrs.find(name);
615  if (iter == selMgrs.end()) {
617  SelectManagerName(name)
618  );
619  }
620  return iter->second;
621 }
622 
624  DigitalPinSet &dpset,
625  ChipSelect &sel,
626  const std::string &setName
627 ) const {
628  PinSetMap::const_iterator piter = pinSets.find(setName);
629  if (piter == pinSets.end()) {
631  }
632  if (!piter->second.dpSet.havePins()) {
634  }
635  dpset = piter->second.dpSet;
636  if (piter->second.selName.empty()) {
637  sel.reset();
638  } else {
639  ChipSelMap::const_iterator siter = chipSels.find(piter->second.selName);
640  if (siter == chipSels.end()) {
642  SelectName(piter->second.selName)
643  );
644  }
645  if (!siter->second.sel.haveManager()) {
647  SelectName(piter->second.selName)
648  );
649  }
650  sel = siter->second.sel;
651  }
652 }
653 
655  const std::string &setName
656 ) const {
657  PinSetMap::const_iterator piter = pinSets.find(setName);
658  if (piter == pinSets.end()) {
660  }
661  if (!piter->second.dpSet.havePins()) {
663  }
664  return piter->second.dpSet;
665 }
666 
668  const std::string &selName
669 ) const {
670  ChipSelMap::const_iterator siter = chipSels.find(selName);
671  if (siter == chipSels.end()) {
673  }
674  if (!siter->second.sel.haveManager()) {
676  }
677  return siter->second.sel;
678 }
679 
681  const std::string &pinName
682 ) const {
683  const PinConfiguration::Pins::index<index_name>::type &nidx =
684  allpins.get<index_name>();
685  PinConfiguration::Pins::index<index_name>::type::iterator niter =
686  nidx.find(pinName);
687  if (niter == nidx.end()) {
689  }
690  if (!niter->parent || !niter->parent->dport) {
692  }
693  return DigitalPin(niter->parent->dport, niter->gid);
694 }
695 
697  DigitalPin &dest,
698  const std::string &pinName
699 ) const {
700  const PinConfiguration::Pins::index<index_name>::type &nidx =
701  allpins.get<index_name>();
702  PinConfiguration::Pins::index<index_name>::type::iterator niter =
703  nidx.find(pinName);
704  if ((niter == nidx.end()) || !niter->parent || !niter->parent->dport) {
705  dest.reset();
706  return false;
707  }
708  dest = DigitalPin(niter->parent->dport, niter->gid);
709  return true;
710 }
711 
713  const std::string &pinName
714 ) const {
715  const PinConfiguration::Pins::index<index_name>::type &nidx =
716  allpins.get<index_name>();
717  PinConfiguration::Pins::index<index_name>::type::iterator niter =
718  nidx.find(pinName);
719  return (niter != nidx.end()) && niter->parent && !niter->parent->dport;
720 }
721 
722 } } }
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&#39;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&#39;t drive the line if the output ty...
Represents a single pin on a DigitalPort.
Definition: DigitalPin.hpp:22
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.
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.
A given pin ID cannot be used with the port, such as an ID that is less than the port&#39;s ID offset...
void modify(const std::shared_ptr< ChipSelectManager > &csm, int chipId)
Changes the manager and chip to select.
Definition: ChipSelect.cpp:64
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.
Definition: PinErrors.hpp:97
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 ...
Definition: ChipSelect.hpp:24
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.
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.
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...
Definition: ChipSelect.cpp:92
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::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...
Definition: Errors.hpp:48
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&#39;t drive the line if the output t...