analogdevicesinc / no-OS

Software drivers in C for systems without an operating system
http://analogdevicesinc.github.io/no-OS/
Other
966 stars 1.66k forks source link

Transitioning AD7124 Library from Polling to Interrupt Mode on STM32 #2309

Open AmirhoseinAskari opened 1 month ago

AmirhoseinAskari commented 1 month ago

Hi,

I’m using the AD7124 driver from this repository with an STM32 MCU. My setup is as follows:

MCU Clock Frequency: 2 MHz SPI Speed: 1 MHz Current Communication Status: Working correctly with AD7124.

Problem: The current implementation of the driver uses a polling mechanism (ad7124_wait_for_spi_ready and ad7124_wait_for_conv_ready functions), which causes significant delays in my main application loop. Specifically, I’m encountering a delay of approximately 800 ms, which negatively impacts the performance of my system.

I would like to eliminate this delay by moving from polling to an interrupt-based approach.

Challenge: The RDY pin (used to indicate data ready) is multiplexed with the DOUT pin on the AD7124. This makes it unclear how to set up an efficient interrupt-based solution since RDY and DOUT share the same pin.

Request: 1- Is there a recommended approach for using interrupts with the AD7124 when RDY and DOUT are on the same pin? 2- Has anyone else faced and solved this challenge when trying to avoid polling delays? 3- Any guidance or alternative methods for handling this scenario would be highly appreciated.

Thank you in advance for your help and support!

buha commented 1 month ago

Hi, I've looked at the driver code and indeed it's based on polling some status bits.

For the moment, what you could do is provide a small timeout for the ad7124_wait_for_spi_ready() and ad7124_wait_for_conv_ready() functions when you call them and make sure to call them often in your application loop and let the loop do the other things it needs to do in between calls. But you'll likely need to implement a small state machine to keep track of where you're at in the conversion.

The other alternative is to set up a GPIO interrupt on the RDY pin (using no-OS GPIO interrupt controller) although being multiplexed, I don't know how well it will work, unless you have a separate pin that you configure as an input and electrically hook it up to the DOUT.

1st method seems much easier for now.

AmirhoseinAskari commented 1 month ago

Hi buha,

Thank you for your response! I understand the first method involving timeouts and state machines, but I'm a bit confused about the second alternative.

When you mentioned using a GPIO interrupt on the RDY pin (even though it's multiplexed with DOUT) and potentially setting up a separate pin, could you explain a bit more about how that would work? Specifically, how would I configure the separate pin to handle interrupts, and how would it be connected to the DOUT/RDY pin electrically?

I’m just not sure how this setup would help manage the shared pin and avoid the polling delay.

Thanks again for your help.

buha commented 1 month ago

Hi @AmirhoseinAskari ,

DOUT/RDY <--- connect electrically ---> GPIO (that has interrupt capability)

And you can use the GPIO as an input and configure GPIO interrupts on it for rising/falling/both (whichever is appropriate). Through no-OS interrupt API you could temporarily enable/disable the interrupt and also set a callback to be called when the rising/falling transition occurs. By enabling/disabling it at the right time you could filter out the data transitions and focus only on the RDY transition.

You avoid the polling delay by allowing the CPU to do other stuff until the RDY transition occurs and your interrupt fires.

But I recommend the 1st method as it has the advantage of not needing to do electrical modifications and also in terms of code it seems much simpler.