diff options
author | Vic Yang <victoryang@chromium.org> | 2012-02-16 15:35:24 -0800 |
---|---|---|
committer | Vic Yang <victoryang@chromium.org> | 2012-02-16 15:37:44 -0800 |
commit | 284c2dbb8980b2aaf000b552abdbaeb045d13601 (patch) | |
tree | 38340e9ba0634fe2a86b46b145dd0ef97f3c8e18 /common | |
parent | e75a32d2e3e9b62c47f4792d9ca17fb3b70b95d4 (diff) | |
download | chrome-ec-284c2dbb8980b2aaf000b552abdbaeb045d13601.tar.gz |
Add fixed-point temp calculation as backup option.
We prefer to use floating-point version but we might need fixed-point
version in the future if we don't have FPU support. If CONFIG_FPU flag
is not set, fixed-point object temperature calculation would be used.
Signed-off-by: Vic Yang <victoryang@chromium.org>
BUG=chrome-os-partner:7801
TEST=none
Change-Id: I69364b10bedf1351206e52266d669b4c566bd6f6
Diffstat (limited to 'common')
-rw-r--r-- | common/temp_sensor.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/common/temp_sensor.c b/common/temp_sensor.c index 80b3166e32..9313623213 100644 --- a/common/temp_sensor.c +++ b/common/temp_sensor.c @@ -53,6 +53,7 @@ int temp_sensor_tmp006_read_die_temp(const struct temp_sensor_t* sensor) */ int temp_sensor_tmp006_calculate_object_temp(int Tdie_i, int Vobj_i, int S0_i) { +#ifdef CONFIG_FPU float Tdie, Vobj, S0; float Tx, S, Vos, Vx, fv, Tobj, T4; int Tobj_i; @@ -80,6 +81,51 @@ int temp_sensor_tmp006_calculate_object_temp(int Tdie_i, int Vobj_i, int S0_i) disable_fpu(Tobj_i); return Tobj_i; +#else + /* This is the fixed-point version of object temperature calculation. + * Should be accurate but it is hard to prevent and debug + * overflow/underflow problem. Only use this version if there is no + * FPU support. + * Division is delayed when possible to preserve precision, but should + * not cause overflow. + * Assuming Tdie is between 200K and 400K, and S0 between 3e-14 and + * 9e-14, the maximum value during the calculation should be less than + * (1 << 30), which fits in int32_t. + */ + int32_t Tx, S19, Vos, Vx, fv9, ub, lb; + + Tx = Tdie - 29815; + /* S19 is the sensitivity multipled by 1e19 */ + S19 = S0 * (100000 + 175 * Tx / 100 - + 1678 * Tx / 100 * Tx / 100000) / 1000; + /* Vos is the offset voltage in nV */ + Vos = -29400 - 570 * Tx / 100 + 463 * Tx / 100 * Tx / 10000; + Vx = Vobj - Vos; + /* fv9 is Seebeck coefficient f(Vobj) multipled by 1e9 */ + fv9 = Vx + 134 * Vx / 100000 * Vx / 100000; + + /* The last step in the calculation involves square root, so we use + * binary search. + * Assuming the object temperature is between 200K and 400K, the search + * should take at most 14 iterations. + */ + ub = 40000; + lb = 20000; + while (lb != ub) { + int32_t t, rhs, lhs; + + t = (ub + lb) / 2; + lhs = t / 100 * t / 10000 * t / 10000 * (S19/100) / 1000 * t; + rhs = Tdie / 100 * Tdie / 10000 * Tdie / 10000 * (S19/100) / + 1000 * Tdie + fv9 * 1000; + if (lhs > rhs) + ub = t; + else + lb = t + 1; + } + + return ub; +#endif } int temp_sensor_tmp006_read_object_temp(const struct temp_sensor_t* sensor) |