6#include "dawn/prog/counter.hxx"
11#include "dawn/debug.hxx"
12#include "dawn/io/common.hxx"
13#include "dawn/io/ddata.hxx"
29CProgCounter::~CProgCounter()
38 bind =
new (std::nothrow) SCounterBind();
45 bind->sourceId = sourceId;
46 bind->outputId = outputId;
47 bind->source =
nullptr;
48 bind->output =
nullptr;
49 bind->sourceData =
nullptr;
52 binds.push_back(bind);
58int CProgCounter::configureDesc(
const CDescObject &desc)
65 for (
size_t i = 0; i < desc.
getSize(); i++)
69 if (item->
cfgid.
s.
cls != CProgCommon::PROG_CLASS_COUNTER)
71 DAWNERR(
"counter: unsupported cfg class 0x%" PRIx32
"\n", item->
cfgid.
v);
77 case PROG_COUNTER_CFG_IOBIND:
79 size_t nitems =
static_cast<size_t>(item->
cfgid.
s.
size);
80 if (nitems == 0 || nitems % 2 != 0)
82 DAWNERR(
"counter: invalid IOBIND size %zu\n", nitems);
87 for (
size_t b = 0; b < nitems / 2; b++)
89 int ret = allocBind(ids[b * 2].v, ids[b * 2 + 1].v);
98 case PROG_COUNTER_CFG_PARAMS:
102 DAWNERR(
"counter: PARAMS config must have exactly 4 entries\n");
116 DAWNERR(
"counter: unsupported cfg id %u\n", item->
cfgid.
s.
id);
124 DAWNERR(
"counter: at least one IOBIND entry required\n");
130 DAWNERR(
"counter: step must be > 0\n");
134 if (countMin > countMax)
136 DAWNERR(
"counter: min (%" PRIu32
") > max (%" PRIu32
")\n", countMin, countMax);
140 if (countInit < countMin || countInit > countMax)
142 DAWNERR(
"counter: initial (%" PRIu32
") outside range [%" PRIu32
", %" PRIu32
"]\n",
155 return configureDesc(
getDesc());
162 for (
auto bind : binds)
164 bind->source =
getIO(bind->sourceId);
165 bind->output =
getIO(bind->outputId);
166 if (!bind->source || !bind->output)
171 if (!bind->source->isRead())
173 DAWNERR(
"counter: source 0x%" PRIx32
" is not readable\n", bind->sourceId);
177 ret = prepareWritableTarget(bind->output, 1,
true);
185 DAWNERR(
"counter: output 0x%" PRIx32
" must be writable scalar uint32\n", bind->outputId);
189 bind->sourceData = bind->source->ddata_alloc(1);
190 if (!bind->sourceData)
203 for (
auto bind : binds)
205 delete bind->sourceData;
213uint32_t CProgCounter::readInput(SCounterBind *bind,
io_ddata_t *data)
220 bind->sourceData->getDataPtr(), data->
getDataPtr(), bind->sourceData->getDataSize());
222 else if (bind->source->getData(*bind->sourceData, 1) != OK)
228 bind->sourceData->getDataPtr(),
229 bind->sourceData->getDataSize() <
sizeof(input) ? bind->sourceData->getDataSize()
234void CProgCounter::writeCount(SCounterBind *bind)
236 bind->outputData(0) = count;
237 int ret = bind->output->setData(bind->outputData);
240 DAWNERR(
"counter: setData failed %d\n", ret);
244void CProgCounter::refresh(SCounterBind *bind,
io_ddata_t *data)
246 uint32_t input = readInput(bind, data);
248 if (bind->prevInput == 0 && input != 0)
250 uint32_t next = count + countStep;
251 count = next > countMax ? countMin : next;
255 bind->prevInput = input;
258int CProgCounter::ioNotifierCb(
void *priv,
io_ddata_t *data)
260 SCounterBind *bind =
static_cast<SCounterBind *
>(priv);
262 if (bind && bind->owner && bind->owner->active)
264 bind->owner->refresh(bind, data);
276 for (
auto bind : binds)
278 if (!bind->source->isNotify())
283 ret = bind->source->setNotifier(ioNotifierCb, 0, bind);
295 for (
auto bind : binds)
297 bind->prevInput = readInput(bind,
nullptr);
308 for (
auto bind : binds)
310 if (bind->source && bind->source->isNotify())
312 bind->source->setNotifier(
nullptr, 0,
nullptr);
333 for (
auto bind : binds)
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
CDescObject & getDesc()
Get descriptor object for this object.
@ CMD_RESET
Reset object internal state.
Base class for all PROG (processing) objects.
bool hasThread() const
Check if a background thread is active.
int configure()
Configure object from descriptor data.
int trigger(uint8_t cmd)
Execute a trigger command.
int doStart()
Start implementation hook.
int deinit()
De-initialize object.
int doStop()
Stop implementation hook.
int init()
One-time initialize object after bindings are resolved.
uint32_t ObjectCfgData_t
Configuration data element - single 32-bit word.
static uint32_t cfgToU32(ObjectCfgData_t x)
Convert ObjectCfgData_t to uint32_t.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
@ DTYPE_UINT32
Unsigned 32-bit integer (0 to 4294967295).
uint32_t ObjectId
ObjectID type - single 32-bit value.
Heap-allocated dynamic I/O data buffer.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
size_t getItems()
Get number of items per batch.
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
32-bit encoded object identifier (union with bit field).