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: 

Register Level Programmer Manual for M Series

I am using M Series 6221 DAQ and unable to find the Register Level Programmer Manual for it. The E series manual is quite a detailed one (http://www.ni.com/pdf/manuals/341079b.pdf) , Can you please point me to a similar document for M series ..

0 Kudos
Message 1 of 18
(10,626 Views)

Sir,

 

Sorry but we do not have any manual for the M series register based programming as of yet. 

 

 

Anuj Bhansali

AE 

NI INDIA 

0 Kudos
Message 2 of 18
(10,610 Views)

Hi Anuj ,

             I am developing a device driver for nonstandard OS (Real Time Operating System) for PCI 6221 Card,

So the kind of document i am seeking is very much required .

 

Atleast can you point me to the details of  Programming PCI Bus .. viz configuring the Command and Status Registers ..

 

Thanks,

Irfan

0 Kudos
Message 3 of 18
(10,604 Views)
We have the NI Measurement Hardware Driver Development Kit (DDK) which he could use to do register level programming of the 6221.
http://sine.ni.com/nips/cds/view/p/lang/en/nid/11737

The DDK exposes the register map of each supported device and provides examples for completing common measurement and control functions.
The register maps can be downloaded from ni.com.
 
http://digital.ni.com/express.nsf/bycode/exyv4w?opendocument&lang=en&node=seminar_US

The following link gives a brief explanation of register level programming using Measurement DDK

http://digital.ni.com/public.nsf/websearch/1C3988D7D33B925C86256C59007FB4B4?OpenDocument

ftp://ftp.ni.com/support/daq/mhddk/readme.htm
Message 4 of 18
(10,587 Views)

Hello ,
      I was directed to the same websites by the Application
Engineer earlier too.

 

I have been using the C++ code. The code is highly complex
and without any comments. Its very difficult to reverse
engineer it. Its a practice that code is written by refering
the manual , instead of understanding the working from code.

Its unbelivable that NI is selling this product without proper
docuemntation.

 

Anyways, My problem right now is :

 

Info
1. Using a x86 SBC based PC with ThreadX as operating system

2. I want to use Port1 and Port2 as DI. Able to read from Port1 and Port2 by following the program.
3. Channel 0 and Channel 1 as On Demand AI (RSE) for sensing 2 different parameters
   in the range of 0V to 10V. 
4. Want to read a single sample from both the channels.
5. Unable to read from Channel 0 and Channel 1 correctly yet.

 

Questions:
1. I am using aiex1.c program to acquire Analog signal .

  

    - numberOfChannels = 2 and numberOfSamples = 1

    - not using adcReset(board)

    - aiPersonalize (board, tMSeries::tAI_Output_Control::kAI_CONVERT_Output_SelectActive_High);

    - aiConfigureChannel (board, 

                                        Channel number 0 and 1 one after the other 

                                        0 gain
                                        tMSeries::tAI_Config_FIFO_Data::kAI_Config_PolarityBipolar,
                                        tMSeries::tAI_Config_FIFO_Data::kAI_Config_Channel_TypeRSE,
                                        Channel 1 is last channel )
  

   - As Is aiConvert (board,
                                 280,     // convert period divisor
                                 280,     // convert delay divisor
                                 kFalse);

 

  Any idea if i am not conguring or missing something ???

  As the acquired value i read is incorrect

 

2. Suppose i configure Channel 0 and Channel 1, And want to acquire only from
   Channel 0 , What to do for it ?

3. If acquisations happens from both the Channels , How do i know which data is acquired
    from the Channel 0 and Channel 1 in the FIFO ?


4. Is there a method to read data directly from ADC instead of reading it from FIFO ?


5. If there is input signal at Port0 (configured as DI), Can a interrupt be triggered ?


6. How to make AI interrput based ?

 

Thanks,
Irfan

0 Kudos
Message 5 of 18
(10,545 Views)

Hi Irfan-

 

1.  Can you please describe how the values you read are incorrect?  What values do you read?  Are they at all close to the value you expect, or are they completely wrong?  How do you have your signals connected to the hardware (which pins)?  All of your configuration seems correct.

 

2.  There is no way to selectively remove channels from the scanlist.  You must either read from all channels and then disregard the unwanted readings, or call aiClearConfigurationMemory() and reprogram the scanlist with aiConfigureChannel().

 

3.  The FIFO data will always be in the order in which the channels were added to the scanlist (that is, the order in which the channels were programming with aiConfigureChannel()).

 

4.  No, there is no way to read data directly from the ADC.  Internal signals (aiConvert) are used to control the operation of the AI channel multiplexor and to clock the ADC conversion.  The data must be retrieved from the FIFO, or through DMA (as shown in other examples in the MHDDK).

 

5.  No, there is no way to generate interrupts based on the inputs to port0.  You could use one of the general-purpose counters on the device to create interrupts based on gate or terminal count conditions, but this would require you to use some of the PFI lines (aka port1 or port2).

 

6.  The easiest way to enable interrupt generation for an AI process would be to use one of the interrupts for AI timing signals (for example AI_Start aka aiSampleClock).  You would need to enable its group (  

writeInterrupt_Group_A_Enable() ) and then the specific interrupt ( writeAI_START_Interrupt_Enable() ) and then observe/acknowledge any interrupts in your ISR ( readAI_START_St() to make sure the AI_Start occurred, then writeAI_START_Interrupt_Ack() )

 

Hopefully this helps-

Tom W
National Instruments
0 Kudos
Message 6 of 18
(10,496 Views)

Hello Tom ,
                 Thanks for the reply ..

 

I am now able to read correctly from the ADC , so the 1st problem is solved .

I still want to know about aiConvert(board,280,280,kFalse) .

Able to understand your responses for points 2 , 3 , 4 and 6.
Thanks again.

 

I am using dioex1.cpp & dioex2.cpp for testing DIO. Some more questions :

 

1. what does board->DIO_Direction.writeRegister(0xFF) do ?
    Looks like its instruction for configuring Port0 for Input/Output


2. Can i program Port1 and Port2 the same way as above ?


3. Similarly I am not able to understand the below code from dioex2.cpp
   
board->IO_Bidirection_Pin.writeRegister (0x00FF);
    board->PFI_Output_Select_1.writeRegister (0x4210);
    board->PFI_Output_Select_2.writeRegister (0x4210);
    board->PFI_Output_Select_3.writeRegister (0x210);

    How dows it program Port1 for Output and Port2 for Input ?


4. If I enable the commented code in dioex2.cpp ,

    I am getting an compilation error for undefined kPFI8_Pin_DirInput in
    board->IO_Bidirection_Pin.writePFI8_Pin_Dir (kPFI8_Pin_DirInput)


5. Can i get instruction (or code snippet) to generate an interrupt when there

    is change in input  signal at Port1 or Port2 (configured as DI)

 

Let me know ..

 

Thanks,

Irfan

0 Kudos
Message 7 of 18
(10,475 Views)

Hi Tom ,
       I read another posting of yours regarding the DIO configuring (pasted below) .
From it i understand that if i set

PFI_Output_Select_1 to PFI_Output_Select_6 to 0x0000

then both Port1 and Port2 will be configured as Input Ports .
Is that right ?

 

and Secondly how do i read from both the Ports.
My guess is


Data = (u8) (board->PFI_DI.readRegister())                 is reading from Port 1

and Data = (u8) (board->PFI_DI.readRegister() >> 😎 is reading from Port 2

Please correct me if wrong ..

 

and Third ,

Can i get instruction (or code snippet) to generate an interrupt when there is
change in input  signal at Port1 or Port2 (configured as DI)

 

Thanks,
Irfan

 

-----------------------------------------------------------------------------------

Re: Programming Analog Input Registers for MSeries NI-6221   [ NEW ]

The format of the PFI_Output_Select_1 register is as follows:

bits 0-4: PFI0 select
bits 5-9: PFI1 select
bits 10-14: PFI2 select
bit 15: reserved

with the same pattern repeating for PFI_Output_Select_N where N is a number between 1 and 5 and the PFI bitfields increase with the same pattern as PFI_Output_Select_1.  PFI_Output_Select_6 contains the selection for PFI15 in bits 0-4 and the rest of the bitfields are reserved.

 

The values written to those registers by dioex2 correspond to setting the lowest PFIn lines to PFI_DO (i.e. output) and the upper PFIn lines to "default" (i.e. input).  The setting for IO_Bidirection_Pin sets the PFI lines to input or output where bits 15-0 correspond to PFI15-PFI0, respectively.  As you might guess, a value of '1' corresponds to output and a value of '0' corresponds to input.

 

0 Kudos
Message 8 of 18
(10,470 Views)

Hi Irfan-

 

1.  The DIO_Direction register configures the direction for lines in port0.  It is 32 bits wide (since some M Series have up to 32 lines in port0) and 0=input, 1=output.

 

2.  No, port1 and port2 use different hardware and can't be programmed the same way.

 

3.  The IO_Bidirection_Pin determines line directions for PFI lines.  Those lines are shared with port1 and port2 for DIO.  So, the 16-bit register controls PFI lines 0..15 where bit 15 represents PFI15, bit 14 represents PFI14, etc.  Again, 0=input, 1=output.  PFI_Output_Select then chooses the signals to route to/from the PFI lines.  The format of PFI_Output_Select is contained in my other post that you referenced in your second post.  Based on that layout, PFI_DO (output for port1, port2) has a value of 16d and "default" (input for port1, port2) has a value of 0d. 

 

For example, PFI_Output_Select_1 = 0x4210 means:

 

PFI0: 1 0000 = 16d (PFI_DO)

PFI1: 1 0000 = 16d (PFI_DO)

PFI2: 1 0000 = 16d (PFI_DO)

 

4.  It looks like that code has a namespacing issue.  Try tIO_Bidirection_Pin::kPFI8_Pin_DirInput instead.

 

5.  I do not have sample code for this available.  The STC Technical Reference Manual has a section that describes interrupt control.  You would want to look at the G0 or G1 Gate interrupt discussion.  For the M Series, you would need to configure the PFI line you want to use as input and then use G0_Input_Select or G1_Input_Select to choose the proper PFI line (see tTIO.h).  For PFI0..9 the Gate_Select value should be 1d..10d.  For PFI10..15 it should be 21d..26d.

Tom W
National Instruments
0 Kudos
Message 9 of 18
(10,459 Views)

Irfan,

 

Is your problem solved? Don't hesitate to contact us in case of further problems.

 

Gaurav

 

0 Kudos
Message 10 of 18
(10,443 Views)