From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Programming Analog Input Registers for MSeries NI-6221

I am trying to understand the Preliminary M Series Register Map in order to correctly setup and acquire data from the Analog Input channels of my PCX-6221 card. I have been able to figure out the DIO locations and use them but I am having trouble understanding what I have to do to configure and acquire data using the Analog Input registers of the card. I need to program at this level for an RTX application using Microsoft Visual Studio Net 2003 and have had great success doing so with other NI Cards. I have tried looking at the examples provided by the MDDK but I haven't been able to create a environment that allows me to compile them with Chipobjects and it appears like alot of the work is hidden by the subroutines.
 
I wonder if someone had a high level algorithum using the Register Map it would help out alot.
 
Questions:
 
How would I create a multiple channel Scan List and load it into the card setting gain etc...
How would I configure the card to acquire continously at a specified freq (ex 1000 samples a sec)
How would I start/stop acquisition
 
I would guess getting the status of the FIFO and accessing the FIFO is a matter of reading the AI_STATUS_1 and AI_FIFO_DATA locations
 
Would looking at the Register Programming Manual for the "E" Series help me or just get me more confused?
 
Thanks in advance for any light you can shed on the subject.
 
Floyd
 
 
 
 
0 Kudos
Message 1 of 18
(12,200 Views)
You're not the first to complain about the lackluster Documentation support for the M-Series, and you certainly won't be the last.

I've found that the E-Series manual, coupled with the M-Series register map & code examples is pretty close to all you need to get a working setup. The M-Series register map isn't complete, so you'll have to fill in the holes with the headers from the m-series ddk and examples. But the registers and their usage map nearly one-to-one. The m-series source code is near-identical in function, though it differs in language (c++ instead of c), and the m-series can write directly to the registers instead of using windowed_mode_read/write.

Most everything else (with the exception of my channel offset issue, it seems) can be found here on the message board. But I'd wade through the code examples first.
----
Rob Dotson
Asst. Research Scientist
Center for Neural Science
New York University
0 Kudos
Message 2 of 18
(12,197 Views)

Hi Rob

Thanks for your response, I have decided to try and dissect the example code in aiex1.cpp in the DDK and had a few questions.

In this Thread someone responded

>> -The offsets for the various registers always refer to BAR1 as the base address.

>> -M Series do not use windowed mode.  It was determined that direct mode addressing was better for several reasons, so that was implemented for M Series.

I have inherited code that works on 65xx cards which I am pretty sure uses windowed mode that I am using in this 6221 driver. I have found that I can set the PLL registers to act as DIO and I can read the Discrete inputs just fine. Makes me curious, if Windowed mode is not used doesn't that mean the addresses are relative to the BAR1 address? Why then am I able to read the DIO?

Also starting with Clock_and_FOUT according to the example I set it for Slow_Internal_Timebase. But when I read back that Address it is always zero. According to the register map it is a "write". Does that mean I can't read it's contents? Or do I seem to have a problem because I am trying to use windowed mode with this card.

Appreciate any light anyone can shed, I hope I know enough to ask the right questions.

 

Floyd

 

 

 

 

0 Kudos
Message 3 of 18
(12,172 Views)

Hi Floyd-

Let me address your questions individually:

 

  • How would I create a multiple channel Scan List and load it into the card setting gain etc...

