drivers: sensor: ntc-thermistor: Simplify comp lookup

bsearch() tries to find the exact match for the key, otherwise it
returns NULL. However, here we want to find two elements our key lies
in-between. This requires some rather complicated logic that pretends
it found the exact match even if it didn't. Replace this with a simple
implementation of binary search.

Signed-off-by: Paweł Anikiel <pan@semihalf.com>
This commit is contained in:
Paweł Anikiel 2023-08-04 10:36:23 +00:00 committed by Maureen Helm
commit 83be5fb596
3 changed files with 19 additions and 74 deletions

View file

@ -96,8 +96,6 @@ static int ntc_thermistor_init(const struct device *dev)
} }
#define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \ #define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \
static int compare_ohm_##id##inst(const void *key, const void *element); \
\
static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \ static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \
\ \
static const struct ntc_thermistor_config ntc_thermistor_cfg_##id##inst = { \ static const struct ntc_thermistor_config ntc_thermistor_cfg_##id##inst = { \
@ -112,17 +110,10 @@ static int ntc_thermistor_init(const struct device *dev)
.type = { \ .type = { \
.comp = _comp, \ .comp = _comp, \
.n_comp = _n_comp, \ .n_comp = _n_comp, \
.ohm_cmp = compare_ohm_##id##inst, \
}, \ }, \
}, \ }, \
}; \ }; \
\ \
static int compare_ohm_##id##inst(const void *key, const void *element) \
{ \
return ntc_compensation_compare_ohm( \
&ntc_thermistor_cfg_##id##inst.ntc_cfg.type, key, element); \
} \
\
SENSOR_DEVICE_DT_INST_DEFINE( \ SENSOR_DEVICE_DT_INST_DEFINE( \
inst, ntc_thermistor_init, NULL, &ntc_thermistor_driver_##id##inst, \ inst, ntc_thermistor_init, NULL, &ntc_thermistor_driver_##id##inst, \
&ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ &ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \

View file

@ -17,7 +17,6 @@ struct ntc_compensation {
struct ntc_type { struct ntc_type {
const struct ntc_compensation *comp; const struct ntc_compensation *comp;
int n_comp; int n_comp;
int (*ohm_cmp)(const void *key, const void *element);
}; };
struct ntc_config { struct ntc_config {
@ -29,19 +28,6 @@ struct ntc_config {
struct ntc_type type; struct ntc_type type;
}; };
/**
* @brief Helper comparison function for bsearch for specific
* ntc_type
*
* Ohms are sorted in descending order, perform comparison to find
* interval indexes where key falls between
*
* @param type: Pointer to ntc_type table info
* @param key: Key value bsearch is looking for
* @param element: Array element bsearch is searching
*/
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element);
/** /**
* @brief Converts ohm to temperature in milli centigrade * @brief Converts ohm to temperature in milli centigrade
* *

View file

@ -30,47 +30,6 @@ static int ntc_fixp_linear_interpolate(int x0, int y0, int x1, int y1, int x)
return y0 + ((y1 - y0) * (x - x0) / (x1 - x0)); return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
} }
/**
* ntc_compensation_compare_ohm() - Helper comparison function for bsearch
*
* Ohms are sorted in descending order, perform comparison to find
* interval indexes where key falls between
*
* @type: Pointer to ntc_type table info
* @key: Key value bsearch is looking for
* @element: Array element bsearch is searching
*/
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element)
{
int sgn = 0;
const struct ntc_compensation *ntc_key = key;
const struct ntc_compensation *element_val = element;
int element_idx = element_val - type->comp;
if (ntc_key->ohm > element_val->ohm) {
if (element_idx == 0) {
sgn = 0;
} else {
sgn = -1;
}
} else if (ntc_key->ohm == element_val->ohm) {
sgn = 0;
} else if (ntc_key->ohm < element_val->ohm) {
if (element_idx == (type->n_comp / 2) - 1) {
sgn = 0;
} else {
if (element_idx != (type->n_comp / 2) - 1 &&
ntc_key->ohm > type->comp[element_idx + 1].ohm) {
sgn = 0;
} else {
sgn = 1;
}
}
}
return sgn;
}
/** /**
* ntc_lookup_comp() - Finds indicies where ohm falls between * ntc_lookup_comp() - Finds indicies where ohm falls between
* *
@ -80,18 +39,27 @@ int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, c
*/ */
static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int *i_low, int *i_high) static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int *i_low, int *i_high)
{ {
const struct ntc_compensation *ptr; int low = 0;
struct ntc_compensation search_ohm_key = {.ohm = ohm}; int high = type->n_comp - 1;
ptr = bsearch(&search_ohm_key, type->comp, type->n_comp, sizeof(type->comp[0]), if (ohm > type->comp[low].ohm) {
type->ohm_cmp); high = low;
if (ptr) { } else if (ohm < type->comp[high].ohm) {
*i_low = ptr - type->comp; low = high;
*i_high = *i_low + 1;
} else {
*i_low = 0;
*i_high = 0;
} }
while (high - low > 1) {
int mid = (low + high) / 2;
if (ohm > type->comp[mid].ohm) {
high = mid;
} else {
low = mid;
}
}
*i_low = low;
*i_high = high;
} }
/** /**