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 <changyi.guo@nxp.com>
This commit is contained in:
Chay Guo 2022-05-13 15:52:59 +08:00 committed by Carles Cufí
commit 08641f0616
2 changed files with 139 additions and 18 deletions

View file

@ -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);