summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerrit <chrome-bot@google.com>2012-02-16 16:46:12 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2012-02-16 16:46:12 -0800
commitad7a0d5ae67cd73fe11c92c1964496455490f2c9 (patch)
treefb29f9b9c0aa928a6a6cbce3bdf977353db75437
parent10c395495190f5325df95ca9bc787f414c99eed2 (diff)
parent284c2dbb8980b2aaf000b552abdbaeb045d13601 (diff)
downloadchrome-ec-ad7a0d5ae67cd73fe11c92c1964496455490f2c9.tar.gz
Merge "Add fixed-point temp calculation as backup option."
-rw-r--r--common/temp_sensor.c46
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)