ADC reading by PRU

Dear Youngtae Jo, thanks for your kindness on sharing your code. It pushed me to finally obtain some results.
However there are certain points that you need to take care on your code. I will try to list at least most of them here:

  1. you haven’t set anything to the ADC_CLKDIV register. On my BBB, this register is set to 7 by default, so the ADC Clock turns out to be 24MHz/(7+1) = 3 MHz, and the PRU’s clock is not a multiple of it. So I suggest to set the ADC_CLKDIV to something that divides the 24 MHz by 3 (2, 5, 11…). Check the SPRUH73L guide for more information on this register.

  2. your code will only work with the PRU0 because of the way things are defined in the .hp file. I know you got it from the am335x github, but I believe they didn’t make a good job on that header file. You can read more about this problem here.

  3. that offset has no reason, I know it was also taken by the am335x github file, but I believe they made that for pedagogical reasons only, as it is an example so they are showing possibilities. I would set the C28 register to 0x100 so that it will point to the first shared memory address (0x10000). Once that’s done you can take rid of the offsets in the C code.

  4. your calculation on the number of loops is wrong. If you know the sampling frequency, then you need the time step between two samples, then you know how many 5 ns instructions fit on it. Finally divide it by 2, as you did, as every loop takes 2 instructions.

  5. I believe that anyone coding an ADC capture in assembly is really looking for some time precision, so you’d need to count every single instruction you make outside of the delay loop and compensate that many instructions in the loop. That’s a tedious job as you need to make the number of instructions even, and make that number be the same no matter where the code jumps to.

  6. you have used bone_capemgr.8 but that could vary, and it does, as on my BBB that number is 9.

  7. according to the SPRUH73L guide, the Enabled bit from the CTRL register must be set only after all the steps configs are set.

  8. the first “sample” on the Results.txt file is actually the buffer flag, I suggest to remove the first line to avoid misreadings.

  9. you have some divisions in your numerical defines, I don’t recommend that because one may have a numerator which is not a multiple of the denominator and then he’ll lose precision.

  10. I suggest a complete restructure of the communication between the C code and the P code, so that you don’t have to manually edit each parameter twice. Sampling frequency, buffer size, you know…

  11. less important, but it would be great if you defined a register to contain the ADC_TSC base register, and then define the offsets of the others. It would have made your code more readable and flexible.

  12. you don’t need to define PRUSS0_SHARED_DATARAM because it already exists with that name in the pruss headers.

  13. you don’t need the ProcessingADC1 function. According to the SPRUH73L guide, the channel number will be printed together only if bit 1 is set, which is not the case.

  14. you can tune your code to use 16 bits for each sample, but as you are using two buffers it doesn’t seem to matter here.
    Well those are some of the points that I dedicated for my final work and I decided to share with you as your code reeeally helped to go ahead.

Thank you very much!

I was wrong about the number 1, actually after some experiments I noticed that I'm still losing samples, even after setting the ACK_CLKDIV to something that divides the 24MHz by 3. Anyway it is useful to know that you can obtain higher sample rates by setting a lower value to that register.

I'd also like to add that the continuous mode that you set on the step config seems not good. I noticed it after sampling higher frequency waves, however even on low frequency ones there's a noticeable step on the sampling: every 14-15 samples had approximately the same value... I solved that by setting STEPCONFIG it to the default one-shot mode and then the PRU request a sample when it thinks it's time to. To request a sample, re-set the bit on the STEPENABLE register.

My last step is to discover how to solve the lost samples problem...
When I'm sampling at 300kSps I noticed I lose 358 samples every 5005 samples. At 30kSps the proportion was 5 to 500.

I agree, and I found the same data repeat problem using the continuous code, it does not look like a data loss. I do a 3.6 kHz sampling rate and observed that every 7 samples, I can see the value of two adjacent samples are very close to each other (see the figure below). Anyway, would you mind sharing your code with us to solve the problem? Thanks very much in advance.