All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Command code working with comedi not working with analogy
@ 2011-09-27 18:55 Fernando Herrero Carrón
  2011-09-27 21:02 ` Gilles Chanteperdrix
  2011-09-28  7:33 ` Julien Delange
  0 siblings, 2 replies; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-09-27 18:55 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

Hi all,

This is my first post to the list. I have been playing around with
RTAI+Comedi for a while and wanted to give Xenomai+Analogy a chance. I am
running a linux 2.6.32.20 kernel on an AMD Phenom(tm) II X4 965, with
Xenomai 2.5.5.2. Xenomai appears to be running fine, analogy recognizes my
NI 6143 and NI 6713 cards, and "analogy-config" sets things properly up.

Now I cannot succeed at running any of the "command" functions. The example
programs "insn_read" and "insn_write" work fine, but "cmd_read" and
"cmd_write" don't. They fail at "a4l_snd_command".

I ported an application that is already working with comedi to analogy. My
question is now whether the same values for the command structures that are
working on Comedi should work directly with Analogy, because the
corresponding "a4l_snd_command" is failing with those values, returning a
value of -22.

Thank you very much for your help,
Fernando

[-- Attachment #2: Type: text/html, Size: 1036 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-27 18:55 [Xenomai-help] Command code working with comedi not working with analogy Fernando Herrero Carrón
@ 2011-09-27 21:02 ` Gilles Chanteperdrix
  2011-09-28  7:33 ` Julien Delange
  1 sibling, 0 replies; 21+ messages in thread
From: Gilles Chanteperdrix @ 2011-09-27 21:02 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: xenomai

On 09/27/2011 08:55 PM, Fernando Herrero Carrón wrote:
> Hi all,
> 
> This is my first post to the list. I have been playing around with
> RTAI+Comedi for a while and wanted to give Xenomai+Analogy a chance. I am
> running a linux 2.6.32.20 kernel on an AMD Phenom(tm) II X4 965, with
> Xenomai 2.5.5.2. Xenomai appears to be running fine, analogy recognizes my
> NI 6143 and NI 6713 cards, and "analogy-config" sets things properly up.
> 
> Now I cannot succeed at running any of the "command" functions. The example
> programs "insn_read" and "insn_write" work fine, but "cmd_read" and
> "cmd_write" don't. They fail at "a4l_snd_command".
> 
> I ported an application that is already working with comedi to analogy. My
> question is now whether the same values for the command structures that are
> working on Comedi should work directly with Analogy, because the
> corresponding "a4l_snd_command" is failing with those values, returning a
> value of -22.
> 
> Thank you very much for your help,
> Fernando

Hi,

could you try Xenomai 2.6.0-rc3?

Regards.

-- 
                                                                Gilles.



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-27 18:55 [Xenomai-help] Command code working with comedi not working with analogy Fernando Herrero Carrón
  2011-09-27 21:02 ` Gilles Chanteperdrix
@ 2011-09-28  7:33 ` Julien Delange
  2011-09-28 15:19   ` Fernando Herrero Carrón
  2011-09-28 15:37   ` Fernando Herrero Carrón
  1 sibling, 2 replies; 21+ messages in thread
From: Julien Delange @ 2011-09-28  7:33 UTC (permalink / raw)
  To: xenomai

2011/9/27 Fernando Herrero Carrón <elferdo@domain.hid>:
> [snip]

Dear Fernando,

Would it be possible to provide more information about your bug, in
particular, the configuration of the board (which is analogy0, ...)
and the code you are trying to use ?

Also, as Gilles said, please also try the latest rc release, it might
solve your issues.

Thanks,


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-28  7:33 ` Julien Delange
@ 2011-09-28 15:19   ` Fernando Herrero Carrón
  2011-09-29 19:57     ` Fernando Herrero Carrón
  2011-09-28 15:37   ` Fernando Herrero Carrón
  1 sibling, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-09-28 15:19 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 2173 bytes --]

2011/9/28 Julien Delange <julien.delange@domain.hid>

> 2011/9/27 Fernando Herrero Carrón <elferdo@domain.hid>:
> > [snip]
>
> Dear Fernando,
>
> Would it be possible to provide more information about your bug, in
> particular, the configuration of the board (which is analogy0, ...)
> and the code you are trying to use ?
>
> Also, as Gilles said, please also try the latest rc release, it might
> solve your issues.
>
> Thanks,
>

Dear Gilles and Julien,

Thanks for your replies. I will try the latest RC and let you know.

These are the details of my setup:

- Dmesg output:

 Analogy: MITE: Available NI device IDs: 0x1870 0x70c0

- lspci:
01:05.0 Class ff00: National Instruments Device 70c0 (this should be the NI
6143) <- used for AO
01:06.0 Class ff00: National Instruments PCI-6713 <- used for AI

- analogy-config:
/usr/xenomai/sbin/analogy_config  analogy0 analogy_ni_pcimio 1,5
/usr/xenomai/sbin/analogy_config  analogy1 analogy_ni_pcimio 1,6

- cat /proc/analogy/devices
--  Analogy devices --

| idx | status | driver
|  00 | Linked | analogy_ni_pcimio
|  01 | Linked | analogy_ni_pcimio
|  02 | Unused | No driver
[...]

- cat /proc/analogy/00-analogy_ni_pcimio
--  Subdevices --

| idx | type
|  00 | Analog input subdevice
|  01 | Unused subdevice
|  02 | Digital input/output subdevice
|  03 | Unused subdevice
|  04 | Unused subdevice
|  05 | Calibration subdevice
|  06 | Memory subdevice
|  07 | Digital input/output subdevice
|  08 | Unused subdevice
|  09 | Serial subdevice
|  10 | Unused subdevice
|  11 | Counter subdevice
|  12 | Counter subdevice
|  13 | Counter subdevice

- cat /proc/analogy/01-analogy_ni_pcimio
--  Subdevices --

| idx | type
|  00 | Unused subdevice
|  01 | Analog output subdevice
|  02 | Digital input/output subdevice
|  03 | Unused subdevice
|  04 | Unused subdevice
|  05 | Calibration subdevice
|  06 | Memory subdevice
|  07 | Digital input/output subdevice
|  08 | Unused subdevice
|  09 | Serial subdevice
|  10 | Unused subdevice
|  11 | Counter subdevice
|  12 | Counter subdevice
|  13 | Counter subdevice

Thanks,
Fernando

[-- Attachment #2: Type: text/html, Size: 3004 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-28  7:33 ` Julien Delange
  2011-09-28 15:19   ` Fernando Herrero Carrón
@ 2011-09-28 15:37   ` Fernando Herrero Carrón
  1 sibling, 0 replies; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-09-28 15:37 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 861 bytes --]

2011/9/28 Julien Delange <julien.delange@domain.hid>

> 2011/9/27 Fernando Herrero Carrón <elferdo@domain.hid>:
> > [snip]
>
> Dear Fernando,
>
> Would it be possible to provide more information about your bug, in
> particular, the configuration of the board (which is analogy0, ...)
> and the code you are trying to use ?
>
> Also, as Gilles said, please also try the latest rc release, it might
> solve your issues.
>
> Thanks,
>

Ok guys, I was about to copy a minimal example when I realized that I was
using:

a4l_open(&dev_output, "/dev/comedi1");

instead of:

a4l_open(&dev_output, "analogy1");

However, "cmd_read" is still not working, so I'll still give rc3 a try and
let you know.

Sorry for the inconveniences. There's no better way to find a bug than
explaining to others what you are doing ;)

Thanks,
Fernando

