diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 22a839a5f35..5692f910cbb 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -719,6 +719,29 @@ static DEVICE_API(adc, adc_nrfx_driver_api) = { #endif }; +#ifdef NRF_SAADC_AIN8 +/* AIN8-AIN14 inputs are on 3v3 GPIO port and they cannot be mixed with other + * analog inputs (from 1v8 ports) in differential mode. + */ +#define CH_IS_3V3(val) (val >= NRF_SAADC_AIN8) + +#define CH_IS_DIFF(node) DT_PROP(node, zephyr_differential) + +#define CH_MIX_3V3_1V8_CHECK(node) \ + (!CH_IS_DIFF(node) || \ + !(CH_IS_3V3(DT_PROP_OR(node, zephyr_input_positive, 0)) ^ \ + CH_IS_3V3(DT_PROP_OR(node, zephyr_input_negative, 0)))) +#else +#define CH_MIX_3V3_1V8_CHECK(node) true +#endif + +#define VALIDATE_CHANNEL_CONFIG(node) \ + BUILD_ASSERT(CH_MIX_3V3_1V8_CHECK(node) == true, \ + "1v8 inputs cannot be mixed with 3v3 inputs"); + +/* Validate configuration of all channels. */ +#define VALIDATE_CHANNELS_CONFIG(inst) DT_FOREACH_CHILD(DT_DRV_INST(inst), VALIDATE_CHANNEL_CONFIG) + /* * There is only one instance on supported SoCs, so inst is guaranteed * to be 0 if any instance is okay. (We use adc_0 above, so the driver @@ -731,6 +754,7 @@ static DEVICE_API(adc, adc_nrfx_driver_api) = { #define SAADC_INIT(inst) \ BUILD_ASSERT((inst) == 0, \ "multiple instances not supported"); \ + VALIDATE_CHANNELS_CONFIG(inst) \ PM_DEVICE_DT_INST_DEFINE(0, saadc_pm_hook, 1); \ DEVICE_DT_INST_DEFINE(0, \ init_saadc, \ diff --git a/samples/drivers/adc/adc_sequence/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/adc/adc_sequence/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index bf53616d928..24cce679375 100644 --- a/samples/drivers/adc/adc_sequence/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/samples/drivers/adc/adc_sequence/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -45,6 +45,7 @@ zephyr,reference = "ADC_REF_INTERNAL"; zephyr,acquisition-time = ; zephyr,input-positive = ; /* P9.01 */ + zephyr,vref-mv = <3686>; /* 3.6V * 1024 */ zephyr,resolution = <12>; zephyr,oversampling = <8>; }; diff --git a/samples/drivers/adc/adc_sequence/src/main.c b/samples/drivers/adc/adc_sequence/src/main.c index 60bde60650d..084dbf428f3 100644 --- a/samples/drivers/adc/adc_sequence/src/main.c +++ b/samples/drivers/adc/adc_sequence/src/main.c @@ -60,7 +60,7 @@ int main(void) printf("Could not setup channel #%d (%d)\n", i, err); return 0; } - if (channel_cfgs[i].reference == ADC_REF_INTERNAL) { + if ((vrefs_mv[i] == 0) && (channel_cfgs[i].reference == ADC_REF_INTERNAL)) { vrefs_mv[i] = adc_ref_internal(adc); } }