DUDS
Distributed Update of Data from Something
DigitalPortIndependentPins.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) 2017 Jeff Jackowski
9  */
11 
12 namespace duds { namespace hardware { namespace interface {
13 
15  return true;
16 }
17 
19  unsigned int,
20  const DigitalPinConfig &,
21  const DigitalPinConfig &
22 ) const {
23  return true;
24 }
25 
26 // may throw from DigitalPinCap::compatible()
28  const std::vector<unsigned int> &pvec,
29  std::vector<DigitalPinConfig> &propConf,
30  std::vector<DigitalPinConfig> &initConf,
31  std::function<void(DigitalPinRejectedConfiguration::Reason)> insertReason
32 ) const {
33  // inputs must match size, except initConf may be empty
34  if ((propConf.size() != pvec.size()) || (
35  !initConf.empty() && initConf.size() != pvec.size()
36  )) {
39  );
40  }
41  // put in inital values for the starting config if empty
42  if (initConf.empty()) {
43  initConf.insert(
44  initConf.begin(),
45  pvec.size(),
47  );
48  }
49  // iterate over the pins & config
50  std::vector<unsigned int>::const_iterator piter = pvec.cbegin();
51  std::vector<DigitalPinConfig>::iterator pConfIter = propConf.begin();
52  std::vector<DigitalPinConfig>::iterator iConfIter = initConf.begin();
53  bool good = true;
54  for (; piter != pvec.cend(); ++piter, ++pConfIter, ++iConfIter) {
57  // skip -1's
58  if (*piter != -1) {
59  // range & existence check
60  if ((*piter >= pins.size()) || (!pins[*piter] && (
61  // non-existent & unsuable pins cannot be changed
62  (*pConfIter != DigitalPinConfig::OperationNoChange) ||
64  ))) {
65  // unusable
67  } else if (pins[*piter]) {
68  // initial config unset?
69  if (*iConfIter == DigitalPinConfig::OperationNoChange) {
70  // set to current config
71  *iConfIter = pins[*piter].conf;
72  }
73  // combine options
74  pConfIter->reverseCombine(*iConfIter);
75  // test compatability - may throw
76  err = pins[*piter].cap.compatible(*pConfIter);
77  }
78  // error?
79  if (err) {
80  // flag it for return value
81  good = false;
82  }
83  }
84  // store reason if requested
85  if (insertReason) {
86  insertReason(err);
87  }
88  }
89  return good;
90 }
91 
92 // not much of an improvement, performance wise, over the above function
94  std::vector<DigitalPinConfig> &propConf,
95  std::vector<DigitalPinConfig> &initConf,
96  std::function<void(DigitalPinRejectedConfiguration::Reason)> insertReason
97 ) const {
98  // inputs must match size of pins, except initConf may be empty
99  if ((propConf.size() != pins.size()) || (
100  !initConf.empty() && initConf.size() != pins.size()
101  )) {
103  DigitalPortAffected(this)
104  );
105  }
106  // put in inital values for the starting config if empty
107  if (initConf.empty()) {
108  initConf = configurationImpl();
109  }
110  // iterate over the pins & config
111  std::vector<DigitalPinConfig>::iterator pConfIter = propConf.begin();
112  std::vector<DigitalPinConfig>::iterator iConfIter = initConf.begin();
113  PinVector::const_iterator pvIter = pins.begin();
114  unsigned int pos = 0;
115  bool good = true;
116  for (; pvIter != pins.cend(); ++pos, ++iConfIter, ++ pConfIter, ++pvIter) {
119  // non-existence check
120  if (!*pvIter && (
121  // non-existent & unsuable pins cannot be changed
122  (*pConfIter != DigitalPinConfig::OperationNoChange) ||
124  )) {
125  // unusable
127  } else if (*pvIter) {
128  // combine options
129  pConfIter->reverseCombine(*iConfIter);
130  // test compatability - may throw
131  err = pins[pos].cap.compatible(*pConfIter);
132  }
133  // error?
134  if (err) {
135  // flag it for return value
136  good = false;
137  }
138  // store reason if requested
139  if (insertReason) {
140  insertReason(err);
141  }
142  }
143  return good;
144 }
145 
148  unsigned int gid,
149  DigitalPinConfig &pconf,
150  DigitalPinConfig &iconf
151 ) const {
152  // check range
153  unsigned int lid = localId(gid);
154  if ((lid >= pins.size()) || !pins[lid]) {
155  // no pin
157  }
159  // use current config
160  iconf = pins[lid].conf;
161  }
162  pconf.reverseCombine(iconf);
163  // test compatability - may throw
164  return pins[lid].cap.compatible(pconf);
165 }
166 
168  const std::vector<DigitalPinConfig> &cfgs,
170 ) {
171  std::vector<DigitalPinConfig>::const_iterator iter = cfgs.cbegin();
172  for (unsigned int lid = 0; iter != cfgs.end(); ++lid, ++iter) {
173  configurePort(lid, *iter, pdata);
174  }
175 }
176 
177 } } }
virtual DigitalPinRejectedConfiguration::Reason proposeConfigImpl(unsigned int gid, DigitalPinConfig &pconf, DigitalPinConfig &iconf) const
Considers the proposed configuration for one pin.
Defines the configuration for a digital general purpose I/O pin.
unsigned int localId(unsigned int globalId) const
Returns the local ID for a pin given the global ID.
constexpr Reason Unsupported
Completely unsupported.
A type for holding arbitrary port-specific data within a DigitalPinAccess or DigitalPinSetAccess obje...
boost::error_info< struct Info_DigitalPortAffected, const DigitalPort * > DigitalPortAffected
Added to exceptions thrown by DigitalPort objects.
void reverseCombine(const DigitalPinConfig &oldCfg)
Combines an old (initial) configuration with a new configuration in this object and stores the result...
constexpr Reason NotRejected
There is no error with the requested pin configuration for the referenced pin.
A type-safe bit flag storage class.
Definition: BitFlags.hpp:101
virtual bool proposeFullConfigImpl(std::vector< DigitalPinConfig > &propConf, std::vector< DigitalPinConfig > &initConf, std::function< void(DigitalPinRejectedConfiguration::Reason)> insertReason=std::function< void(DigitalPinRejectedConfiguration::Reason)>()) const
Considers the proposed configuration one pin at a time for all pins in the port.
Indicates that the specified configuration data includes too many or too few items, or has parallel data structures of inconsistent sizes.
static constexpr Flags OperationNoChange
No change to any pin operation.
std::vector< DigitalPinConfig > configurationImpl() const
Returns the configuration of all pins in the port.
PinVector pins
Data on each pin handled by the port.
virtual void configurePort(const std::vector< DigitalPinConfig > &cfgs, DigitalPinAccessBase::PortData *pdata)
Changes the hardware configuration for the whole port by calling configurePort(const DigitalPinConfig...
#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