[-- Attachment #2: Type: text/html, Size: 1345 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-28 15:19   ` Fernando Herrero Carrón
@ 2011-09-29 19:57     ` Fernando Herrero Carrón
  2011-09-29 22:16       ` Alexis Berlemont
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-09-29 19:57 UTC (permalink / raw)
  To: xenomai


[-- Attachment #1.1: Type: text/plain, Size: 4590 bytes --]

El 28 de septiembre de 2011 12:19, Fernando Herrero Carrón <
elferdo@domain.hid> escribió:

> 2011/9/28 Julien Delange <julien.delange@domain.hid>
>
>> 2011/9/27 Fernando Herrero Carrón <elferdo@domain.hid>:
>> > [snip]
>>
>> Dear Fernando,
>>
>> Would it be possible to provide more information about your bug, in
>> particular, the configuration of the board (which is analogy0, ...)
>> and the code you are trying to use ?
>>
>> Also, as Gilles said, please also try the latest rc release, it might
>> solve your issues.
>>
>> Thanks,
>>
>
> Dear Gilles and Julien,
>
> Thanks for your replies. I will try the latest RC and let you know.
>
> These are the details of my setup:
>
> - Dmesg output:
>
>  Analogy: MITE: Available NI device IDs: 0x1870 0x70c0
>
> - lspci:
> 01:05.0 Class ff00: National Instruments Device 70c0 (this should be the NI
> 6143) <- used for AO
> 01:06.0 Class ff00: National Instruments PCI-6713 <- used for AI
>
> - analogy-config:
> /usr/xenomai/sbin/analogy_config  analogy0 analogy_ni_pcimio 1,5
> /usr/xenomai/sbin/analogy_config  analogy1 analogy_ni_pcimio 1,6
>
> - cat /proc/analogy/devices
> --  Analogy devices --
>
> | idx | status | driver
> |  00 | Linked | analogy_ni_pcimio
> |  01 | Linked | analogy_ni_pcimio
> |  02 | Unused | No driver
> [...]
>
> - cat /proc/analogy/00-analogy_ni_pcimio
> --  Subdevices --
>
> | idx | type
> |  00 | Analog input subdevice
> |  01 | Unused subdevice
> |  02 | Digital input/output subdevice
> |  03 | Unused subdevice
> |  04 | Unused subdevice
> |  05 | Calibration subdevice
> |  06 | Memory subdevice
> |  07 | Digital input/output subdevice
> |  08 | Unused subdevice
> |  09 | Serial subdevice
> |  10 | Unused subdevice
> |  11 | Counter subdevice
> |  12 | Counter subdevice
> |  13 | Counter subdevice
>
> - cat /proc/analogy/01-analogy_ni_pcimio
> --  Subdevices --
>
> | idx | type
> |  00 | Unused subdevice
> |  01 | Analog output subdevice
> |  02 | Digital input/output subdevice
> |  03 | Unused subdevice
> |  04 | Unused subdevice
> |  05 | Calibration subdevice
> |  06 | Memory subdevice
> |  07 | Digital input/output subdevice
> |  08 | Unused subdevice
> |  09 | Serial subdevice
> |  10 | Unused subdevice
> |  11 | Counter subdevice
> |  12 | Counter subdevice
> |  13 | Counter subdevice
>
> Thanks,
> Fernando
>

Dear all,

I have followed your advice and just tested with the following
kernel/xenomai versions:

Linux ******** 2.6.38.8-xenomai-2.6rc4 #1 SMP PREEMPT Thu Sep 29 16:17:41
BRT 2011 x86_64 GNU/Linux

Now both "cmd_read" and my own code are running, but "a4l_async_read" reads
either garbage or either value of 0 or 0x8000. In order to make cmd_read
work with my board I had to make the following changes to the code:

--- cmd_read.c.orig    2011-09-29 16:40:50.000000000 -0300
+++ cmd_read.c    2011-09-29 16:41:04.000000000 -0300
@@ -66,8 +66,8 @@
     .start_arg = 0,
     .scan_begin_src = TRIG_TIMER,
     .scan_begin_arg = 8000000,    /* in ns */
-    .convert_src = TRIG_TIMER,
-    .convert_arg = 500000,    /* in ns */
+    .convert_src = TRIG_NOW,
+    .convert_arg = 00000,    /* in ns */
     .scan_end_src = TRIG_COUNT,
     .scan_end_arg = 0,
     .stop_src = TRIG_COUNT,

otherwise the drive would complain about "the driver cmd_test failed" or
something like that, because my board has 8 parallel ADCs.

If I run my program (see attachment) and call dmesg I can see:

[  641.237710] Analogy: analogy_ni_pcimio: ni_ai_cmd: start
[  641.237718] Analogy: analogy_ni_pcimio: ni_ai_cmd:
Interrupt_A_Enable_Register = 0x0031
[  641.237723] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
[  641.238874] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
a_status=90b0 ai_mite_status=00200000
[  641.239872] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
a_status=9030 ai_mite_status=00200000
[...]
[  642.237879] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
a_status=9070 ai_mite_status=00200000
[  642.237881] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt

I just checked my setup with our RTAI/comedi code and it is properly
working. The input card is attached to a 3Hz sine wave generator with 1V
peek-to-peek. If I run the attached program, the output looks like this:

Analogy device analogy_ni_pcimio.
Channel 0 has 16 bits and 1 different ranges
32768
32768
32768
32768
32768
[...]
32768

Any help on debugging this would be greatly appreciated.

Sincerely,
Fernando

[-- Attachment #1.2: Type: text/html, Size: 5954 bytes --]

[-- Attachment #2: analogy_cmd_read.cpp --]
[-- Type: text/x-c++src, Size: 3136 bytes --]

/**
 * Use analogy commands to read an analog device.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#include <math.h>

#include <analogy/analogy.h>
#include <analogy/command.h>

#include <native/task.h>

#define NICHAN   1
#define INPUT_FREQ 1000

a4l_desc_t dev_input;

a4l_chinfo_t *chaninfos[NICHAN] = {0};

static lsampl_t maxdatai;

int ret = 0;

#define SAMPLE_HISTORY 1000
long unsigned int channel_history[SAMPLE_HISTORY][NICHAN] = {0};

RT_TASK rt_task_desc;

int init_board(void)
{
	int result = 0;

	result = a4l_open(&dev_input, "analogy0");
	printf("Analogy device %s.\n", dev_input.board_name);

	if (result){
		printf("Unable to open %s.\n", dev_input.board_name);
		return 1;
	}

	dev_input.sbdata = malloc(dev_input.sbsize);

	if (dev_input.sbdata == NULL)
	{
		fprintf (stderr, "Malloc error at %s, line %d.\n", __FILE__, __LINE__);

		exit(-1);
	}

	ret = a4l_fill_desc(&dev_input);

	if(ret < 0)
	{
		fprintf (stderr, "%d at %s, line %d.\n", ret, __FILE__, __LINE__);

		exit(-1);
	}

	return 0;
}

void setup_input_card(a4l_desc_t *dev)
{
	unsigned int chanlist[NICHAN] = {0};
	a4l_cmd_t cmd;

	// Set up command
	memset(&cmd, 0, sizeof(cmd));

	// Setup chan list
	for(int i = 0; i < NICHAN; i++){
		chanlist[i] = PACK(i, 0, AREF_COMMON);
	}

	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;

	for(int i = 0; i < NICHAN; i++)
	{
		int ret = a4l_get_chinfo(dev, 0, i, &chaninfos[i]);

		printf("Channel %d has %d bits and %d different ranges\n", i, chaninfos[i]->nb_bits, chaninfos[i]->nb_rng);

		if(ret < 0)
		{
			fprintf (stderr, "%d at %s, line %d.\n", ret, __FILE__, __LINE__);

			break;
		}
	}

	a4l_snd_cancel(dev, 0);

	/* Start the command */
	ret = a4l_snd_command(dev, &cmd);

	if(ret < 0){
		fprintf (stderr, "%d at %s, line %d.\n", ret, __FILE__, __LINE__);

		exit(1);
	}
}

int main(void)
{
	unsigned char input_buffer[NICHAN * 10];

	mlockall(MCL_CURRENT | MCL_FUTURE);

	int ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);

	if (ret < 0) {
		fprintf(stderr,	"rt_task_shadow failed (ret=%d)\n",	ret);

		exit(-1);
	}

	if (init_board()) {;
		printf("Board initialization failed.\n");
		return 1;
	}

	setup_input_card(&dev_input);

	for(int scan = 0; scan < SAMPLE_HISTORY; scan++)
	{
		int m = a4l_async_read(&dev_input, input_buffer, NICHAN * a4l_sizeof_chan(chaninfos[0]), A4L_INFINITE);

		a4l_rawtoul(chaninfos[0], channel_history[scan], input_buffer, NICHAN);
	}

	a4l_snd_cancel(&dev_input, 0);
	a4l_close(&dev_input);

	for (int i = 0; i < SAMPLE_HISTORY; i++) {
		for(int j = 0; j < NICHAN; j++)
		{
			printf("%lu ", channel_history[i][j]);
		}

		printf("\n");
	}

	return 0;
}

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-29 19:57     ` Fernando Herrero Carrón
@ 2011-09-29 22:16       ` Alexis Berlemont
  2011-10-03 21:41         ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Alexis Berlemont @ 2011-09-29 22:16 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: xenomai

Hi,

2011/9/29 Fernando Herrero Carrón <elferdo@domain.hid>:
> El 28 de septiembre de 2011 12:19, Fernando Herrero Carrón
> <elferdo@domain.hid> escribió:
>>
>> 2011/9/28 Julien Delange <julien.delange@domain.hid>
>>>
>>> 2011/9/27 Fernando Herrero Carrón <elferdo@domain.hid>:
>>> > [snip]
>>>
>>> Dear Fernando,
>>>
>>> Would it be possible to provide more information about your bug, in
>>> particular, the configuration of the board (which is analogy0, ...)
>>> and the code you are trying to use ?
>>>
>>> Also, as Gilles said, please also try the latest rc release, it might
>>> solve your issues.
>>>
>>> Thanks,
>>
>> Dear Gilles and Julien,
>>
>> Thanks for your replies. I will try the latest RC and let you know.
>>
>> These are the details of my setup:
>>
>> - Dmesg output:
>>
>>  Analogy: MITE: Available NI device IDs: 0x1870 0x70c0
>>
>> - lspci:
>> 01:05.0 Class ff00: National Instruments Device 70c0 (this should be the
>> NI 6143) <- used for AO
>> 01:06.0 Class ff00: National Instruments PCI-6713 <- used for AI
>>
>> - analogy-config:
>> /usr/xenomai/sbin/analogy_config  analogy0 analogy_ni_pcimio 1,5
>> /usr/xenomai/sbin/analogy_config  analogy1 analogy_ni_pcimio 1,6
>>
>> - cat /proc/analogy/devices
>> --  Analogy devices --
>>
>> | idx | status | driver
>> |  00 | Linked | analogy_ni_pcimio
>> |  01 | Linked | analogy_ni_pcimio
>> |  02 | Unused | No driver
>> [...]
>>
>> - cat /proc/analogy/00-analogy_ni_pcimio
>> --  Subdevices --
>>
>> | idx | type
>> |  00 | Analog input subdevice
>> |  01 | Unused subdevice
>> |  02 | Digital input/output subdevice
>> |  03 | Unused subdevice
>> |  04 | Unused subdevice
>> |  05 | Calibration subdevice
>> |  06 | Memory subdevice
>> |  07 | Digital input/output subdevice
>> |  08 | Unused subdevice
>> |  09 | Serial subdevice
>> |  10 | Unused subdevice
>> |  11 | Counter subdevice
>> |  12 | Counter subdevice
>> |  13 | Counter subdevice
>>
>> - cat /proc/analogy/01-analogy_ni_pcimio
>> --  Subdevices --
>>
>> | idx | type
>> |  00 | Unused subdevice
>> |  01 | Analog output subdevice
>> |  02 | Digital input/output subdevice
>> |  03 | Unused subdevice
>> |  04 | Unused subdevice
>> |  05 | Calibration subdevice
>> |  06 | Memory subdevice
>> |  07 | Digital input/output subdevice
>> |  08 | Unused subdevice
>> |  09 | Serial subdevice
>> |  10 | Unused subdevice
>> |  11 | Counter subdevice
>> |  12 | Counter subdevice
>> |  13 | Counter subdevice
>>
>> Thanks,
>> Fernando
>
> Dear all,
>
> I have followed your advice and just tested with the following
> kernel/xenomai versions:
>
> Linux ******** 2.6.38.8-xenomai-2.6rc4 #1 SMP PREEMPT Thu Sep 29 16:17:41
> BRT 2011 x86_64 GNU/Linux
>
> Now both "cmd_read" and my own code are running, but "a4l_async_read" reads
> either garbage or either value of 0 or 0x8000. In order to make cmd_read
> work with my board I had to make the following changes to the code:
>
> --- cmd_read.c.orig    2011-09-29 16:40:50.000000000 -0300
> +++ cmd_read.c    2011-09-29 16:41:04.000000000 -0300
> @@ -66,8 +66,8 @@
>      .start_arg = 0,
>      .scan_begin_src = TRIG_TIMER,
>      .scan_begin_arg = 8000000,    /* in ns */
> -    .convert_src = TRIG_TIMER,
> -    .convert_arg = 500000,    /* in ns */
> +    .convert_src = TRIG_NOW,
> +    .convert_arg = 00000,    /* in ns */
>      .scan_end_src = TRIG_COUNT,
>      .scan_end_arg = 0,
>      .stop_src = TRIG_COUNT,
>
> otherwise the drive would complain about "the driver cmd_test failed" or
> something like that, because my board has 8 parallel ADCs.
>
> If I run my program (see attachment) and call dmesg I can see:
>
> [  641.237710] Analogy: analogy_ni_pcimio: ni_ai_cmd: start
> [  641.237718] Analogy: analogy_ni_pcimio: ni_ai_cmd:
> Interrupt_A_Enable_Register = 0x0031
> [  641.237723] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
> [  641.238874] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
> a_status=90b0 ai_mite_status=00200000
> [  641.239872] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
> a_status=9030 ai_mite_status=00200000
> [...]
> [  642.237879] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
> a_status=9070 ai_mite_status=00200000
> [  642.237881] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt
>
> I just checked my setup with our RTAI/comedi code and it is properly
> working. The input card is attached to a 3Hz sine wave generator with 1V
> peek-to-peek. If I run the attached program, the output looks like this:
>
> Analogy device analogy_ni_pcimio.
> Channel 0 has 16 bits and 1 different ranges
> 32768
> 32768
> 32768
> 32768
> 32768
> [...]
> 32768
>
> Any help on debugging this would be greatly appreciated.

With insn_read, did you manage to acquire correct values at least?

>
> Sincerely,
> Fernando
>
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help
>
>

Alexis.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-09-29 22:16       ` Alexis Berlemont
@ 2011-10-03 21:41         ` Fernando Herrero Carrón
  2011-10-04 20:29           ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-03 21:41 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 1426 bytes --]

El 30 de septiembre de 2011 00:16, Alexis Berlemont <
alexis.berlemont@domain.hid> escribió:

> Hi,
> [...]
> With insn_read, did you manage to acquire correct values at least?
>
>
Dear Alexis,

insn_read does indeed work. If I run "insn_read -S 1000" I get my input
sampled at approx 125kHz. Running cmd_read with and without '-m' only
returns 0x8000.

I have been playing around with __a4l_info and the driver code to track down
my problem. I am not familiar at all with low-level DAQ programming, so I
just followed my intuition.

I modified
buffer.c:a4l_read_buf and buffer.h:__consume

to dump the values that were being consumed from the internal buffer. There
I found the infamous 0x8000, so my conclusion is that those values are
traveling along the kernel side. I decided I would go the other way around
and modified

drivers/analogy/national_instruments/mio_common.c: handle_a_interrupt
and drivers/analogy/buffer.c: a4l_buf_evt

I guess that interrupt is being generated every time a DMA transfer has
been completed from the DAQ to analogy's internal  buffer. I dump variable
"count" in a4l_buf_evt and it always reports the appropriate byte count to
be transferred, which is "number of channels" * 2.

My guess is that the DMA transfers are being performed to the wrong place,
because the whole procedure seems to be working ok otherwise.

All help is appreciated,
Fernando

[-- Attachment #2: Type: text/html, Size: 2303 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-03 21:41         ` Fernando Herrero Carrón
@ 2011-10-04 20:29           ` Fernando Herrero Carrón
  2011-10-05 21:16             ` Alexis Berlemont
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-04 20:29 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 2044 bytes --]

El 3 de octubre de 2011 18:41, Fernando Herrero Carrón
<elferdo@domain.hid>escribió:

> El 30 de septiembre de 2011 00:16, Alexis Berlemont <
> alexis.berlemont@domain.hid> escribió:
>
>> Hi,
>> [...]
>>
>> With insn_read, did you manage to acquire correct values at least?
>>
>>
> Dear Alexis,
>
> insn_read does indeed work. If I run "insn_read -S 1000" I get my input
> sampled at approx 125kHz. Running cmd_read with and without '-m' only
> returns 0x8000.
>
> I have been playing around with __a4l_info and the driver code to track
> down my problem. I am not familiar at all with low-level DAQ programming, so
> I just followed my intuition.
>
> I modified
>  buffer.c:a4l_read_buf and buffer.h:__consume
>
> to dump the values that were being consumed from the internal buffer. There
> I found the infamous 0x8000, so my conclusion is that those values are
> traveling along the kernel side. I decided I would go the other way around
> and modified
>
> drivers/analogy/national_instruments/mio_common.c: handle_a_interrupt
> and drivers/analogy/buffer.c: a4l_buf_evt
>
> I guess that interrupt is being generated every time a DMA transfer has
> been completed from the DAQ to analogy's internal  buffer. I dump variable
> "count" in a4l_buf_evt and it always reports the appropriate byte count to
> be transferred, which is "number of channels" * 2.
>
> My guess is that the DMA transfers are being performed to the wrong place,
> because the whole procedure seems to be working ok otherwise.
>
> All help is appreciated,
> Fernando
>
>
>

Dear all,

More updates on this. I just tested both the "cmd_read" example and my own
code on the analogy_fake device. They're both working, I get a sawtooth
shape. So my guess is still that there is some error in the DMA transfer in
the NI driver(s).

Could anyone please help me indicating where DMA is setup in the NI drivers?
I'll try to have a look at it myself, but a more experienced advice would be
helpful.

Thanks,
Fernando

[-- Attachment #2: Type: text/html, Size: 3158 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-04 20:29           ` Fernando Herrero Carrón
@ 2011-10-05 21:16             ` Alexis Berlemont
  2011-10-05 23:06               ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Alexis Berlemont @ 2011-10-05 21:16 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: xenomai

Hi,

2011/10/4 Fernando Herrero Carrón <elferdo@domain.hid>:
> El 3 de octubre de 2011 18:41, Fernando Herrero Carrón <elferdo@domain.hidom>
> escribió:
>>
>> El 30 de septiembre de 2011 00:16, Alexis Berlemont
>> <alexis.berlemont@domain.hid> escribió:
>>>
>>> Hi,
>>> [...]
>>> With insn_read, did you manage to acquire correct values at least?
>>>
>>
>> Dear Alexis,
>> insn_read does indeed work. If I run "insn_read -S 1000" I get my input
>> sampled at approx 125kHz. Running cmd_read with and without '-m' only
>> returns 0x8000.
>>
>> I have been playing around with __a4l_info and the driver code to track
>> down my problem. I am not familiar at all with low-level DAQ programming, so
>> I just followed my intuition.
>>
>> I modified
>> buffer.c:a4l_read_buf and buffer.h:__consume
>>
>> to dump the values that were being consumed from the internal buffer.
>> There I found the infamous 0x8000, so my conclusion is that those values are
>> traveling along the kernel side. I decided I would go the other way around
>> and modified
>>
>> drivers/analogy/national_instruments/mio_common.c: handle_a_interrupt
>> and drivers/analogy/buffer.c: a4l_buf_evt
>>
>> I guess that interrupt is being generated every time a DMA transfer has
>> been completed from the DAQ to analogy's internal  buffer. I dump variable
>> "count" in a4l_buf_evt and it always reports the appropriate byte count to
>> be transferred, which is "number of channels" * 2.
>>
>> My guess is that the DMA transfers are being performed to the wrong place,
>> because the whole procedure seems to be working ok otherwise.
>>
>> All help is appreciated,
>> Fernando
>>
>>
>
> Dear all,
>
> More updates on this. I just tested both the "cmd_read" example and my own
> code on the analogy_fake device. They're both working, I get a sawtooth
> shape. So my guess is still that there is some error in the DMA transfer in
> the NI driver(s).
>
> Could anyone please help me indicating where DMA is setup in the NI drivers?
> I'll try to have a look at it myself, but a more experienced advice would be
> helpful.
>

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.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-05 21:16             ` Alexis Berlemont
@ 2011-10-05 23:06               ` Fernando Herrero Carrón
  2011-10-06 18:49                 ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-05 23:06 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 5040 bytes --]

El 5 de octubre de 2011 18:16, Alexis Berlemont
<alexis.berlemont@domain.hid>escribió:

> Hi,
>
> 2011/10/4 Fernando Herrero Carrón <elferdo@domain.hid>:
> > El 3 de octubre de 2011 18:41, Fernando Herrero Carrón <
> elferdo@domain.hid>
> > escribió:
> >>
> >> El 30 de septiembre de 2011 00:16, Alexis Berlemont
> >> <alexis.berlemont@domain.hid> escribió:
> >>>
> >>> Hi,
> >>> [...]
> >>> With insn_read, did you manage to acquire correct values at least?
> >>>
> >>
> >> Dear Alexis,
> >> insn_read does indeed work. If I run "insn_read -S 1000" I get my input
> >> sampled at approx 125kHz. Running cmd_read with and without '-m' only
> >> returns 0x8000.
> >>
> >> I have been playing around with __a4l_info and the driver code to track
> >> down my problem. I am not familiar at all with low-level DAQ
> programming, so
> >> I just followed my intuition.
> >>
> >> I modified
> >> buffer.c:a4l_read_buf and buffer.h:__consume
> >>
> >> to dump the values that were being consumed from the internal buffer.
> >> There I found the infamous 0x8000, so my conclusion is that those values
> are
> >> traveling along the kernel side. I decided I would go the other way
> around
> >> and modified
> >>
> >> drivers/analogy/national_instruments/mio_common.c: handle_a_interrupt
> >> and drivers/analogy/buffer.c: a4l_buf_evt
> >>
> >> I guess that interrupt is being generated every time a DMA transfer has
> >> been completed from the DAQ to analogy's internal  buffer. I dump
> variable
> >> "count" in a4l_buf_evt and it always reports the appropriate byte count
> to
> >> be transferred, which is "number of channels" * 2.
> >>
> >> My guess is that the DMA transfers are being performed to the wrong
> place,
> >> because the whole procedure seems to be working ok otherwise.
> >>
> >> All help is appreciated,
> >> Fernando
> >>
> >>
> >
> > Dear all,
> >
> > More updates on this. I just tested both the "cmd_read" example and my
> own
> > code on the analogy_fake device. They're both working, I get a sawtooth
> > shape. So my guess is still that there is some error in the DMA transfer
> in
> > the NI driver(s).
> >
> > Could anyone please help me indicating where DMA is setup in the NI
> drivers?
> > I'll try to have a look at it myself, but a more experienced advice would
> be
> > helpful.
> >
>
> 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

[-- Attachment #2: Type: text/html, Size: 6292 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-05 23:06               ` Fernando Herrero Carrón
@ 2011-10-06 18:49                 ` Fernando Herrero Carrón
  2011-10-06 21:31                   ` Alexis Berlemont
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-06 18:49 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 5112 bytes --]

El 5 de octubre de 2011 20:06, Fernando Herrero Carrón
<elferdo@domain.hid>escribió:

> El 5 de octubre de 2011 18:16, Alexis Berlemont <
> alexis.berlemont@domain.hid> 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@domain.hid

  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@domain.hid $1 = {0 <repeats 100 times>}
(gdb) n     <------------------ calls a4l_mark_bufrw()

186            if (front == 0) {

(gdb) print /x*(unsigned short *)map@domain.hid
$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?

Best regards,
Fernando

[-- Attachment #2: Type: text/html, Size: 6573 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-06 18:49                 ` Fernando Herrero Carrón
@ 2011-10-06 21:31                   ` Alexis Berlemont
  2011-10-06 22:18                     ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Alexis Berlemont @ 2011-10-06 21:31 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: Xenomai help

Hi,

2011/10/6 Fernando Herrero Carrón <elferdo@domain.hid>:
>
>
> El 5 de octubre de 2011 20:06, Fernando Herrero Carrón <elferdo@domain.hidom>
> escribió:
>>
>> El 5 de octubre de 2011 18:16, Alexis Berlemont
>> <alexis.berlemont@domain.hid> 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@domain.hid
>
>   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@domain.hid $1 = {0 <repeats 100 times>}
> (gdb) n     <------------------ calls a4l_mark_bufrw()
>
> 186            if (front == 0) {
>
> (gdb) print /x*(unsigned short *)map@domain.hid
> $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.

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.

Best regards,

Alexis.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-06 21:31                   ` Alexis Berlemont
@ 2011-10-06 22:18                     ` Fernando Herrero Carrón
  2011-10-07 22:06                       ` Alexis Berlemont
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-06 22:18 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 9152 bytes --]

El 6 de octubre de 2011 18:31, Alexis Berlemont
<alexis.berlemont@domain.hid>escribió:

> Hi,
>
> 2011/10/6 Fernando Herrero Carrón <elferdo@domain.hid>:
> >
> >
> > El 5 de octubre de 2011 20:06, Fernando Herrero Carrón <
> elferdo@domain.hid>
> > escribió:
> >>
> >> El 5 de octubre de 2011 18:16, Alexis Berlemont
> >> <alexis.berlemont@domain.hid> 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@domain.hid
> >
> >   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@domain.hid $1 = {0 <repeats 100 times>}
> > (gdb) n     <------------------ calls a4l_mark_bufrw()
> >
> > 186            if (front == 0) {
> >
> > (gdb) print /x*(unsigned short *)map@domain.hid
> > $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@domain.hid
$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@domain.hid
$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@domain.hid
$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

[-- Attachment #2: Type: text/html, Size: 11764 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-06 22:18                     ` Fernando Herrero Carrón
@ 2011-10-07 22:06                       ` Alexis Berlemont
  2011-10-10 15:27                         ` Fernando Herrero Carrón
  0 siblings, 1 reply; 21+ messages in thread
From: Alexis Berlemont @ 2011-10-07 22:06 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: Xenomai help

Hi,

2011/10/7 Fernando Herrero Carrón <elferdo@domain.hid>:
> El 6 de octubre de 2011 18:31, Alexis Berlemont <alexis.berlemont@domain.hidom>
> escribió:
>>
>> Hi,
>>
>> 2011/10/6 Fernando Herrero Carrón <elferdo@domain.hid>:
>> >
>> >
>> > El 5 de octubre de 2011 20:06, Fernando Herrero Carrón
>> > <elferdo@domain.hid>
>> > escribió:
>> >>
>> >> El 5 de octubre de 2011 18:16, Alexis Berlemont
>> >> <alexis.berlemont@domain.hid> 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@domain.hid
>> >
>> >   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@domain.hid $1 = {0 <repeats 100 times>}
>> > (gdb) n     <------------------ calls a4l_mark_bufrw()
>> >
>> > 186            if (front == 0) {
>> >
>> > (gdb) print /x*(unsigned short *)map@domain.hid
>> > $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@domain.hid
> $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@domain.hid
> $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@domain.hid
> $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.

I may have an idea thanks to your additional test. I cant' figure out
how a DMA controller could perform a or / add operation on memory with
one single write shot; so, this operation must be done by the CPU.

The only way for the CPU to interfere is through a munge operaiton,
let's have a look at ni_ai_munge16:

static void ni_ai_munge16(a4l_subd_t *subd, void *buf, unsigned long size)
{
	a4l_dev_t *dev = subd->dev;
	a4l_cmd_t *cmd = a4l_get_cmd(subd);
	int chan_idx = a4l_get_chan(subd);
	unsigned int i;
	sampl_t *array = buf;

	for (i = 0; i < size / sizeof(sampl_t); i++) {
#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
     defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
		array[i] = le16_to_cpu(array[i]);
#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */

###### HERE
		array[i] += devpriv->ai_offset[chan_idx];
######## HERE

		chan_idx++;
		chan_idx %= cmd->nb_chan;
	}
}

According to the code in ni_load_channelgain_list, I think ai_offset
is set to 0x8000 in your case.

Could you empty the function ni_ai_munge16 and check that the buffer
is not modified anymore?

If it is the case, let's go back to your first theory: the DMA controller.

Alexis.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-07 22:06                       ` Alexis Berlemont
@ 2011-10-10 15:27                         ` Fernando Herrero Carrón
  2011-10-11 22:12                           ` Alexis Berlemont
  0 siblings, 1 reply; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-10 15:27 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 14724 bytes --]

El 7 de octubre de 2011 19:06, Alexis Berlemont
<alexis.berlemont@domain.hid>escribió:

> Hi,
>
> 2011/10/7 Fernando Herrero Carrón <elferdo@domain.hid>:
> > El 6 de octubre de 2011 18:31, Alexis Berlemont <
> alexis.berlemont@domain.hid>
> > escribió:
> >>
> >> Hi,
> >>
> >> 2011/10/6 Fernando Herrero Carrón <elferdo@domain.hid>:
> >> >
> >> >
> >> > El 5 de octubre de 2011 20:06, Fernando Herrero Carrón
> >> > <elferdo@domain.hid>
> >> > escribió:
> >> >>
> >> >> El 5 de octubre de 2011 18:16, Alexis Berlemont
> >> >> <alexis.berlemont@domain.hid> 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@domain.hid
> >> >
> >> >   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@domain.hid $1 = {0 <repeats 100 times>}
> >> > (gdb) n     <------------------ calls a4l_mark_bufrw()
> >> >
> >> > 186            if (front == 0) {
> >> >
> >> > (gdb) print /x*(unsigned short *)map@domain.hid
> >> > $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@domain.hid
> > $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@domain.hid
> > $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@domain.hid
> > $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.
>
> I may have an idea thanks to your additional test. I cant' figure out
> how a DMA controller could perform a or / add operation on memory with
> one single write shot; so, this operation must be done by the CPU.
>
> The only way for the CPU to interfere is through a munge operaiton,
> let's have a look at ni_ai_munge16:
>
> static void ni_ai_munge16(a4l_subd_t *subd, void *buf, unsigned long size)
> {
>        a4l_dev_t *dev = subd->dev;
>        a4l_cmd_t *cmd = a4l_get_cmd(subd);
>        int chan_idx = a4l_get_chan(subd);
>        unsigned int i;
>        sampl_t *array = buf;
>
>        for (i = 0; i < size / sizeof(sampl_t); i++) {
> #if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
>     defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
>                array[i] = le16_to_cpu(array[i]);
> #endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
>
> ###### HERE
>                array[i] += devpriv->ai_offset[chan_idx];
> ######## HERE
>
>                chan_idx++;
>                chan_idx %= cmd->nb_chan;
>        }
> }
>
> According to the code in ni_load_channelgain_list, I think ai_offset
> is set to 0x8000 in your case.
>
> Could you empty the function ni_ai_munge16 and check that the buffer
> is not modified anymore?
>
> If it is the case, let's go back to your first theory: the DMA controller.
>
>
Dear Alexis,

Yes, I commented out that line you mentioned and indeed the buffer is now
filled with 0x0f0f instead of 0x8f0f. So yes, I still suspect it has to do
with the DMA transfers.

Recalling, it seems that everything is working with the DMA except this very
point. I mean, I set my board to transfer data at the end of every scan
(with .flags = TRIG_WAKE_EOS) and I program a given frequency, say 1kHz. The
dmesg reports an interrupt from the board with the right timing and my
"a4l_async_read()" call gets unblocked apparently with the right timing as
well. At the end of buffer.c:a4l_buf_evt() I dump the value of "count",
which reports the number of bytes transferred in the current event, and it
reports the expected value (except in some cases, which I will comment on a
separate mail).

So I would like to check the following points:

- Check that the subdevice's buffer is properly configured when the device
is set up and/or when the command is launched.

- Check that the DMA programming is actually using that buffer.

- Check that the read operation is accessing the right buffer as well.

I can't think of many other things going wrong. While writing this email I
have thought of some further tests, so here is the result :)

I have changed the size of the default buffer using analogy_config. First, I
have specified:

sudo /usr/xenomai/sbin/analogy_config -v analogy0 -S 4

Then I have run cmd_read, with the same results, but I have dumped some
values at "ni_ai_setup_MITE_dma()" and at a4l_buf_evt():

[ 3115.793026] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: beginning
[ 3115.793029] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: buf->buf:
ffffc90001893000; buf->end_count 800; buf->prd_count 0; buf->cns_count 0;
buf->tmp_count 0
[ 3115.793035] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
[ 3116.593187] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
a_status=90f0 ai_mite_status=00200000
[ 3116.593189] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt
[ 3116.593191] Analogy: Signalling event. Available data to user: 800. Two
first bytes in buffer: 15d 15d. Buffer pointer: ffffc90001893000

Now I changed the size of the buffer to 8, which aparently resulted in a
buffer reallocation:

[ 3119.523172] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: beginning
[ 3119.523175] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: buf->buf:
ffffc9000189b000; buf->end_count 800; buf->prd_count 0; buf->cns_count 0;
buf->tmp_count 0
[ 3119.523181] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
[ 3120.323332] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
a_status=90f0 ai_mite_status=00200000
[ 3120.323335] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt
[ 3120.323336] Analogy: Signalling event. Available data to user: 800. Two
first bytes in buffer: 15d 15d. Buffer pointer: ffffc9000189b000

I don't know if this is really useful, but this is proving that at least
"ni_ai_setup_MITE_dma()" and "a4l_buf_evt()" are consistent in their notion
of buffer.

Best regards,
Fernando

[-- Attachment #2: Type: text/html, Size: 18857 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-10 15:27                         ` Fernando Herrero Carrón
@ 2011-10-11 22:12                           ` Alexis Berlemont
  2011-10-11 22:21                             ` Gilles Chanteperdrix
                                               ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Alexis Berlemont @ 2011-10-11 22:12 UTC (permalink / raw)
  To: Fernando Herrero Carrón; +Cc: Xenomai help

Hi,

Sorry for answering late.

2011/10/10 Fernando Herrero Carrón <elferdo@domain.hid>:
>
>
> El 7 de octubre de 2011 19:06, Alexis Berlemont <alexis.berlemont@domain.hidom>
> escribió:
>>
>> Hi,
>>
>> 2011/10/7 Fernando Herrero Carrón <elferdo@domain.hid>:
>> > El 6 de octubre de 2011 18:31, Alexis Berlemont
>> > <alexis.berlemont@domain.hid>
>> > escribió:
>> >>
>> >> Hi,
>> >>
>> >> 2011/10/6 Fernando Herrero Carrón <elferdo@domain.hid>:
>> >> >
>> >> >
>> >> > El 5 de octubre de 2011 20:06, Fernando Herrero Carrón
>> >> > <elferdo@domain.hid>
>> >> > escribió:
>> >> >>
>> >> >> El 5 de octubre de 2011 18:16, Alexis Berlemont
>> >> >> <alexis.berlemont@domain.hid> 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@domain.hid
>> >> >
>> >> >   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@domain.hid $1 = {0 <repeats 100 times>}
>> >> > (gdb) n     <------------------ calls a4l_mark_bufrw()
>> >> >
>> >> > 186            if (front == 0) {
>> >> >
>> >> > (gdb) print /x*(unsigned short *)map@domain.hid
>> >> > $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@domain.hid
>> > $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@domain.hid
>> > $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@domain.hid
>> > $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.
>>
>> I may have an idea thanks to your additional test. I cant' figure out
>> how a DMA controller could perform a or / add operation on memory with
>> one single write shot; so, this operation must be done by the CPU.
>>
>> The only way for the CPU to interfere is through a munge operaiton,
>> let's have a look at ni_ai_munge16:
>>
>> static void ni_ai_munge16(a4l_subd_t *subd, void *buf, unsigned long size)
>> {
>>        a4l_dev_t *dev = subd->dev;
>>        a4l_cmd_t *cmd = a4l_get_cmd(subd);
>>        int chan_idx = a4l_get_chan(subd);
>>        unsigned int i;
>>        sampl_t *array = buf;
>>
>>        for (i = 0; i < size / sizeof(sampl_t); i++) {
>> #if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
>>     defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
>>                array[i] = le16_to_cpu(array[i]);
>> #endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
>>
>> ###### HERE
>>                array[i] += devpriv->ai_offset[chan_idx];
>> ######## HERE
>>
>>                chan_idx++;
>>                chan_idx %= cmd->nb_chan;
>>        }
>> }
>>
>> According to the code in ni_load_channelgain_list, I think ai_offset
>> is set to 0x8000 in your case.
>>
>> Could you empty the function ni_ai_munge16 and check that the buffer
>> is not modified anymore?
>>
>> If it is the case, let's go back to your first theory: the DMA controller.
>>
>
> Dear Alexis,
>
> Yes, I commented out that line you mentioned and indeed the buffer is now
> filled with 0x0f0f instead of 0x8f0f. So yes, I still suspect it has to do
> with the DMA transfers.
>
> Recalling, it seems that everything is working with the DMA except this very
> point. I mean, I set my board to transfer data at the end of every scan
> (with .flags = TRIG_WAKE_EOS) and I program a given frequency, say 1kHz. The
> dmesg reports an interrupt from the board with the right timing and my
> "a4l_async_read()" call gets unblocked apparently with the right timing as
> well. At the end of buffer.c:a4l_buf_evt() I dump the value of "count",
> which reports the number of bytes transferred in the current event, and it
> reports the expected value (except in some cases, which I will comment on a
> separate mail).
>
> So I would like to check the following points:
>
> - Check that the subdevice's buffer is properly configured when the device
> is set up and/or when the command is launched.
>
> - Check that the DMA programming is actually using that buffer.
>
> - Check that the read operation is accessing the right buffer as well.
>
> I can't think of many other things going wrong. While writing this email I
> have thought of some further tests, so here is the result :)
>
> I have changed the size of the default buffer using analogy_config. First, I
> have specified:
>
> sudo /usr/xenomai/sbin/analogy_config -v analogy0 -S 4
>
> Then I have run cmd_read, with the same results, but I have dumped some
> values at "ni_ai_setup_MITE_dma()" and at a4l_buf_evt():
>
> [ 3115.793026] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: beginning
> [ 3115.793029] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: buf->buf:
> ffffc90001893000; buf->end_count 800; buf->prd_count 0; buf->cns_count 0;
> buf->tmp_count 0
> [ 3115.793035] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
> [ 3116.593187] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
> a_status=90f0 ai_mite_status=00200000
> [ 3116.593189] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt
> [ 3116.593191] Analogy: Signalling event. Available data to user: 800. Two
> first bytes in buffer: 15d 15d. Buffer pointer: ffffc90001893000
>
> Now I changed the size of the buffer to 8, which aparently resulted in a
> buffer reallocation:
>
> [ 3119.523172] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: beginning
> [ 3119.523175] Analogy: analogy_ni_pcimio: ni_ai_setup_MITE_dma: buf->buf:
> ffffc9000189b000; buf->end_count 800; buf->prd_count 0; buf->cns_count 0;
> buf->tmp_count 0
> [ 3119.523181] Analogy: analogy_ni_pcimio: ni_ai_cmd: exit
> [ 3120.323332] Analogy: analogy_ni_pcimio: ni_mio_common: interrupt:
> a_status=90f0 ai_mite_status=00200000
> [ 3120.323335] Analogy: analogy_ni_pcimio: ni_mio_common: SC_TC interrupt
> [ 3120.323336] Analogy: Signalling event. Available data to user: 800. Two
> first bytes in buffer: 15d 15d. Buffer pointer: ffffc9000189b000
>
> I don't know if this is really useful, but this is proving that at least
> "ni_ai_setup_MITE_dma()" and "a4l_buf_evt()" are consistent in their notion
> of buffer.
>

I took some time to compare both versions of code (comedi and
analogy). I did not find anything interesting in mite.c. I was about
to ask you to increase verbosity (debug + a specific patch) when I got
a glimpse on the allocation of the asynchronous buffer on the comedi
side.

The methods are not the same at that level:
- comedi: n * dma_alloc_coherent  + a vmap at the end
- analogy:  a big vmalloc + n * page_to_phys(vmalloc_to_page(vaddr)

I don't understand the reason why the analogy way is not correct, I
did not have time to check yet. If anyone has any idea, please help
me.

However, the NI mite expects 32 bit addresses... (because of
cpu_to_le32 in the mite driver).

If I remember well, you are using a 64-bit architecture. Is it
correct? There may be a bug here; analogy might give to the mite
physical addresses which are not below 2^32.

So, could you:
- with comedi, add some printk("%lx") in mite_buf_change so as to dump
the pages physical addresses
- with analogy, do the same thing in a4l_mite_buf_change.

Or you can test on another machine.

So far, I got only remote access on a 32 bit machine in which there is
a NI card; I must have missed something...

> Best regards,
> Fernando
>
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help
>
>

Best regards,

Alexis.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-11 22:12                           ` Alexis Berlemont
@ 2011-10-11 22:21                             ` Gilles Chanteperdrix
  2011-10-11 23:08                               ` Alexis Berlemont
  2011-10-12 16:00                             ` Fernando Herrero Carrón
  2011-10-12 19:13                             ` Fernando Herrero Carrón
  2 siblings, 1 reply; 21+ messages in thread
From: Gilles Chanteperdrix @ 2011-10-11 22:21 UTC (permalink / raw)
  To: Alexis Berlemont; +Cc: Xenomai help

On 10/12/2011 12:12 AM, Alexis Berlemont wrote:
> The methods are not the same at that level:
> - comedi: n * dma_alloc_coherent  + a vmap at the end
> - analogy:  a big vmalloc + n * page_to_phys(vmalloc_to_page(vaddr)

I do not know if that makes a difference, but the result of
dma_alloc_coherent is memory physically contiguous, whereas it is not
the case for memory returned by vmalloc.

dma_alloc_coherent also allows the GFP_DMA32 flag if you want 32 bits
memory.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-11 22:21                             ` Gilles Chanteperdrix
@ 2011-10-11 23:08                               ` Alexis Berlemont
  0 siblings, 0 replies; 21+ messages in thread
From: Alexis Berlemont @ 2011-10-11 23:08 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai help

Hi,

2011/10/12 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>:
> On 10/12/2011 12:12 AM, Alexis Berlemont wrote:
>> The methods are not the same at that level:
>> - comedi: n * dma_alloc_coherent  + a vmap at the end
>> - analogy:  a big vmalloc + n * page_to_phys(vmalloc_to_page(vaddr)
>
> I do not know if that makes a difference, but the result of
> dma_alloc_coherent is memory physically contiguous, whereas it is not
> the case for memory returned by vmalloc

I don't think comedi guys are using dma_alloc_coherent() for
contiguity: they are asking for PAGE_SIZE many times; they just want
blocks of 4KB (like analogy, I think).
.
>
> dma_alloc_coherent also allows the GFP_DMA32 flag if you want 32 bits
> memory.
The striking point is that the flags used are GFP_KERNEL | __GFP_COMP
not GFP_DMA32... . There might be a bug in Comedi too, which has not
occured yet.
Have you already used __GFP_COMP (/* Add compound page metadata */)?

Many thanks for your help.

Alexis.

>
> --
>                                                                Gilles.
>


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-11 22:12                           ` Alexis Berlemont
  2011-10-11 22:21                             ` Gilles Chanteperdrix
@ 2011-10-12 16:00                             ` Fernando Herrero Carrón
  2011-10-12 19:13                             ` Fernando Herrero Carrón
  2 siblings, 0 replies; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-12 16:00 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 2887 bytes --]

El 11 de octubre de 2011 19:12, Alexis Berlemont <alexis.berlemont@domain.hidm
> escribió:

> Hi,
>
> Sorry for answering late.
>

Well, thanks for answering ;)


>
> I took some time to compare both versions of code (comedi and
> analogy). I did not find anything interesting in mite.c. I was about
> to ask you to increase verbosity (debug + a specific patch) when I got
> a glimpse on the allocation of the asynchronous buffer on the comedi
> side.
>
> The methods are not the same at that level:
> - comedi: n * dma_alloc_coherent  + a vmap at the end
> - analogy:  a big vmalloc + n * page_to_phys(vmalloc_to_page(vaddr)
>
> I don't understand the reason why the analogy way is not correct, I
> did not have time to check yet. If anyone has any idea, please help
> me.
>
> However, the NI mite expects 32 bit addresses... (because of
> cpu_to_le32 in the mite driver).
>
> If I remember well, you are using a 64-bit architecture. Is it
> correct? There may be a bug here; analogy might give to the mite
> physical addresses which are not below 2^32.
>

That's right, I'm on a 64bit machine. This sounds very reasonable to me.


> So, could you:
> - with comedi, add some printk("%lx") in mite_buf_change so as to dump
> the pages physical addresses
> - with analogy, do the same thing in a4l_mite_buf_change.
>

Ok, I'v only performed the analogy tests so far, and here are the results:

[  172.627662] Analogy: sizeof(dma_addr_t) = 8
[  172.627663] Analogy: ring->descriptors_dma_addr = c740d000
[  172.627665] Analogy: cpu_to_le32(ring->descriptors_dma_addr) = c740d000
[  172.627666] Analogy: buf->pg_list[0] = 19d806000
[  172.627667] Analogy: buf->pg_list[1] = 1a9095000
[  172.627668] Analogy: buf->pg_list[2] = 19d552000
[  172.627669] Analogy: buf->pg_list[3] = 19eb93000
[  172.627671] Analogy: buf->pg_list[4] = 1a91fc000
[  172.627672] Analogy: buf->pg_list[5] = 1a9203000
[  172.627673] Analogy: buf->pg_list[6] = 19d9c1000
[  172.627674] Analogy: buf->pg_list[7] = 19ebff000
[  172.627675] Analogy: buf->pg_list[8] = 19eacb000
[  172.627676] Analogy: buf->pg_list[9] = 1a905d000
[  172.627677] Analogy: buf->pg_list[10] = 1a9050000
[  172.627678] Analogy: buf->pg_list[11] = 1a9174000
[  172.627679] Analogy: buf->pg_list[12] = 1aa791000
[  172.627680] Analogy: buf->pg_list[13] = 1aa635000
[  172.627682] Analogy: buf->pg_list[14] = 1aa7fb000
[  172.627683] Analogy: buf->pg_list[15] = 19dae5000

These are printed right after the call to "pci_alloc_consistent()" and in
the subsequent "for" loop. So if I understand it right,
"ring->descriptors_dma_addr" represents the base physical address that DMA
transfers will access? And then, "buf->pg_list" are virtual addresses or
virtual page indexes?

I'll check those values in comedi and let you know.

Thanks a lot for your effort!

Fernando

[-- Attachment #2: Type: text/html, Size: 3940 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Xenomai-help] Command code working with comedi not working with analogy
  2011-10-11 22:12                           ` Alexis Berlemont
  2011-10-11 22:21                             ` Gilles Chanteperdrix
  2011-10-12 16:00                             ` Fernando Herrero Carrón
@ 2011-10-12 19:13                             ` Fernando Herrero Carrón
  2 siblings, 0 replies; 21+ messages in thread
From: Fernando Herrero Carrón @ 2011-10-12 19:13 UTC (permalink / raw)
  To: Xenomai help

[-- Attachment #1: Type: text/plain, Size: 2614 bytes --]

El 11 de octubre de 2011 19:12, Alexis Berlemont <alexis.berlemont@domain.hidm
> escribió:
[...]


>  I took some time to compare both versions of code (comedi and
> analogy). I did not find anything interesting in mite.c. I was about
> to ask you to increase verbosity (debug + a specific patch) when I got
> a glimpse on the allocation of the asynchronous buffer on the comedi
> side.
>
> The methods are not the same at that level:
> - comedi: n * dma_alloc_coherent  + a vmap at the end
> - analogy:  a big vmalloc + n * page_to_phys(vmalloc_to_page(vaddr)
>

Hmmm, quoting http://www.mjmwired.net/kernel/Documentation/DMA-mapping.txt:


If you acquired your memory via the page allocator
(i.e. __get_free_page*()) or the generic memory allocators
(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
that memory using the addresses returned from those routines.

This means specifically that you may _not_ use the memory/addresses

returned from vmalloc() for DMA.  It is possible to DMA to the
_underlying_ memory mapped into a vmalloc() area, but this requires
walking page tables to get the physical addresses, and then

translating each of those pages back to a kernel address using
something like __va().  [ EDIT: Update this when we integrate
Gerd Knorr's generic code which does this. ]


So, I guess analogy indeed took the walking approach mentioned there? If I
understand it right, the following loop in "a4l_buf_alloc()":

for (vaddr = vabase; vaddr < vabase + buf_desc->size;
         vaddr += PAGE_SIZE)
        buf_desc->pg_list[(vaddr - vabase) >> PAGE_SHIFT] =
            (unsigned long) page_to_phys(vmalloc_to_page(vaddr));

does exactly this, by holding a list of the physical addresses of all the
logical pages of the buffer, even if they may be non-contiguous. Then, the
MITE is able to scatter data across the ring descriptors calculated in
a4l_mite_buf_change()? What is the benefit of using vmalloc? Copying from/to
user space is easier so?

According to my previous test, the addresses calculated are all indeed
larger than 2^32. This makes sense as well, since this machine appears to
have 6GB of memory:

[    0.000000] Memory: 5992084k/7208960k available (5325k kernel code,
919428k absent, 297448k reserved, 3285k data, 920k init)

The comedi drivers and kernel were not installed by myself, so reinstalling
them is somewhat more involved. If you still feel it would be useful to
check them out I will reinstall them, but this looks to me like the possible
source of the problem.

Best regards,
Fernando

[-- Attachment #2: Type: text/html, Size: 3481 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2011-10-12 19:13 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-27 18:55 [Xenomai-help] Command code working with comedi not working with analogy Fernando Herrero Carrón
2011-09-27 21:02 ` Gilles Chanteperdrix
2011-09-28  7:33 ` Julien Delange
2011-09-28 15:19   ` Fernando Herrero Carrón
2011-09-29 19:57     ` Fernando Herrero Carrón
2011-09-29 22:16       ` Alexis Berlemont
2011-10-03 21:41         ` Fernando Herrero Carrón
2011-10-04 20:29           ` Fernando Herrero Carrón
2011-10-05 21:16             ` Alexis Berlemont
2011-10-05 23:06               ` Fernando Herrero Carrón
2011-10-06 18:49                 ` Fernando Herrero Carrón
2011-10-06 21:31                   ` Alexis Berlemont
2011-10-06 22:18                     ` Fernando Herrero Carrón
2011-10-07 22:06                       ` Alexis Berlemont
2011-10-10 15:27                         ` Fernando Herrero Carrón
2011-10-11 22:12                           ` Alexis Berlemont
2011-10-11 22:21                             ` Gilles Chanteperdrix
2011-10-11 23:08                               ` Alexis Berlemont
2011-10-12 16:00                             ` Fernando Herrero Carrón
2011-10-12 19:13                             ` Fernando Herrero Carrón
2011-09-28 15:37   ` Fernando Herrero Carrón

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.