El 6 de octubre de 2011 18:31, Alexis Berlemont <[email protected]>escribió:
> Hi, > > 2011/10/6 Fernando Herrero Carrón <[email protected]>: > > > > > > El 5 de octubre de 2011 20:06, Fernando Herrero Carrón < > [email protected]> > > escribió: > >> > >> El 5 de octubre de 2011 18:16, Alexis Berlemont > >> <[email protected]> escribió: > >>> > >>> I think the problem might be located at two different places: > >>> 1) Either the DMA controller is badly configured and it copies the > >>> properly acquired values to wrong places. > >>> 2) Or the DAQ-STC module is badly configured; so, the DMA controller > >>> copies the wrong values to right places. > >>> > >>> Concerning the alternative 1, I think it is not the most probable one. > >>> Why? Because, the DMA controller (the MITE) is configured the same way > >>> whatever the NI acquisition board holds it (or nearly). > >>> To check this idea: let's make a little test with cmd_read. > >>> > >>> If cmd_read is launched with the option -m (map), we get direct > >>> access, in user space, to the memory area the DMA controller is > >>> supposed to shot to. > >>> > >>> So, just after a4l_mmap (before the DMA controller shots anything): > >>> 367: /* Map the analog input subdevice buffer */ > >>> 368: ret = a4l_mmap(&dsc, cmd.idx_subd, buf_size, &map); > >>> you can have a look at the values hold by the buffer: > >>> - If the values are already 0x8000, we might conclude that the DMA > >>> controller does not send anything there. > >>> - If the values are not 0x8000, then we are sure that the DMA > >>> controller does behave as expected. Consequently we can skip > >>> alternative 1) and focus on the second one. > >>> > >>> If the DAQ is not properly configured; things are getting a little bit > >>> simpler (if we have the documentation /. developer manual of your > >>> acquisition card). We just have to find which stuff was not properly > >>> configured. A simple solution could be the monitoring of the status > >>> registers. In such a case, I can send you a patch which will dump the > >>> content of these registers. > >>> > >>> But before going that way, could you make the test with cmd_read + > mmap? > >>> > >>> Regards, > >>> > >>> Alexis. > >> > >> Ok, I'll check those tomorrow. From what I recall, I checked cmd_read > just > >> passing the '-m' option and resulted in the same behaviour, but I'll > recheck > >> tomorrow. > >> > >> What I find somewhat surprising is that I got it working with comedi, so > I > >> guess that the register programming should also be working with analogy. > The > >> only difference I have managed to find so far between the analogy and > the > >> comedi drivers, besides generic buffer management, is that comedi > appears to > >> handle DMA through the "generic device" interface (as in > >> http://www.mjmwired.net/kernel/Documentation/DMA-API.txt) and analogy > >> handles DMA through the PCI interface (as in > >> > http://m8-android-kernel.googlecode.com/svn/trunk/Documentation/DMA-mapping.txt > ). > >> But this is merely speculation. > >> > >> I'll look tomorrow at your two options in more detail. > >> > >> Thanks for your help! > >> Fernando > > > > Dear Alexis, > > > > I just repeated the tests with mmap. > > > > Running the provided example of "cmd_read" with either "-m" or "-m -r" > only > > dumps the 0x8000 value. _Sometimes_, very rarely, I can get to see > different > > values not far from that one, but if I get to plot it it just looks like > > noise. I don't know what is causing those values and I cannot reproduce > the > > conditions for them. > > > > Now I used gdb to step through the process (with my own code) and here is > > the sequence: > > > > - I run up to the line where the "mmapping" happens. I check that map == > > NULL and after I run the "mmap()" it gets a different value and ret == 0, > > ok. > > > > - I do a > > print *(unsigned short *)map@100 > > > > to dump the contents of the buffer and it is all filled with zeroes at > > this point. > > > > - I setup my command structure like this: > > > > cmd.idx_subd = 0; > > cmd.start_src = TRIG_NOW; > > cmd.start_arg = 0; > > cmd.flags = TRIG_WAKE_EOS; > > cmd.scan_begin_src = TRIG_TIMER; > > cmd.scan_begin_arg = 1e9 / INPUT_FREQ; > > cmd.convert_src = TRIG_NOW; > > cmd.convert_arg = 0; > > cmd.chan_descs = chanlist; > > cmd.nb_chan = NICHAN; > > cmd.scan_end_src = TRIG_COUNT; > > cmd.scan_end_arg = NICHAN; > > > > cmd.stop_src = TRIG_COUNT; > > cmd.stop_arg = SAMPLE_HISTORY; > > > > with > > > > INPUT_FREQ = 1000 (1kHz) > > NICHAN = 1 (I have also tried 4 and 8 with no difference in results) > > > > and call the a4l_snd_command() function, which returns without errors. > > > > I dump the contents of the buffer and it is still filled with zeroes. > > > > - I declare > > > > unsigned long front = 0; > > > > and call > > > > ret = a4l_mark_bufrw(&dev_input, 0, front, &front); > > > > at this point the buffer gets filled with 0x8000: > > > > > > (gdb) print *(unsigned short *)map@100 $1 = {0 <repeats 100 times>} > > (gdb) n <------------------ calls a4l_mark_bufrw() > > > > 186 if (front == 0) { > > > > (gdb) print /x*(unsigned short *)map@100 > > $2 = {0x8000 <repeats 100 times>} > > > > Now I find it funny that the value read is always the same. Could it be > that > > everything is working fine and it is the board itself that is > transferring > > that value? Could it be an indicator for an error condition? > > I don't think it is an error indicator; errors are reported in > dedicated status registers. > > Yep, you're right on that one... > If I understand correctly, most of the times you acquire 0x8000 and a > few times other values. That could mean that 0x8000 values are really > produced by the ADC converter. By the way, 0x8000 is not a meaningless > value (0x0000 - 0xFFFF median). I don't know which range was selected > (-5V / 5V by default?) but it could mean that the card is acquiring a > continuous 0V signal. > > Which channel are you using? > Could you test each channel separately and all of them at once? > Could try another range? 0V / 5V could be a great candidate: with this > one the acquired values could be 0x0000 instead of 0x8000. > > That makes sense, but with insn_read I get the right waveshape, with the same setup. I am reading a 3Hz, 3V input signal. Unfortunately, this board reports only one possible range. The output of cmd_read -v reports: cmd_read: device analogy0 opened (fd=0) cmd_read: basic descriptor retrieved subdevices count = 14 read subdevice index = 0 write subdevice index = 0 cmd_read: complex descriptor retrieved cmd_read: channel 0 ranges count = 1 bit width = 16 (bits) Now here goes a crazy thing. I modified ksrc/drivers/analogy/national_instruments/mio_common.c:ni_ai_cmd() so that every time a command is issued the buffer is filled with 0x0f. That is, I added the following line: memset(subd->buf->buf, 0x0f, subd->buf->size); Now I repeat the same sequence as in my previous mail with gdb: - Map the buffer, check address and content (buffer has some leftovers from previous runs) ret = a4l_mmap(&dev_input, 0, buf_size, &map); (gdb) print map $1 = (void *) 0x7ffff7fc8000 (gdb) print /x*(unsigned short *)map@100 $2 = {0x600, 0x5e04, 0x0 <repeats 98 times>} - Issue the command and recheck contents. Now the buffer is filled with 0x0f0f (gdb) n 173 setup_input_card(&dev_input); (gdb) n Channel 0 has 16 bits and 1 different ranges 175 unsigned long front = 0; (gdb) print /x*(unsigned short *)map@100 $3 = {0xf0f <repeats 100 times>} - Call a4l_mark_bufrw() and recheck contents. 70 samples have changed values, 30 remain the same. In those samples that changed value, only one bit changed!! (gdb) n 177 for(int scan = 0; scan < SAMPLE_HISTORY; scan++) (gdb) n 180 ret = a4l_mark_bufrw(&dev_input, 0, front, &front); (gdb) n 186 if (front == 0) { (gdb) print /x*(unsigned short *)map@100 $4 = {0x8f0f <repeats 70 times>, 0xf0f <repeats 30 times>} So there is either an 'or' operation or an addition operation with 0x8000 that is changing those values. As you said, 0x8000 is a very representative value. It represents zero on a 16 DAQ like mine, and it is also a value used as a mask in various places: ./ksrc/drivers/analogy/national_instruments/ni_stc.h:#define _bit15 0x8000 ./ksrc/drivers/analogy/national_instruments/ni_stc.h:#define Calibration_Channel_6143_RelayOn 0x8000 (which happens to be my DAQ...) Running cmd_read only yields the 0x8f0f value now, by the way. I now it's hard to imagine what is happening without having the board yourself, so I really appreciate your help. Thanks! Fernando
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
