/* compute jitter, min and max following jitter in per mille */ #define INV_SENSORS_TIMESTAMP_JITTER(_val, _jitter) \
(div_s64((_val) * (_jitter), 1000)) #define INV_SENSORS_TIMESTAMP_MIN(_val, _jitter) \
(((_val) * (1000 - (_jitter))) / 1000) #define INV_SENSORS_TIMESTAMP_MAX(_val, _jitter) \
(((_val) * (1000 + (_jitter))) / 1000)
/* Add a new value inside an accumulator and update the estimate value */ staticvoid inv_update_acc(struct inv_sensors_timestamp_acc *acc, uint32_t val)
{
uint64_t sum = 0;
size_t i;
acc->values[acc->idx++] = val; if (acc->idx >= ARRAY_SIZE(acc->values))
acc->idx = 0;
/* compute the mean of all stored values, use 0 as empty slot */ for (i = 0; i < ARRAY_SIZE(acc->values); ++i) { if (acc->values[i] == 0) break;
sum += acc->values[i];
}
/* save chip parameters and compute min and max clock period */
ts->chip = *chip;
ts->min_period = INV_SENSORS_TIMESTAMP_MIN(chip->clock_period, chip->jitter);
ts->max_period = INV_SENSORS_TIMESTAMP_MAX(chip->clock_period, chip->jitter);
/* current multiplier and period values after reset */
ts->mult = chip->init_period / chip->clock_period;
ts->period = chip->init_period;
/* use theoretical value for chip period */
inv_update_acc(&ts->chip_period, chip->clock_period);
}
EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_init, "IIO_INV_SENSORS_TIMESTAMP");
/* update interrupt timestamp and compute chip and sensor periods */
it = &ts->it;
it->lo = it->up;
it->up = timestamp;
delta = it->up - it->lo; if (it->lo != 0) { /* compute period: delta time divided by number of samples */
period = div_s64(delta, sample_nb);
valid = inv_update_chip_period(ts, period);
}
/* no previous data, compute theoritical value from interrupt */ if (ts->timestamp == 0) { /* elapsed time: sensor period * sensor samples number */
interval = (int64_t)ts->period * (int64_t)sample_nb;
ts->timestamp = it->up - interval; return;
}
/* if interrupt interval is valid, sync with interrupt timestamp */ if (valid)
inv_align_timestamp_it(ts);
}
EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, "IIO_INV_SENSORS_TIMESTAMP");
/* update to new multiplier and update period */
ts->mult = ts->new_mult;
ts->new_mult = 0;
ts->period = ts->mult * ts->chip_period.val;
/* * After ODR change the time interval with the previous sample is * undertermined (depends when the change occures). So we compute the * timestamp from the current interrupt using the new FIFO period, the * total number of samples and the current sample numero.
*/ if (ts->timestamp != 0) { /* compute measured fifo period */
fifo_mult = fifo_period / ts->chip.clock_period;
fifo_period = fifo_mult * ts->chip_period.val; /* computes time interval between interrupt and this sample */
interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period;
ts->timestamp = ts->it.up - interval;
}
}
EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_apply_odr, "IIO_INV_SENSORS_TIMESTAMP");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.