From 08641f06164eabbc2d6326fbd4125bf49e93265b Mon Sep 17 00:00:00 2001 From: Chay Guo Date: Fri, 13 May 2022 15:52:59 +0800 Subject: [PATCH] driver: sensor: mcux_acmp: add discrete mode The ACMP on i.MXRT11xx support discrete mode, updated the driver to support discrete mode configuration. Signed-off-by: Chay Guo --- drivers/sensor/mcux_acmp/mcux_acmp.c | 116 ++++++++++++++++++---- include/zephyr/drivers/sensor/mcux_acmp.h | 41 ++++++++ 2 files changed, 139 insertions(+), 18 deletions(-) diff --git a/drivers/sensor/mcux_acmp/mcux_acmp.c b/drivers/sensor/mcux_acmp/mcux_acmp.c index 5fa6256d82d..f3ac7db0c43 100644 --- a/drivers/sensor/mcux_acmp/mcux_acmp.c +++ b/drivers/sensor/mcux_acmp/mcux_acmp.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Vestas Wind Systems A/S + * Copyright 2022 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,24 +16,6 @@ LOG_MODULE_REGISTER(mcux_acmp, CONFIG_SENSOR_LOG_LEVEL); -#if defined(FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT == 1U) -#define MCUX_ACMP_HAS_INPSEL 1 -#else -#define MCUX_ACMP_HAS_INPSEL 0 -#endif - -#if defined(FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT == 1U) -#define MCUX_ACMP_HAS_INNSEL 1 -#else -#define MCUX_ACMP_HAS_INNSEL 0 -#endif - -#if defined(FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT) && (FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT == 1U) -#define MCUX_ACMP_HAS_OFFSET 1 -#else -#define MCUX_ACMP_HAS_OFFSET 0 -#endif - #define MCUX_ACMP_DAC_LEVELS 256 #define MCUX_ACMP_INPUT_CHANNELS 8 @@ -73,6 +56,9 @@ struct mcux_acmp_data { acmp_config_t config; acmp_channel_config_t channels; acmp_dac_config_t dac; +#if MCUX_ACMP_HAS_DISCRETE_MODE + acmp_discrete_mode_config_t discrete_config; +#endif #ifdef CONFIG_MCUX_ACMP_TRIGGER const struct device *dev; sensor_trigger_handler_t rising; @@ -189,6 +175,72 @@ static int mcux_acmp_attr_set(const struct device *dev, return -EINVAL; } break; +#if MCUX_ACMP_HAS_DISCRETE_MODE + case SENSOR_ATTR_MCUX_ACMP_POSITIVE_DISCRETE_MODE: + if (val1 <= 1 && val1 >= 0) { + LOG_DBG("pdiscrete = %d", val1); + data->discrete_config.enablePositiveChannelDiscreteMode = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_DISCRETE_MODE: + if (val1 <= 1 && val1 >= 0) { + LOG_DBG("ndiscrete = %d", val1); + data->discrete_config.enableNegativeChannelDiscreteMode = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_CLOCK: + if (val1 <= kACMP_DiscreteClockFast && val1 >= kACMP_DiscreteClockSlow) { + LOG_DBG("discreteClk = %d", val1); + data->discrete_config.clockSource = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_ENABLE_RESISTOR_DIVIDER: + if (val1 <= 1 && val1 >= 0) { + LOG_DBG("discreteClk = %d", val1); + data->discrete_config.enableResistorDivider = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_SAMPLE_TIME: + if (val1 <= kACMP_DiscreteSampleTimeAs256T && + val1 >= kACMP_DiscreteSampleTimeAs1T) { + LOG_DBG("discrete sampleTime = %d", val1); + data->discrete_config.sampleTime = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE1_TIME: + if (val1 <= kACMP_DiscretePhaseTimeAlt7 && val1 >= kACMP_DiscretePhaseTimeAlt0) { + LOG_DBG("discrete phase1Time = %d", val1); + data->discrete_config.phase1Time = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE2_TIME: + if (val1 <= kACMP_DiscretePhaseTimeAlt7 && val1 >= kACMP_DiscretePhaseTimeAlt0) { + LOG_DBG("discrete phase2Time = %d", val1); + data->discrete_config.phase2Time = val1; + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); + } else { + return -EINVAL; + } + break; +#endif /* MCUX_ACMP_HAS_DISCRETE_MODE */ default: return -ENOTSUP; } @@ -240,6 +292,29 @@ static int mcux_acmp_attr_get(const struct device *dev, case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_MUX_INPUT: val->val1 = data->channels.minusMuxInput; break; +#if MCUX_ACMP_HAS_DISCRETE_MODE + case SENSOR_ATTR_MCUX_ACMP_POSITIVE_DISCRETE_MODE: + val->val1 = data->discrete_config.enablePositiveChannelDiscreteMode; + break; + case SENSOR_ATTR_MCUX_ACMP_NEGATIVE_DISCRETE_MODE: + val->val1 = data->discrete_config.enableNegativeChannelDiscreteMode; + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_CLOCK: + val->val1 = data->discrete_config.clockSource; + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_ENABLE_RESISTOR_DIVIDER: + val->val1 = data->discrete_config.enableResistorDivider; + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_SAMPLE_TIME: + val->val1 = data->discrete_config.sampleTime; + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE1_TIME: + val->val1 = data->discrete_config.phase1Time; + break; + case SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE2_TIME: + val->val1 = data->discrete_config.phase2Time; + break; +#endif /* MCUX_ACMP_HAS_DISCRETE_MODE */ default: return -ENOTSUP; } @@ -366,6 +441,11 @@ static int mcux_acmp_init(const struct device *dev) data->config.enablePinOut = config->output; ACMP_Init(config->base, &data->config); +#if MCUX_ACMP_HAS_DISCRETE_MODE + ACMP_GetDefaultDiscreteModeConfig(&data->discrete_config); + ACMP_SetDiscreteModeConfig(config->base, &data->discrete_config); +#endif + ACMP_EnableWindowMode(config->base, config->window); ACMP_SetFilterConfig(config->base, &config->filter); ACMP_SetChannelConfig(config->base, &data->channels); diff --git a/include/zephyr/drivers/sensor/mcux_acmp.h b/include/zephyr/drivers/sensor/mcux_acmp.h index 5f43e77ad13..3bbfc22ea92 100644 --- a/include/zephyr/drivers/sensor/mcux_acmp.h +++ b/include/zephyr/drivers/sensor/mcux_acmp.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Vestas Wind Systems A/S + * Copyright 2022 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +19,30 @@ extern "C" { #include +#if defined(FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INPSEL_BIT == 1U) +#define MCUX_ACMP_HAS_INPSEL 1 +#else +#define MCUX_ACMP_HAS_INPSEL 0 +#endif + +#if defined(FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT) && (FSL_FEATURE_ACMP_HAS_C1_INNSEL_BIT == 1U) +#define MCUX_ACMP_HAS_INNSEL 1 +#else +#define MCUX_ACMP_HAS_INNSEL 0 +#endif + +#if defined(FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT) && (FSL_FEATURE_ACMP_HAS_C0_OFFSET_BIT == 1U) +#define MCUX_ACMP_HAS_OFFSET 1 +#else +#define MCUX_ACMP_HAS_OFFSET 0 +#endif + +#if defined(FSL_FEATURE_ACMP_HAS_C3_REG) && (FSL_FEATURE_ACMP_HAS_C3_REG != 0U) +#define MCUX_ACMP_HAS_DISCRETE_MODE 1 +#else +#define MCUX_ACMP_HAS_DISCRETE_MODE 0 +#endif + enum sensor_channel_mcux_acmp { /** Analog Comparator Output. */ SENSOR_CHAN_MCUX_ACMP_OUTPUT = SENSOR_CHAN_PRIV_START, @@ -50,6 +75,22 @@ enum sensor_attribute_mcux_acmp { SENSOR_ATTR_MCUX_ACMP_NEGATIVE_PORT_INPUT, /** Analog Comparator negative mux input. */ SENSOR_ATTR_MCUX_ACMP_NEGATIVE_MUX_INPUT, +#if MCUX_ACMP_HAS_DISCRETE_MODE + /** Analog Comparator Positive Channel Discrete Mode Enable. */ + SENSOR_ATTR_MCUX_ACMP_POSITIVE_DISCRETE_MODE, + /** Analog Comparator Negative Channel Discrete Mode Enable. */ + SENSOR_ATTR_MCUX_ACMP_NEGATIVE_DISCRETE_MODE, + /** Analog Comparator discrete mode clock selection. */ + SENSOR_ATTR_MCUX_ACMP_DISCRETE_CLOCK, + /** Analog Comparator resistor divider enable. */ + SENSOR_ATTR_MCUX_ACMP_DISCRETE_ENABLE_RESISTOR_DIVIDER, + /** Analog Comparator discrete sample selection. */ + SENSOR_ATTR_MCUX_ACMP_DISCRETE_SAMPLE_TIME, + /** Analog Comparator discrete phase1 sampling time selection. */ + SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE1_TIME, + /** Analog Comparator discrete phase2 sampling time selection. */ + SENSOR_ATTR_MCUX_ACMP_DISCRETE_PHASE2_TIME, +#endif }; #ifdef __cplusplus