summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-10-14 21:36:29 -0700
committerChromeOS bot <3su6n15k.default@developer.gserviceaccount.com>2015-10-16 02:50:14 +0000
commitac3c962dafd8bf33f521941e128ebf0646874e2c (patch)
tree013a864485a1e6f6c8e796858f6dad6d89e09d0e
parent48312a797ace728cdd72015c313b428b2a336502 (diff)
downloadchrome-ec-ac3c962dafd8bf33f521941e128ebf0646874e2c.tar.gz
common: motion: Fix forced mode computation
When the sensor is defined to be used in forced mode, ec rate was not calculated properly: if the AP rate was rounded up, ec_rate requested by the AP would always be 0. If the EC rate is 0, the sensor may potientally never be queried. Also, when the sensor was disable for a long time, the last timestamp of collection may appear to be in the future, so collection was not initiated. (long time more than 35 minutes, less than 71 minutes). We still see instance where the sensor seems locked up. accelinit would not help because the state machine was not reseted, fix that. BRANCH=smaug BUG=chrome-os-partner:45627 TEST=With accelerate 3/4, check the value is now correct. Check proximity sensor is not stuck 45 minutes after last collection. Change-Id: Ia6805b75f67b048cb0b42c0f91a73dfaf94a254f Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/306107
-rw-r--r--board/ryu/board.c2
-rw-r--r--common/motion_sense.c33
-rw-r--r--driver/als_si114x.c3
3 files changed, 23 insertions, 15 deletions
diff --git a/board/ryu/board.c b/board/ryu/board.c
index 82a992e575..661d5af826 100644
--- a/board/ryu/board.c
+++ b/board/ryu/board.c
@@ -624,7 +624,7 @@ struct motion_sensor_t motion_sensors[] = {
/* EC needs sensor for light adaptive brightness */
[SENSOR_CONFIG_EC_S0] = {
.odr = 1000,
- .ec_rate = 1000,
+ .ec_rate = 0,
},
[SENSOR_CONFIG_EC_S3] = {
.odr = 1000,
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 164de91069..2a8dd29d4d 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -94,7 +94,7 @@ void motion_sense_fifo_add_unit(struct ec_response_motion_sensor_data *data,
/* For valid sensors, check if AP really needs this data */
if (valid_data) {
- /* Use Hz, conversion to FP will overflow with mHz */
+ /* Use Hz, conversion to FP will overflow with kHz */
fp_t ap_odr =
fp_div(BASE_ODR(sensor->config[SENSOR_CONFIG_AP].odr),
1000);
@@ -184,7 +184,7 @@ static inline int motion_sensor_time_to_read(const timestamp_t *ts,
if (rate == 0)
return 0;
/*
- * converting from mHz to us, need 1e9,
+ * converting from kHz to us, need 1e9,
* If within 95% of the time, check sensor.
*/
return time_after(ts->le.lo,
@@ -215,6 +215,7 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor)
{
int roundup = 0, ec_odr = 0, odr = 0;
enum sensor_config config_id;
+ timestamp_t ts = get_time();
/* We assume the sensor is initalized */
@@ -233,21 +234,27 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor)
CPRINTS("%s ODR: %d - roundup %d from config %d",
sensor->name, odr, roundup, config_id);
sensor->oversampling = 0;
+ /*
+ * Reset last collection: the last collection may be so much in the past
+ * it may appear to be in the future.
+ */
+ sensor->last_collection = ts.le.lo;
return sensor->drv->set_data_rate(sensor, odr, roundup);
}
-static inline int motion_sense_select_ec_rate(
+static int motion_sense_select_ec_rate(
const struct motion_sensor_t *sensor,
enum sensor_config config_id)
{
#ifdef CONFIG_ACCEL_FORCE_MODE_MASK
- if (CONFIG_ACCEL_FORCE_MODE_MASK & (1 << (sensor - motion_sensors)))
+ if (CONFIG_ACCEL_FORCE_MODE_MASK & (1 << (sensor - motion_sensors))) {
+ int rate = BASE_ODR(sensor->config[config_id].odr);
/* we have to run ec at the sensor frequency rate.*/
- if (sensor->config[config_id].odr > 0)
- return 1000000 / sensor->config[config_id].odr;
+ if (rate > 0)
+ return 1000000 / rate;
else
return 0;
- else
+ } else
#endif
return sensor->config[config_id].ec_rate;
}
@@ -270,9 +277,9 @@ static int motion_sense_ec_rate(struct motion_sensor_t *sensor)
ec_rate_from_cfg = motion_sense_select_ec_rate(
sensor, motion_sense_get_ec_config());
- if ((ec_rate == 0 && ec_rate_from_cfg != 0) ||
- (ec_rate_from_cfg != 0 && ec_rate_from_cfg < ec_rate))
- ec_rate = ec_rate_from_cfg;
+ if (ec_rate_from_cfg != 0)
+ if (ec_rate == 0 || ec_rate_from_cfg < ec_rate)
+ ec_rate = ec_rate_from_cfg;
return ec_rate * MSEC;
}
@@ -303,7 +310,8 @@ int motion_sense_set_motion_intervals(void)
if (ec_rate == 0 || sensor_ec_rate < ec_rate)
ec_rate = sensor_ec_rate;
- sensor_ec_rate = sensor->config[SENSOR_CONFIG_AP].ec_rate;
+ sensor_ec_rate = motion_sense_select_ec_rate(
+ sensor, SENSOR_CONFIG_AP);
if (ec_int_rate_ms == 0 ||
(sensor_ec_rate && sensor_ec_rate < ec_int_rate_ms))
ec_int_rate_ms = sensor_ec_rate;
@@ -336,9 +344,7 @@ static inline int motion_sense_init(struct motion_sensor_t *sensor)
if (ret != EC_SUCCESS) {
sensor->state = SENSOR_INIT_ERROR;
} else {
- timestamp_t ts = get_time();
sensor->state = SENSOR_INITIALIZED;
- sensor->last_collection = ts.le.lo;
motion_sense_set_data_rate(sensor);
}
return ret;
@@ -632,7 +638,6 @@ void motion_sense_task(void)
continue;
}
- ts_begin_task = get_time();
ret = motion_sense_process(sensor, &event,
&ts_begin_task);
if (ret != EC_SUCCESS)
diff --git a/driver/als_si114x.c b/driver/als_si114x.c
index fb927e9367..fb4a19fc6a 100644
--- a/driver/als_si114x.c
+++ b/driver/als_si114x.c
@@ -482,6 +482,7 @@ static int set_interrupt(const struct motion_sensor_t *s,
static int init(const struct motion_sensor_t *s)
{
int ret, resol;
+ struct si114x_drv_data_t *data = SI114X_GET_DATA(s);
/* initialize only once: light must be declared first. */
if (s->type == MOTIONSENSE_TYPE_LIGHT) {
@@ -493,6 +494,8 @@ static int init(const struct motion_sensor_t *s)
ret = si114x_initialize(s);
if (ret != EC_SUCCESS)
return ret;
+
+ data->state = SI114X_IDLE;
resol = 7;
} else {
resol = 5;