Skip to content

ADC stream API #90285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

vladislav-pejic
Copy link
Contributor

@vladislav-pejic vladislav-pejic commented May 21, 2025

Addition of streaming APIs for ADC devices that enables them to stream data to the application in more efficient way then it is currently possible.

Our goal was to provide a way to continuously stream data from ADC. We used similar approach as sensor stream API implementation.

On the user side adc_steam and adc_get_decoder APIs are added while on the driver side adc_driver_api is extended with submit and get_decoder.
Following decoder APIs are also added: get_frame_count, get_size_info, decode and has_trigger. Result of decode API should be in V in q31_t format.
Supported triggers:

  • ADC_TRIG_DATA_READY
  • ADC_TRIG_FIFO_FULL
  • ADC_TRIG_FIFO_WATERMARK
    There are 3 supported operations on data associated with trigger:
  • ADC_STREAM_DATA_INCLUDE - Include whatever data is associated with the trigger
  • ADC_STREAM_DATA_NOP - Do nothing with the associated trigger data, it may be consumed later
  • ADC_STREAM_DATA_DROP - Flush/clear whatever data is associated with the trigger

In this PR there are two driver implementations that are demonstrating use of streaming APIs with RTIO.

Signed-off-by: Vladislav Pejic vladislav.pejic@orioninc.com

Copy link

github-actions bot commented May 21, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_adi zephyrproject-rtos/hal_adi@16829b7 (main) zephyrproject-rtos/hal_adi#29 zephyrproject-rtos/hal_adi#29/files

DNM label due to: 1 project with PR revision

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-hal_adi DNM (manifest) This PR should not be merged (controlled by action-manifest) labels May 21, 2025
@MaureenHelm MaureenHelm requested review from teburd, ubieda and yasinustunerg and removed request for yasinustunerg and dcpleung May 21, 2025 14:46
@carlescufi
Copy link
Member

carlescufi commented Jul 1, 2025

Architecture WG meeting:

  • @vladislav-pejic presents the proposal
  • @henrikbrixandersen asks how ADC resolutions work, @vladislav-pejic goes through the code to explain
  • @teburd suggests extending the conversion functions to support other formats
  • @teburd asks whether one can select which ADC channels to stream, @vladislav-pejic points to the use of adc_sequence
  • @vladislav-pejic discusses the presence of default implementations of the new required functions that drivers need to implement to support streaming. They are untested, they may be useful
  • @ubieda asks whether the new APIs will end up replacing the current ones, or are we covering two different use cases? @carlescufi suggests perhaps keeping read() for the simpler cases. @bjarki-andreasen thinks that they are perhaps redundant if the future points to rtio. @henrikbrixandersen also thinks that keeping a simple read() function is worthwhile for simpler use cases and footprint considerations. @ubieda thinks having both is also reasonable, as long as the boundary is well delineated. He also suggests improving RTIO documentation, because it's not clear where and when to use its APIs.
  • @teburd reminds us that the boilerplate code using RTIO can be shared and provided for the app, so that all the complexity is hidden from it.

teburd
teburd previously approved these changes Jul 1, 2025
Copy link
Contributor

@bjarki-andreasen bjarki-andreasen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comment regarding the sample, it will be crucial for users to understand how to adopt adc_stream, so add more comments, mention stuff twice, make sure nothing is implied as much as possible :)

#include <zephyr/dsp/print_format.h>

/* ADC node from the devicetree. */
#define ADC_NODE DT_ALIAS(adc0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please namespace stuff in the sample, prefixing something ADC_ or DT_ will quickly clash with something in adc.h or devicetree.h, DT_SPEC_AND_COMMA even sounds like an "official" DT macro :) namespacing/prefixing with SAMPLE_ is quite effective, so SAMPLE_ADC_NODE for example

Comment on lines 41 to 52
#define ADC_TRIGGERS \
{ADC_TRIG_FIFO_FULL, ADC_STREAM_DATA_INCLUDE}, \
{ADC_TRIG_FIFO_WATERMARK, ADC_STREAM_DATA_INCLUDE}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment here describing what each element is and means would be helpful


ADC_DT_STREAM_IODEV(iodev, ADC_NODE, adc_channels, ADC_TRIGGERS);

RTIO_DEFINE_WITH_MEMPOOL(adc_ctx, 20, 20, 20, 512, sizeof(void *));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment as to how the mempool is used could be added here, along with the rational behind the hardcoded sizes and use of void *

adc_stream(local_iodev, &adc_ctx, NULL, &handles);

while (1) {
cqe = rtio_cqe_consume_block(&adc_ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a quick description of what an CQE is, where its being created from, and what it contains of data would be helpful

return rc;
}

const struct device *adc = dev;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems redundant, there is only one ADC in this sample right? just name the argument of the print_adc_stream adc in the first place :)

read_cfg->sequence = &sequence;

init_adc();
(void)adc_sequence_init_dt(&adc_channels[0], &sequence);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why ignore the return? a user would be expected to check it normally right?


ret = print_adc_stream(adc_channels[0].dev, &iodev);

return ret;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main must return 0

init_adc();
(void)adc_sequence_init_dt(&adc_channels[0], &sequence);

ret = print_adc_stream(adc_channels[0].dev, &iodev);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless you print something based in the ret value, it can be removed as it is unused :)

vladislav-pejic and others added 6 commits July 2, 2025 17:15
Introduce a streaming APIs for ADC devices.
Two new APIs are added to the adc_driver_api: submit and get_decoder.
Added decoder following APIs: get_frame_count, get_size_info, decode,
has_trigger.

Supported triggers are:
- ADC_TRIG_DATA_READY
- ADC_TRIG_FIFO_WATERMARK
- ADC_TRIG_FIFO_FULL
Supported operations to be done on trigger:
- include - whatever data is associated with the trigger
- nop - do nothing with data associated with the trigger
- drop - clear data associated with the trigger

Some changes to the linker scripts were needed to add decoder APIs.

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
Fix for compatible property.
Addition of hardware timer to be used with APARD32690 board.

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
Added support for RTIO stream.
Also added sampling_period property to the DTS. This is for setting the
sampling period when streaming is used.
Hardware or kernel timer can be
used for this.
To use hardware timer you need to add it to the DTS. Example:

{
	chosen {
		zephyr,adc-clock = &counter0;
	};
};

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
Updated MAX32 driver with RTIO  stream functionality.

Signed-off-by: Dimitrije Lilic <dimitrije.lilic@orioninc.com>
Fix for gpio-map-mask and gpio-map-pass-thru to enable use of
MAX32_GPIO_VSEL_VDDIOH and other defines with arduino_header connector.

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
Add sample application to demonstrate new ADC stream APIs.
Two tests are also added:
- ad4052-stream
- max32-stream

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
@vladislav-pejic
Copy link
Contributor Author

A few comment regarding the sample, it will be crucial for users to understand how to adopt adc_stream, so add more comments, mention stuff twice, make sure nothing is implied as much as possible :)

Thank you for the feedback. I added comments and corrected everything that you have suggested. Can you check if the changes are ok?

Copy link

sonarqubecloud bot commented Jul 2, 2025

Please retry analysis of this Pull-Request directly on SonarQube Cloud

@josuah josuah mentioned this pull request Jul 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture Review Discussion in the Architecture WG required area: ADC Analog-to-Digital Converter (ADC) area: Build System area: Linker Scripts area: Samples Samples area: Shields Shields (add-on boards) area: Userspace Userspace DNM (manifest) This PR should not be merged (controlled by action-manifest) manifest manifest-hal_adi platform: ADI Analog Devices, Inc.
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.