if (period_gyro <= period_accel)
period = period_gyro; else
period = period_accel;
st->fifo.period = period;
}
int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st, unsignedint fifo_en)
{ unsignedint mask, val; int ret;
/* update only FIFO EN bits */
mask = INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN |
INV_ICM42600_FIFO_CONFIG1_TEMP_EN |
INV_ICM42600_FIFO_CONFIG1_GYRO_EN |
INV_ICM42600_FIFO_CONFIG1_ACCEL_EN;
val = 0; if (fifo_en & INV_ICM42600_SENSOR_GYRO)
val |= INV_ICM42600_FIFO_CONFIG1_GYRO_EN; if (fifo_en & INV_ICM42600_SENSOR_ACCEL)
val |= INV_ICM42600_FIFO_CONFIG1_ACCEL_EN; if (fifo_en & INV_ICM42600_SENSOR_TEMP)
val |= INV_ICM42600_FIFO_CONFIG1_TEMP_EN;
ret = regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, mask, val); if (ret) return ret;
/** * inv_icm42600_buffer_update_watermark - update watermark FIFO threshold * @st: driver internal state * * Returns 0 on success, a negative error code otherwise. * * FIFO watermark threshold is computed based on the required watermark values * set for gyro and accel sensors. Since watermark is all about acceptable data * latency, use the smallest setting between the 2. It means choosing the * smallest latency but this is not as simple as choosing the smallest watermark * value. Latency depends on watermark and ODR. It requires several steps: * 1) compute gyro and accel latencies and choose the smallest value. * 2) adapt the choosen latency so that it is a multiple of both gyro and accel * ones. Otherwise it is possible that you don't meet a requirement. (for * example with gyro @100Hz wm 4 and accel @100Hz with wm 6, choosing the * value of 4 will not meet accel latency requirement because 6 is not a * multiple of 4. You need to use the value 2.) * 3) Since all periods are multiple of each others, watermark is computed by * dividing this computed latency by the smallest period, which corresponds * to the FIFO frequency. Beware that this is only true because we are not * using 500Hz frequency which is not a multiple of the others.
*/ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
{
size_t packet_size, wm_size; unsignedint wm_gyro, wm_accel, watermark;
u32 period_gyro, period_accel, period;
u32 latency_gyro, latency_accel, latency; bool restore;
__le16 raw_wm; int ret;
/* * update_scan_mode callback is turning sensors on and setting data FIFO enable * bits.
*/ staticint inv_icm42600_buffer_postenable(struct iio_dev *indio_dev)
{ struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); int ret;
mutex_lock(&st->lock);
/* exit if FIFO is already on */ if (st->fifo.on) {
ret = 0; goto out_on;
}
/* set FIFO threshold interrupt */
ret = regmap_set_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN); if (ret) goto out_unlock;
/* flush FIFO data */
ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); if (ret) goto out_unlock;
/* set FIFO in streaming mode */
ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
INV_ICM42600_FIFO_CONFIG_STREAM); if (ret) goto out_unlock;
/* workaround: first read of FIFO count after reset is always 0 */
ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, st->buffer, 2); if (ret) goto out_unlock;
/* exit if there are several sensors using the FIFO */ if (st->fifo.on > 1) {
ret = 0; goto out_off;
}
/* set FIFO in bypass mode */
ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
INV_ICM42600_FIFO_CONFIG_BYPASS); if (ret) goto out_unlock;
/* flush FIFO data */
ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); if (ret) goto out_unlock;
/* disable FIFO threshold interrupt */
ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN); if (ret) goto out_unlock;
/* compute maximum FIFO read size */ if (max == 0)
max_count = sizeof(st->fifo.data); else
max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
/* read FIFO count value */
raw_fifo_count = (__be16 *)st->buffer;
ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT,
raw_fifo_count, sizeof(*raw_fifo_count)); if (ret) return ret;
st->fifo.count = be16_to_cpup(raw_fifo_count);
/* check and clamp FIFO count value */ if (st->fifo.count == 0) return 0; if (st->fifo.count > max_count)
st->fifo.count = max_count;
/* read all FIFO data in internal buffer */
ret = regmap_noinc_read(st->map, INV_ICM42600_REG_FIFO_DATA,
st->fifo.data, st->fifo.count); if (ret) return ret;
/* compute number of samples for each sensor */ for (i = 0; i < st->fifo.count; i += size) {
size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i],
&accel, &gyro, &temp, ×tamp, &odr); if (size <= 0) break; if (gyro != NULL && inv_icm42600_fifo_is_data_valid(gyro))
st->fifo.nb.gyro++; if (accel != NULL && inv_icm42600_fifo_is_data_valid(accel))
st->fifo.nb.accel++;
st->fifo.nb.total++;
}
return 0;
}
int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
{ struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro); struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel); struct inv_sensors_timestamp *ts; int ret;
if (st->fifo.nb.total == 0) return 0;
/* handle gyroscope timestamp and FIFO data parsing */ if (st->fifo.nb.gyro > 0) {
ts = &gyro_st->ts;
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro,
st->timestamp.gyro);
ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); if (ret) return ret;
}
/* handle accelerometer timestamp and FIFO data parsing */ if (st->fifo.nb.accel > 0) {
ts = &accel_st->ts;
inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel,
st->timestamp.accel);
ret = inv_icm42600_accel_parse_fifo(st->indio_accel); if (ret) return ret;
}
/* * Default FIFO configuration (bits 7 to 5) * - use invalid value * - FIFO count in bytes * - FIFO count in big endian
*/
val = INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN;
ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
GENMASK(7, 5), val); if (ret) return ret;
/* * Enable FIFO partial read and continuous watermark interrupt. * Disable all FIFO EN bits.
*/
val = INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD |
INV_ICM42600_FIFO_CONFIG1_WM_GT_TH; return regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1,
GENMASK(6, 5) | GENMASK(3, 0), val);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
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.