summaryrefslogtreecommitdiff
path: root/common/temp_sensor.c
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2012-02-15 15:36:40 -0800
committerVic Yang <victoryang@chromium.org>2012-02-15 16:34:54 -0800
commit93d77ada6ca328044496d4d42364bc6f70b468d5 (patch)
tree2684b23d20b0434183cf36d679a3750fb4282e4f /common/temp_sensor.c
parent8236345574850df798197878d413e87f3cdc09b6 (diff)
downloadchrome-ec-93d77ada6ca328044496d4d42364bc6f70b468d5.tar.gz
Change TMP006 temperature calculation to use FP.
The temperature calculation currently uses fixed point operations. Change it to use floating point for better readability and maintenance. Also changes disable_fpu() to accept parameter which serves as optimization barrier to prevent floating point operations after disabling FPU. BUG=chrome-os-partner:7801 TEST=In console, tempremote "tempremote 29715 -105000 6390" gives 28506. Change-Id: Ib766904b8feb9a78eac9f7cd53afeca85091c5a5 Signed-off-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'common/temp_sensor.c')
-rw-r--r--common/temp_sensor.c70
1 files changed, 30 insertions, 40 deletions
diff --git a/common/temp_sensor.c b/common/temp_sensor.c
index bc794874ab..80b3166e32 100644
--- a/common/temp_sensor.c
+++ b/common/temp_sensor.c
@@ -11,6 +11,9 @@
#include "util.h"
#include "console.h"
#include "board.h"
+#include "task.h"
+#include "fpu.h"
+#include "math.h"
/* Defined in board_temp_sensor.c. Must be in the same order as
* in enum temp_sensor_id.
@@ -44,52 +47,39 @@ int temp_sensor_tmp006_read_die_temp(const struct temp_sensor_t* sensor)
* Parameters:
* Tdie: Die temperature in 1/100 K.
* Vobj: Voltage read from register 0. In nV.
- * S0: Sensitivity factor in 1/1000.
+ * S0: Sensitivity factor in 1e-17.
* Return:
* Object temperature in 1/100 K.
*/
-int temp_sensor_tmp006_calculate_object_temp(int Tdie, int Vobj, int S0)
+int temp_sensor_tmp006_calculate_object_temp(int Tdie_i, int Vobj_i, int S0_i)
{
- int32_t Tx, S19, Vos, Vx, fv9, ub, lb;
-
- /* Calculate according to TMP006 users guide.
- * 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.
- */
- 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;
+ float Tdie, Vobj, S0;
+ float Tx, S, Vos, Vx, fv, Tobj, T4;
+ int Tobj_i;
+
+ enable_fpu();
+
+ Tdie = (float)Tdie_i * 1e-2f;
+ Vobj = (float)Vobj_i * 1e-9f;
+ S0 = (float)S0_i * 1e-17f;
+
+ /* Calculate according to TMP006 users guide. */
+ Tx = Tdie - 298.15f;
+ /* S is the sensitivity */
+ S = S0 * (1.0f + 1.75e-3f * Tx - 1.678e-5f * Tx * Tx);
+ /* Vos is the offset voltage */
+ Vos = -2.94e-5f - 5.7e-7f * Tx + 4.63e-9f * Tx * Tx;
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;
- }
+ /* fv is Seebeck coefficient f(Vobj) */
+ fv = Vx + 13.4f * Vx * Vx;
+
+ T4 = Tdie * Tdie * Tdie * Tdie + fv / S;
+ Tobj = sqrtf(sqrtf(T4));
+ Tobj_i = (int32_t)(Tobj * 100.0f);
+
+ disable_fpu(Tobj_i);
- return ub;
+ return Tobj_i;
}
int temp_sensor_tmp006_read_object_temp(const struct temp_sensor_t* sensor)