drivers: adc: Introduce the adc_sequence_options::user_data field

Introduce the field that can be used to associate a given sampling
sequence with any other data needed in the sampling-done callback
function.
Adjust one ADC API test case that uses a sequence callback so that
it checks if this introduced field is propagated as expected.

Also clarify in the description of the `sequence` parameter of the
callback function that this parameter is not supposed to be supplied
to the CONTAINER_OF() macro, to avoid any further confusion in that
regard.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2020-12-08 16:42:15 +01:00 committed by Carles Cufí
commit f234c5f876
2 changed files with 28 additions and 2 deletions

View file

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

View file

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