diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-11-17 13:14:10 -0800 |
---|---|---|
committer | ChromeOS bot <3su6n15k.default@developer.gserviceaccount.com> | 2015-11-20 04:13:38 +0000 |
commit | 0c4d323aefbd1c1193359ad6b4a13191cc0237b0 (patch) | |
tree | 5a3b83be03fbf6a0887a42f4d5d20c6f7bca7f79 | |
parent | 43b072f03a295510b8dcf2b04397c9d96d6ceb80 (diff) | |
download | chrome-ec-0c4d323aefbd1c1193359ad6b4a13191cc0237b0.tar.gz |
motion: Alter ec_rate to prevent samples without data
If EC sampling rate is close to sensor rate, decrease sampling frequency
by 5% to prevent samples by the EC without data.
It can happen when the clocks are slightly different and get
unsynchronized.
BRANCH=smaug
BUG=b:24367625
TEST=Ran cts.SingleSensorTests overnight without error.
Change-Id: Iab5e578763171411eb474e1e717167c8e1ef7ecf
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/312985
Reviewed-by: Alec Berg <alecaberg@chromium.org>
(cherry picked from commit d98999f3685ddbd27af86e1d96f2af030af9beab)
Reviewed-on: https://chromium-review.googlesource.com/313348
-rw-r--r-- | common/motion_sense.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/common/motion_sense.c b/common/motion_sense.c index ac2ffb8148..8a21377abf 100644 --- a/common/motion_sense.c +++ b/common/motion_sense.c @@ -163,11 +163,11 @@ static inline int motion_sensor_time_to_read(const timestamp_t *ts, if (rate == 0) return 0; /* - * converting from kHz to us, need 1e9, + * converting from kHz to us. * If within 95% of the time, check sensor. */ return time_after(ts->le.lo, - sensor->last_collection + 950000000 / rate); + sensor->last_collection + SECOND * 950 / rate); } static enum sensor_config motion_sense_get_ec_config(void) @@ -236,6 +236,41 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor) return 0; } +static int motion_sense_set_ec_rate_from_ap( + const struct motion_sensor_t *sensor, + unsigned int new_rate) +{ + int ap_odr = BASE_ODR(sensor->config[SENSOR_CONFIG_AP].odr); + + if (new_rate == 0) + return 0; +#ifdef CONFIG_ACCEL_FORCE_MODE_MASK + if (CONFIG_ACCEL_FORCE_MODE_MASK & (1 << (sensor - motion_sensors))) + goto end_set_ec_rate_from_ap; +#endif + if (ap_odr == 0) + goto end_set_ec_rate_from_ap; + + /* + * If the EC collection rate is close to the sensor data rate, + * given variation from the EC scheduler, it is possible that a sensor + * will not present any measurement for a given time slice, and then 2 + * measurement for the next. That will create a large interval between + * 2 measurements. + * To prevent that, increase the EC period by 5% to be sure to get at + * least one measurement at every collection time. + * We wll apply that correction only if the ec rate is within 10% of + * the data rate. + */ + if (SECOND * 1100 / ap_odr > new_rate) + new_rate = new_rate / 100 * 105; + +end_set_ec_rate_from_ap: + return MAX(new_rate, motion_min_interval); +} + + + static int motion_sense_select_ec_rate( const struct motion_sensor_t *sensor, enum sensor_config config_id) @@ -917,13 +952,9 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args) * has a value. */ if (in->ec_rate.data != EC_MOTION_SENSE_NO_VALUE) { - if (in->ec_rate.data == 0) - sensor->config[SENSOR_CONFIG_AP].ec_rate = 0; - else - sensor->config[SENSOR_CONFIG_AP].ec_rate = - MAX(in->ec_rate.data * MSEC, - motion_min_interval); - + sensor->config[SENSOR_CONFIG_AP].ec_rate = + motion_sense_set_ec_rate_from_ap( + sensor, in->ec_rate.data * MSEC); /* Bound the new sampling rate. */ motion_sense_set_motion_intervals(); } |