Also before someone says: "Hey, you're sampling 8 channels, but I can only physically connect to 7 . . ." or some such. Keep in mind that will only increase the performance of the code . . .
On Wed, Oct 7, 2015 at 9:34 PM, William Hermans <[email protected]> wrote: > Ok, I got it sorted. I was not setting ADC STEPENABLE bit for each pin. > > offset 54h STEPENABLE Step Enable Section 12.5.16 Shown here > http://elinux.org/images/6/65/Spruh73c.pdf#page=1484&zoom=auto,0,650.3 > > Now, I'm back on par. > > To screen: > debian@beaglebone:~$ time sudo ./test > . . . > 0:3883 1:3851 2:3969 3:3659 4:3680 5:3756 6:3731 7:3876 > Read: 8 channels - 200000 samples per channel for a total of 1600000 > samples read. > > real 0m13.371s > user 0m3.510s > sys 0m2.230s > > Piped to file: > debian@beaglebone:~$ time sudo ./test > output.txt > > real 0m4.343s > user 0m3.160s > sys 0m0.070s > debian@beaglebone:~$ tail output.txt > 0:3870 1:3831 2:3755 3:3766 4:3769 5:3784 6:3775 7:3873 > 0:3844 1:3846 2:3859 3:3804 4:3798 5:3795 6:3788 7:3871 > 0:3800 1:3787 2:3828 3:3779 4:3779 5:3780 6:3808 7:3871 > 0:3879 1:3829 2:3849 3:3800 4:3788 5:3761 6:3771 7:3871 > 0:3832 1:3799 2:3831 3:3817 4:3806 5:3787 6:3791 7:3871 > 0:3859 1:3780 2:3818 3:3781 4:3785 5:3779 6:3777 7:3883 > 0:3900 1:3835 2:3851 3:3806 4:3802 5:3793 6:3760 7:3875 > 0:3821 1:3795 2:3832 3:3785 4:3789 5:3811 6:3795 7:3875 > 0:3869 1:3828 2:3840 3:3768 4:3772 5:3782 6:3771 7:3875 > Read: 8 channels - 200000 samples per channel for a total of 1600000 > samples read. > > So do keep in mind that this is a "lazy" profile of the code. Meaning if I > actually profile the code properly. That would work out into my favor. > Anyway, using my basic math skills . . . I get 46051.11673958093 samples a > second - per channel *OR* 368408.9339166475 samples a second total. > > Also there are a couple things worth mentioning. Since I am only piping > stdout to a file, there is room for improvement here. I'm betting it net me > a HUGE performance gain, if I used mmap() to put that data into memory, or > a POSIX shared memory file. Both would achieve the same end goal, and I do > not believe either would be faster than the other. > > Second, this is roughly 2M a second worth of data. So, one could simply > setup an NFS share, and very conveniently pipe that data remotely to > another system without much fuss. That is to say I have 99 lines of code in > a header file, and 39 lines in my main C code file. No need to fuss with > the PRU's, Linux sockets API, or any of that. Or if you wanted to get > fancy, you could pipe that data out over netcat. > > One additional thing to note: I have not validated the samples. I'll leave > that up to someone else, but mark this horse beat into another incarnation. > > On Wed, Oct 7, 2015 at 7:18 PM, William Hermans <[email protected]> wrote: > >> Harvey, >> >> Actually, you're right. the previously mentioned FIFO is actually 100h in >> size, my bad. Too much on my brain here. What I described above is actually >> what each 32bit field *in* that buffer *is*. hah ! >> >> Anyway, I make it a habit to jump into things like this because they're >> hard to do. So I often find myself struggling with details like this. But >> in this case, not only am I "fighting" the hardware. I'm also fighting my >> ignorance of how Linux stores this information in memory. >> >> What I hope to take away from this is something like: "God, that was a >> pain in the butt, but man was it worth it!" Meaning: hopefully I'll learn >> something worth knowing ;) >> >> On Wed, Oct 7, 2015 at 6:58 PM, Harvey White <[email protected]> >> wrote: >> >>> On Wed, 7 Oct 2015 18:36:00 -0700, you wrote: >>> >>> >> >>> >> *You're working with two things, FIFO and ADC.* >>> >> >>> >> * What does the ADC do when the FIFO is full?* >>> >> >>> >> * What does the FIFO do when it is full?* >>> >> >>> >> * How do you know?* >>> >> >>> >> * Do you record it?* >>> > >>> > >>> >Hey Harvey, >>> > >>> >There is nothing wrong with my code per se. What is wrong however, and >>> >possibly indirectly related to the code in question. Is that I'm still >>> >learning the hardware, and some very obscure details as to how Linux >>> plays >>> >a part in that. >>> >>> Oh, I'm not suggesting that there is something wrong with your code, >>> but I am wondering if there is something wrong with the process >>> involved. >>> >>> Just off the top of my head (and without offence, since I'd apply the >>> same list to myself... and have.... >>> >>> 1) do we know what the OS is doing? >>> 2) do we know what the hardware is doing? >>> 3) do we know what the firmware/driver is doing? >>> 4) have we made a mistake? >>> 5) is someone else's code not doing what's designed? >>> 6) have we run into a boundary condition of some sort that is not >>> handled? >>> 7) how do we know the above answers? >>> >>> Has nothing to do with programmer (your) competence. I'd decent at >>> this, and I've graduated to more complex and obscure mistakes, >>> although I will occasionally make simple ones just to keep myself in >>> practice (for what, I don't know....) >>> >>> > >>> >So, the way I understand it is that stepping is related to averaging. In >>> >this context, a step is a single sample in a set of samples contained >>> in an >>> >average. Here is what I think I understand. Once enabled, the first step >>> >reads from the pin, stores the value, decrements the stepping value, >>> then >>> >checks if step > 0 - to possibly restart the sampling. Once all steps >>> are >>> >finished ( 1, 2, 4, 8, or 16 possible steps ), the step enable bit is >>> >toggled. So this last part here, I'm not clear on, but I think I have >>> the >>> >rest correct. But assuming this last part is correct, what could be >>> >happening is that once I have a full buffer, the step enable bit is >>> >enabled, and the ADC then "goes to sleep" until one, or more channels >>> have >>> >their step enable bit set. >>> >>> Sounds more like a sequence where the "stepping" is used to indicate >>> which samples the multiplexed input of the ADC is actually sampling >>> and measuring. >>> >>> The AVR megas and Xmegas do this. >>> >>> Analog multiplexer hooked to ADC. >>> >>> > >>> >The FIFO, in my case FIFO0DATA is only a single 32bit register. 12bit >>> data, >>> >4bit reserved, 3bit channel id, the rest reserved. So, technically, it >>> is >>> >always full. I never clear the whole register, only the data field 12 >>> bits. >>> >When I do this with devmem2, the value resets, and the whole field >>> >refreshes with new values. >>> >>> Now *that* is not what I'd call a FIFO. It's a single buffer, not a >>> First In First Out multibyte buffer with lots of storage, but a single >>> byte buffer for one reading. The most you can ever get behind is one >>> reading cycle. >>> > >>> >With the above said, I suppose you are right in that my code might be >>> >wrong, but still I think it is more of a hardware misunderstanding. Not >>> >that I think that I am the greatest C programmer to ever live, but >>> usually, >>> >I can code my way out of a wet paper bag. >>> >>> Oh, and a few dry ones as well.... That, as I mentioned, is not the >>> issue. >>> >>> Often times I find it useful to go back and check the fundamental >>> assumptions just because. >>> >>> <yoda voice> >>> Is no fault, is only program. >>> <end yoda voice> >>> >>> >>> > >>> >At any rate. Believe it or not prior to answering your post. I did hit >>> on >>> >the idea that I could either manually toggle step enable ( was just >>> reading >>> >a bit of code on this ), or I could manually clear the lower 12bits on >>> the >>> >FIFO register, and see what happens. >>> >>> Not sure what that'll do, but give it a try. >>> >>> Not sure about the ARM hardware, but I know how other processor do >>> this, and there are some little gotchas. >>> >>> Harvey >>> >>> > >>> > >>> >On Wed, Oct 7, 2015 at 5:45 PM, Harvey White <[email protected]> >>> wrote: >>> > >>> >> On Wed, 7 Oct 2015 17:20:26 -0700, you wrote: >>> >> >>> >> >Oh and dahm, one more thing heh. Sorry people I'm kind of >>> remembering this >>> >> >as I think about it. Normally I keep notes, but was up late >>> attempting to >>> >> >track this issue down. So, I'm reasonably sure the FIFO is not >>> refreshing, >>> >> >as if I flush the data value manually ( value address &= ~0xFFFF ), >>> it >>> >> >never gets repopulated. >>> >> > >>> >> >Once more, if I read out the sample in order based on channel id, the >>> >> >values stay the same form one iteration to the next. But If I burst >>> read >>> >> in >>> >> >whatever comes from the FIFO next, the values do change, but repeat >>> after >>> >> >many read. Which let us just assume, for now, it's the length of the >>> >> buffer >>> >> >I set through iio:device0. >>> >> > >>> >> >*Perhaps* I just need to enable / disable the ADC once the buffer >>> fills - >>> >> >via iio ? I'm not sure, as I've only been working with the ADC for >>> about >>> >> >what ? A week now ? With no prior experience . . . >>> >> >>> >> You're working with two things, FIFO and ADC. >>> >> >>> >> What does the ADC do when the FIFO is full? >>> >> >>> >> What does the FIFO do when it is full? >>> >> >>> >> How do you know? >>> >> >>> >> Do you record it? >>> >> >>> >> Harvey >>> >> >>> >> >>> >> > >>> >> >On Wed, Oct 7, 2015 at 5:10 PM, William Hermans <[email protected]> >>> >> wrote: >>> >> > >>> >> >> More info on the issues I'm having with the FIFO. The data seems to >>> >> >> repeat, and never changes between system reboots. I'm not sure if >>> this >>> >> is >>> >> >> my fault, or the fault of something to do with this Linux kernel, >>> the >>> >> iio >>> >> >> user space drivers, or something else. For now, I'm assuming it is >>> my >>> >> >> fault. Things that I am noticing: >>> >> >> >>> >> >> When reading the values out of the ADC via mmap() versus using >>> iio, the >>> >> >> values read out are not in the same range. Using sysfs, the >>> floating >>> >> >> voltage values are around ~4000. But with mmap() these values vary >>> >> starting >>> >> >> from as low as in the hundreds, or up close to, but not passing >>> 4000. >>> >> The >>> >> >> ID field for the ADC's *always* stay in the correct range though. >>> Which >>> >> is >>> >> >> why I think I'm not flushing / clearing the FIFO correctly - More >>> on >>> >> this >>> >> >> later. >>> >> >> >>> >> >> It does not matter how I configure the ADC( sysfs or mmap() ) in >>> this >>> >> >> case. What I've been experimenting with is a header file originally >>> >> written >>> >> >> for the Beaglebone white, but I checked the base address / offset >>> >> >> constants( against the TRM ), and they seem to be exactly the same. >>> >> Here, >>> >> >> my problem lies in not completely understanding the hardware, and >>> how >>> >> >> various things interact inside of, or with Linux. Writing the >>> software >>> >> for >>> >> >> all this once understood. For me, will be trivial. >>> >> >> >>> >> >> What does make sense to me with this problem is that I do not >>> understand >>> >> >> how to flush the buffer, and then tell the ADC "hey send more >>> samples". >>> >> But >>> >> >> I am not exactly sure this is what my problem is. This is just a >>> guess >>> >> on >>> >> >> my behalf, that makes the most sense. >>> >> >> >>> >> >> Another thing that did occur to me is that I'm reading from the >>> FIFO too >>> >> >> fast. But there are many factors here, including but not limited >>> to: >>> >> >> Averaging, stepping, clock divider, and ADC clock cycles needed to >>> read >>> >> out >>> >> >> a correct value. These are the things that are foremost on my mind >>> right >>> >> >> now, of which I have limited understanding of - so far. >>> >> >> >>> >> >> On Wed, Oct 7, 2015 at 4:44 PM, William Hermans <[email protected] >>> > >>> >> wrote: >>> >> >> >>> >> >>> *Have you experimented with buffer size? is there any optimal >>> value >>> >> >>>> calculation? Would it have any impact on the result, Like if we >>> keep a >>> >> >>>> larger buffer and than directly take that buffer that way it >>> would be >>> >> >>>> faster? I have currently kept 1k.* >>> >> >>> >>> >> >>> >>> >> >>> Yeah sorry, I'm kind of in my own world here at the moment. >>> Anyway, >>> >> like >>> >> >>> I mentioned above I was speaking of the ADC FIFO. As for >>> buffering into >>> >> >>> system RAM, this is certainly possible, and very likely >>> preferable. >>> >> This >>> >> >>> can also be done, very easily, using POSIX shared memory. >>> Potentially, >>> >> this >>> >> >>> is a problem, as once the data is in RAM, how do you get it back >>> out >>> >> for >>> >> >>> transport. Without using additional CPU cycles, or using the >>> PRU's ? >>> >> Not >>> >> >>> using the PRU's for this by the way, is a constraint I've placed >>> on >>> >> myself. >>> >> >>> Just to see if it is *reasonably* possible. Indeed, I do believe >>> it is >>> >> >>> possible, but not quite sure how reasonable that possibility >>> *is*. - >>> >> Yet. >>> >> >>> >>> >> >>> On Wed, Oct 7, 2015 at 4:34 PM, William Hermans < >>> [email protected]> >>> >> >>> wrote: >>> >> >>> >>> >> >>>> Well, the buffer I'm talking about is the ADC buffer. I've been >>> >> looking >>> >> >>>> through others code for PRU -> ADC, and have been attempting to >>> >> translate >>> >> >>>> that. I'm afraid my ASM skills are very lacking for this task( I >>> have >>> >> not >>> >> >>>> written ASM code in years ). However the constants used in much >>> of >>> >> the code >>> >> >>>> out there, are the same. So while I do not yet know what LBBO, >>> and >>> >> stuff >>> >> >>>> liek r0-r31 mean for program flow, I can figure out the >>> addressing >>> >> very >>> >> >>>> quickly. Not to mention that the TRM has this information too, >>> but >>> >> the TRM >>> >> >>>> is very terse reading for many things. It's great for "cherry >>> picking" >>> >> >>>> offsets, but much of the information is not presented in an >>> order that >>> >> >>>> makes the most sense to me. ie, you have to bounce around too >>> much >>> >> form one >>> >> >>>> place to another in this *huge* manual . . . >>> >> >>>> >>> >> >>>> So, I may have to take a break, and get to know the PRU assembly >>> >> >>>> language well before proceeding much further. Which is something >>> I >>> >> intended >>> >> >>>> on doing anyhow, just not right at this moment. One thing that >>> has me >>> >> >>>> excited here is an idea that came to me last night. Concerning >>> using >>> >> the >>> >> >>>> PRU's in a way I've not seen anyone else do - yet. Well, I've >>> seen >>> >> mention >>> >> >>>> of others touching on the subject I suppose, but . . . yeah I do >>> not >>> >> want >>> >> >>>> to let my "secrete" out just yet. >>> >> >>>> >>> >> >>>> On Wed, Oct 7, 2015 at 2:48 PM, Rathin Dholakia < >>> >> >>>> [email protected]> wrote: >>> >> >>>> >>> >> >>>>> Hi William, >>> >> >>>>> >>> >> >>>>> Oh, I had already seen that and experimented with it..!!but had >>> >> >>>>> forgotten, after watching your link I recollected. I am really >>> sorry >>> >> for >>> >> >>>>> silly question. >>> >> >>>>> >>> >> >>>>> Have you experimented with buffer size? is there any optimal >>> value >>> >> >>>>> calculation? Would it have any impact on the result, Like if we >>> keep >>> >> a >>> >> >>>>> larger buffer and than directly take that buffer that way it >>> would be >>> >> >>>>> faster? I have currently kept 1k. >>> >> >>>>> >>> >> >>>>> And yes, Priority is a priority!! I though you were on break >>> from >>> >> >>>>> BBB,...!! :-) >>> >> >>>>> >>> >> >>>>> Sincerely, >>> >> >>>>> Rathin >>> >> >>>>> >>> >> >>>>> -- >>> >> >>>>> For more options, visit http://beagleboard.org/discuss >>> >> >>>>> --- >>> >> >>>>> You received this message because you are subscribed to the >>> Google >>> >> >>>>> Groups "BeagleBoard" group. >>> >> >>>>> To unsubscribe from this group and stop receiving emails from >>> it, >>> >> send >>> >> >>>>> an email to [email protected]. >>> >> >>>>> For more options, visit https://groups.google.com/d/optout. >>> >> >>>>> >>> >> >>>> >>> >> >>>> >>> >> >>> >>> >> >> >>> >> >>> >> -- >>> >> For more options, visit http://beagleboard.org/discuss >>> >> --- >>> >> You received this message because you are subscribed to the Google >>> Groups >>> >> "BeagleBoard" group. >>> >> To unsubscribe from this group and stop receiving emails from it, >>> send an >>> >> email to [email protected]. >>> >> For more options, visit https://groups.google.com/d/optout. >>> >> >>> >>> -- >>> For more options, visit http://beagleboard.org/discuss >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "BeagleBoard" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> > -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
