This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x ADC continuous mode, read return -1

Hi everyone,

We have a custom board using AM335X on which we use the ADC in continuous mode to read 8 inputs (so the 8 ADC channels are enabled). Our software handle the different files :
- scan_elements/in_voltageX_en to enable the channel X (in our case all of them are set to 1)
- buffer/lenght set to 100 (100 values per channel)
- buffer/enable set to 1 to configure the ADC in continuous mode
and read the char device /dev/iio:device0 every 250ms (read method from unistd.h).

Unfortunately after some time (no obvious pattern) the read method return -1 (and from then nothing else) and nothing seems to be able to restore the ADC back to a functionnal state.
Wy tried to :
- kill our soft, disable the continuous mode (buffer/enable set to 0) and then restart our soft
- kill our soft, disable the channels (every scan_elements/in_voltageX_en set to 0), and then restart our soft
- kill our soft, disable the continuous mode, disable the channels and then restart our soft
- kill our soft, rmmod the ti_am335x_adc kernel module, modprobe it back and then restart our soft

Nothing.

The only solution we found for the ADC to be restored back to a functionnal state is to reboot the system.

  •  Would any one have any idea why the read start returning -1 at some point ?
  • Any idea how to retore the ADC back to a functionnal state without having to reboot the system ?


(We are using the linux staging 3.14.49-ge9cd4cc819).

Thanks in advance.

  • Hi,

    Are you sure that you always get signal levels 1.8V on the ADC pins, see the caution here: processors.wiki.ti.com/.../Linux_Core_ADC_User's_Guide

    Also for continuous mode, take a look at the following wiki:
    processors.wiki.ti.com/.../Linux_Core_ADC_User's_Guide

    Best Regards,
    Yordan
  • Thanks for the answer !

    We've been following the wiki (processors.wiki.ti.com/.../Linux_Core_ADC_User's_Guide) to build our code and tried to take into account every caution it gives but if there's anything you think we might have forgotten please ....

    For the signal levels over 1.8V, I have not check it but I doubt this is our problem since we're using 1.8V op-amp.

    Thx again,
  • Hi,

    Do you get any error log? Can you share the dmesg output?

    Best Regards,
    Yordan
  • I don't know since when my target is in this error state so I have no idea which part of the dmesg would be usefull in regard to this problem. I've scrolled it and don't thing it contains any usefull information, anyway, when I succeed in reproducing the problem on purpose I'll make sure to post here the dmesg output following the reading problem just in case.

    When the ADC fails like this and the read return -1, errno is set to "Resource temporarily unavailable".
     

    What could be done during reboot that we would not do by disabling/enabling channels, continuous mode, setting buffer lenght, unloading and reloading relative kernel module ?

  • I don't know if this has anything at all to do with your problem but it seems plausible that there could be a timing issue with reading too fast such as this thread mentions:

    Lock-up reading AM335x ADC on 3.14.35 kernel

    e2e.ti.com/.../415890

    In any case, if you find a solution, please post it because I need to read the ADC on our custom board, too. Also, if you know of any C code for reading the ADC directly without going through /sys, please post a link to it.

    Thanks

     

  • I doubt it. I open the character device (used in continuous mode) using the flag O_NONBLOCK, thus when I increase the frequency I'm reading the device with, the only difference is I read less bytes. I'm not sure I'm clear enough but the idea is simple, if asking for 1600 bytes (it's just an example) to the read method, reading at a low frequency the read method return the 1600 bytes but at an higher frequency I will only get 1500 bytes (again just as an example) on the 1600 requested.
    Given this behavior I doubt our problem (being stuck in a state where read only return -1 no matter what unless we reboot the system) comes from reading too fast. I'll investigate this possibility anyway just to be sure.

    I have no C code (to read the ADC directly) to recommend but I'll post here any new information I get.

    Thanks for the answer