From c8d26b4b14da13fc2ac0062cf2e476479cf0beca Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 20 Mar 2020 14:17:17 +0100 Subject: [PATCH] drivers: sensor: nxp_kinetis_temp: add weighted average filter Add an optional weighted average filter to the ADC readings in the NXP Kinetis temperature sensor driver as recommended in NXP AN3031. Signed-off-by: Henrik Brix Andersen --- drivers/sensor/nxp_kinetis_temp/Kconfig | 6 ++++++ .../sensor/nxp_kinetis_temp/temp_kinetis.c | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/sensor/nxp_kinetis_temp/Kconfig b/drivers/sensor/nxp_kinetis_temp/Kconfig index f18666f96b6..64cc84cd176 100644 --- a/drivers/sensor/nxp_kinetis_temp/Kconfig +++ b/drivers/sensor/nxp_kinetis_temp/Kconfig @@ -28,4 +28,10 @@ config TEMP_KINETIS_OVERSAMPLING bandgap voltage readings. Oversampling can help in providing more stable readings. +config TEMP_KINETIS_FILTER + bool "Enable digital filtering of ADC readings" + help + Enable weighted average digital filtering of the ADC + readings as per NXP AN3031. + endif # TEMP_KINETIS diff --git a/drivers/sensor/nxp_kinetis_temp/temp_kinetis.c b/drivers/sensor/nxp_kinetis_temp/temp_kinetis.c index b3861a7ebbc..2fbad2571a4 100644 --- a/drivers/sensor/nxp_kinetis_temp/temp_kinetis.c +++ b/drivers/sensor/nxp_kinetis_temp/temp_kinetis.c @@ -45,6 +45,10 @@ static int temp_kinetis_sample_fetch(struct device *dev, { const struct temp_kinetis_config *config = dev->config->config_info; struct temp_kinetis_data *data = dev->driver_data; +#ifdef CONFIG_TEMP_KINETIS_FILTER + u16_t previous[TEMP_KINETIS_ADC_SAMPLES]; + int i; +#endif /* CONFIG_TEMP_KINETIS_FILTER */ int err; /* Always read both sensor and bandgap voltage in one go */ @@ -53,6 +57,10 @@ static int temp_kinetis_sample_fetch(struct device *dev, return -ENOTSUP; } +#ifdef CONFIG_TEMP_KINETIS_FILTER + memcpy(previous, data->buffer, sizeof(previous)); +#endif /* CONFIG_TEMP_KINETIS_FILTER */ + err = adc_read(data->adc, &config->adc_seq); if (err) { LOG_ERR("failed to read ADC channels (err %d)", err); @@ -61,6 +69,18 @@ static int temp_kinetis_sample_fetch(struct device *dev, LOG_DBG("sensor = %d, bandgap = %d", data->buffer[0], data->buffer[1]); +#ifdef CONFIG_TEMP_KINETIS_FILTER + if (previous[0] != 0 && previous[1] != 0) { + for (i = 0; i < ARRAY_SIZE(previous); i++) { + data->buffer[i] = (data->buffer[i] >> 1) + + (previous[i] >> 1); + } + + LOG_DBG("sensor = %d, bandgap = %d (filtered)", data->buffer[0], + data->buffer[1]); + } +#endif /* CONFIG_TEMP_KINETIS_FILTER */ + return 0; }