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

Reply via email to