diff --git a/include/drivers/adc.h b/include/drivers/adc.h index 27d89b15a0f..6691e0af2b4 100644 --- a/include/drivers/adc.h +++ b/include/drivers/adc.h @@ -218,8 +218,15 @@ enum adc_action { * * @param dev Pointer to the device structure for the driver * instance. - * @param sequence Pointer to the sequence structure that triggered the - * sampling. + * @param sequence Pointer to the sequence structure that triggered + * the sampling. This parameter points to a copy of + * the structure that was supplied to the call that + * started the sampling sequence, thus it cannot be + * used with the CONTAINER_OF() macro to retrieve + * some other data associated with the sequence. + * Instead, the adc_sequence_options::user_data field + * should be used for such purpose. + * * @param sampling_index Index (0-65535) of the sampling done. * * @returns Action to be performed by the driver. See @ref adc_action. @@ -249,6 +256,12 @@ struct adc_sequence_options { */ adc_sequence_callback callback; + /** + * Pointer to user data. It can be used to associate the sequence + * with any other data that is needed in the callback function. + */ + void *user_data; + /** * Number of extra samplings to perform (the total number of samplings * is 1 + extra_samplings). diff --git a/tests/drivers/adc/adc_api/src/test_adc.c b/tests/drivers/adc/adc_api/src/test_adc.c index 73c708d7445..ff34695070a 100644 --- a/tests/drivers/adc/adc_api/src/test_adc.c +++ b/tests/drivers/adc/adc_api/src/test_adc.c @@ -452,10 +452,18 @@ void test_adc_asynchronous_call(void) /* * test_adc_sample_with_interval */ +static uint32_t my_sequence_identifier = 0x12345678; +static void *user_data = &my_sequence_identifier; + static enum adc_action sample_with_interval_callback(const struct device *dev, const struct adc_sequence *sequence, uint16_t sampling_index) { + if (sequence->options->user_data != &my_sequence_identifier) { + user_data = sequence->options->user_data; + return ADC_ACTION_FINISH; + } + TC_PRINT("%s: sampling %d\n", __func__, sampling_index); return ADC_ACTION_CONTINUE; } @@ -466,6 +474,7 @@ static int test_task_with_interval(void) const struct adc_sequence_options options = { .interval_us = 100 * 1000UL, .callback = sample_with_interval_callback, + .user_data = user_data, .extra_samplings = 4, }; const struct adc_sequence sequence = { @@ -485,6 +494,10 @@ static int test_task_with_interval(void) ret = adc_read(adc_dev, &sequence); zassert_equal(ret, 0, "adc_read() failed with code %d", ret); + zassert_equal(user_data, sequence.options->user_data, + "Invalid user data: %p, expected: %p", + user_data, sequence.options->user_data); + check_samples(1 + options.extra_samplings); return TC_PASS;