A multi-channel scanlist can be created as shown in the method aiConfigureChannel() from ai.cpp in the M Series MHDDK \Examples folder.  Note that the other operations leading up that point (notably, aiClearConfigurationMemory() must be performed in the order shown in the various AI examples.  aiex3.cpp is the most useful starting point for investigation, in my opinion.

  • How would I configure the card to acquire continously at a specified freq (ex 1000 samples a sec)

aiex3.cpp shows how to setup the device and its DMA controller (aka the "MITE") for DMA operation.  In order to configure for continuous operation you set the "continous" flag in that example to kTrue.  The effect of that setting is to program the STC-II to generate either a finite or continuous AI sample clock.  This programming is performed in the function aiNumberOfSamples() from ai.cpp and has the effect of setting the appropriate bitfield for continuous operation in the AI_Mode_1 register. 

Earlier in your post you asked if the STC Technical Reference Manual ( http://digital.ni.com/manuals.nsf/websearch/E929838D7D0EE50986256728007FEADF ) would be a good reference.  In fact, it's a great reference from the perspective of understanding the bitfield/register names and understanding the basics of how the timing hardware works (for example BC, UC and other sample counters are all functionally equivalent in the STC and STC-II).  From the perspective of actual register writes and reads, the functionality is different between E Series and M Series.  The biggest difference, as another forum user alluded, is that we map and write directly to the registers on M Series so Windowed_Mode reads and writes are no longer necessary.

Another difference between STC and STC-II is that the STC-II uses NI TIO-style counter/timers.  For that reason, the NI 660x RLP manual ( http://digital.ni.com/manuals.nsf/websearch/4CE1C778F442B01386256C870060F9F3  ) would be a good reference for M Series counter/timer operations.

  • How would I start/stop acquisition

Assuming you don't need an external start trigger, you only need to write to the strobe bit AI_Command_2->AI_START1_Pulse.  This will create a single start trigger pulse internally.  The differences between AI_START1 and AI_START are described in the STC Technical Reference Manual.

A finite acquisition would be stopped automatically by the AI timing engine based on the number of samples you program via the method shown in aiNumberOfSamples().  Continuous AI would be stopped by first stopping the DMA operation and then calling aiReset().

  •  I would guess getting the status of the FIFO and accessing the FIFO is a matter of reading the AI_STATUS_1 and AI_FIFO_DATA locations

Yes, this would work but I would strongly suggest using DMA as shown in aiex3.cpp.  If you want to use "programmed I/O" to read the FIFO data directly, that method is shown in aiex2.cpp

  •  Would looking at the Register Programming Manual for the "E" Series help me or just get me more confused?

In many cases it would be very helpful.  See my comments, above.

  • I have inherited code that works on 65xx cards which I am pretty sure uses windowed mode that I am using in this 6221 driver. I have found that I can set the PLL registers to act as DIO and I can read the Discrete inputs just fine. Makes me curious, if Windowed mode is not used doesn't that mean the addresses are relative to the BAR1 address? Why then am I able to read the DIO?

I'm not sure why this would work- it's possible that some legacy functionality is still working due to the way you access the hardware in your code.  For full functionality with M Series you must use mapped memory I/O to write and read from the device's registers.

  • Also starting with Clock_and_FOUT according to the example I set it for Slow_Internal_Timebase. But when I read back that Address it is always zero. According to the register map it is a "write". Does that mean I can't read it's contents? Or do I seem to have a problem because I am trying to use windowed mode with this card.

Yes, the "write" registers are write-only and the "read" registers are read-only.  The effect of data read from or written to "write" or "read" registers, respectively, is undefined.


 

 
Hopefully this helps-
Tom W
National Instruments
0 Kudos
Message 4 of 18
(12,110 Views)
Hi Tom
Thanks for your response, I appreciate it. I am figuring that the best approach for me to learn this card would be to, as you suggested, look at the example code provided in the DDK. I have been trying to figure out how to compile it in Visual Studio Net 2003 but so far have run into a few roadblocks.
 
There are references to header files such as osibus.h and others in the code and the makefile shows paths to the chipobjects and examples directory which I see are included in the DDK but I am having trouble figuring out how to get the environment etc.. together in Visual Studio Net in order to get it to work. I was wondering if you or any of you folks out there have been able to create a project succesfully or give me instructions on how I might do so.
 
Thanks again
 
Floyd
 
0 Kudos
Message 5 of 18
(12,025 Views)

Hi Floyd-

I would recommend building from the command line rather than trying to replicate the build environment in Visual Studio.  We have already developed the Makefile(s) necessary for just this purpose.

The good news is that you can still use the C++ compiler provided by Visual Studio, and the Visual Studio installation actually provides a neat little utility that can help with the process.  I use the Visual Studio Command Prompt (on my machine it's linked from the start menu, under Visual Studio>>Visual Studio tools). 

In order to invoke 'make' from the command line you'll need some kind of Windows port of that utility.  I use UnxUtils.  You just need to download that util package and unzip it so that the the included utilities are available in your path.

You'll need to unzip all of the MHDDK source so that they appear at the same level (i.e. ./nimseries/... ./dma/... ./osinterface/... etc) and then invoke 'make' from within the Visual Studio Command Prompt in the ./nimseries directory.  The Makefile there should take care of the rest.

Hopefully this helps-



Message Edited by Tom W [DE] on 02-12-2008 03:45 PM
Tom W
National Instruments
Message 6 of 18
(12,019 Views)
hi again Tom
Thanks for your patience
 
I've got the Visual Studio Command Prompt and I downloaded the Unixutils and I am finally able to get some reaction to the make. However you stated, and there are paths givin in the makefile that do not exist in the version of the DDK code that I have. (just redownloaded them again from your website to make sure)
 
You Said:

>>You'll need to unzip all of the MHDDK source so that they appear at the same level (i.e. ./nimseries/... ./dma/... >>./osinterface/... etc) and then invoke 'make' from within the Visual Studio Command Prompt in the ./nimseries directory.  >>The Makefile there should take care of the rest.

My directory structure is

c:\nimseries\

.....................ChipObjects

                     |....................................nimdbg

.....................Examples

there is no DMA directory or osinterface directory

no osiBus

In my makefile these statements point to paths I don't have (I don't think)

OSINTERFACE_DIR := ../nimhddk_visa
OSINTERFACE_MAKEFILE := win-visa.mak
include $(OSINTERFACE_DIR)/$(OSINTERFACE_MAKEFILE)

Have I the correct files? Or am I missing some parts I need to have

If I remove the DMA support from the Makefile when I run "make" it responds that there are no targets but no other errors

when I include them in the Makefile I get the following messages

../dma/dma.mak: No such file or directory

../nimhddk_visa/win-Visa.mak: No such file or directory

No Rule to make Target

 

Again thanks for bearing with me

 

Floyd

 

 

 

 

0 Kudos
Message 7 of 18
(12,013 Views)
Hi Floyd-
 
Ah, so you're actually missing the O/S interface and DMA files that you will need to have.  They're absolutely essential and can be downloaded from the same MHDDK download site.  You will want the "generic DMA library" and RTX "bus interface component"
 
Adding the RTX component will also require some changes to the nimseries Makefile; you'll have to modify the paths to OSINTERFACE_DIR and OSINTERFACE_MAKEFILE to reflect those used in the RTX O/S interface (aka bus interface component) files.
Tom W
National Instruments
0 Kudos
Message 8 of 18
(12,009 Views)

Woo Hoo!

Thanks Tom

I was able to compile both in RTX and Windows. This should be a big leap forward. Again much appreciate your assistance in this,

 

 

0 Kudos
Message 9 of 18
(12,005 Views)

Hi Again

As I have noted I have been successful in getting the Analog Input Examples to compile and execute both in win-visa and RTX but I have been unsuccessful in getting any good data from the card. aiex1, 2 and 3 are returning 32767 counts for a 2 volt differential signal in A0/A8 input pins. I can use the Test Panel for the 6221 card in MAX and it all works fine although I must first "Reset" the device if I have run the example code prior to calling up the test panel.

I have found some notes that I will not need the AdcReset routine for a 6221 card and there was a comment that 80 should be used for a Time Divisor? I am wondering if there are any other modifications that I need to do to the example code for it to work with a 6221 card?

Also note that I am using a PXI-6221 which resides in a remote chassis bridged to my PC using MXI-4. I have no idea if that should affect anything as it has been really transparent to all the rest of the cards I am using.

Again any help you can provide I will be eternally grateful.

 

 

 

 

0 Kudos
Message 10 of 18
(11,992 Views)