In the DAQ-STC3 X Series DDK Reference Manual, Chapter 1: Theroy of Operation, Section Interrupts, Subsection Special Considerations: Maximizing Throughput in Low-Latency Situations (p41), it is said:
"for X Series devices, the CHInCh can interrupt on the DMA channel’s total transfer count, which occurs once the data has been completely transferred to the host memory. The order of programming for this situation (and output operations) is as follows:
1. Program the DMA channel’s Total_Transfer_Count_Compare_Register (CHTTCCR) with the number of Bytes in a single input/output sample.
2. Set the DMA channel’s Notify on Total Count flag in the CHCR.
3. Set the DMA channel’s Arm Total Count Interrupt flag in the CHOR.
4. Start data transfer (through the DMA controller and the subsystem’s Stream Circuit).
5. Receive total transfer count interrupt.
6. Increase the CHTTCCR by the number of Bytes in a single input/output sample.
7. Re-arm the total transfer count interrupt in the CHOR.
Using the X Series DDK, I don't manage to perform such a configuration.
Can you please provide me code sample to do so ?
Thanks in advance for your support.
This operation requires the use of interrupts as well as register level programming of the board. Interrupts and interrupt service routines are very system/OS dependent, and we have not added any interrupt components to the OS Interrupt component of the Measurements DDK.
However, those steps describe how this operation should be done regarding when the different registers/bitfields of the board should be accessed. Do you have experience creating and using interrupt service routines for your operating system/platform? Were any of the registers, bitfields, or values mentioned in this list confusing?
I'm using INtime RTOS from TenAsys. It's a first time for us. INtime provide a code sample that handle interruptions coming from Serial Line. This application work great.
We are not sure that NI board throw interruptions (we don't catch any).
Do you have any code sample that configure NI board to send an interruption (at a given frequency with counters for example). It will help us to be sure that probleme is with INtime configuration and not NI board.
Thanks for your answer
Unfortunately an example for your use-case and operating system does not exist. If you think that creating this example is the only way that you can move forward, please contact your local field sales engineer.
This knowledgebase has our support policy of the Measurements Hardware DDK:
I think you can move forward in other ways.
In the X Series DDIK Reference Manual, Chapter 1 Theory of Operation, Functional Overview, Interrupts...It mentions the interrupt mask registers for enabling interrupts for the board and individual subsystems. There is also interrupt status registers which will indicate if the condition for a certain interrupt has happened. When you follow the pseudo code in your post:
1. Are the AI counters armed?
2. What is the Total Count Interrupt status (does the associated status register indicate that this condition has happened)?
3. Does the CHInCh itself receive an interrupt from the DMA subsystems?
is there any news on this?
I've written a Linux/Xenomai driver for the X 6321 / 6321 using programmed I/O. It works fine, but we're too slow in our system context.
So my next idea was to use DMA. This also works, but only for a maximum of 4 analog input channels. Using more brings the whole system to a grinding halt.
So I thought I use interrupts to catch the input at the end of the DMA-transfer. Following the stanza in the reference manual I set CPU_Int and STC3_Int to 1.
I also set:
- Channel_Total_Transfer_Count_Compare_Register_LSW = 1, so I'd get an interrupt as soon as the first byte arrives - certainly a reason to celebrate.
- Notify_On_Total_Count = 1
- Arm_Total_Count_Int = 1
- Gen_Interrupt_Enable = 1
- ... and a few others, to provoke some reaction
What I see from the printk-s in my driver is that the status registers Vol_CPU, and Vol_DMA go up and down as I would expect them to.
On the Linux/Xenomai side everything looks okay: The device registers on IRQ 17, as confirmed by pci_enable_device, and also /proc/irq.
But I can't catch any interrupts on the bus, i.e. my interrupt handler is never called...
Sorry for the long delay.
Come back from holidays and got a lot of things to do in the previous weeks.
From what you said, I did the same thing. Here is part of the code I used to enable interrupt.
Here is what I have done to make the whole things work on Linux:
Hope it will help you
Don't fear to ask if it is not the case.
Weeks ago, we developed a Linux application that configure NI acquisition board (serie X) to send an interrupt when FIFO count reach a given number. At this stage we manage to prove that our board configuration was good and that the problem was due to INtime. TenAsys (INtime developers) fix this issue few weeks ago.
We just come back from holidays, apply the modifications created by TenAsys and manage to get interrupt inside INtime.
We still have two problems.
From the interrupt handler, when we access to the DMA to get samples stored in the FIFO, we manage to get the samples inside the first interrupt handler. With the following interrupts, when accessing DMA with the tCHInChDMAChannel structure, it said that there is no available bytes. But when we read the Channel_Total_Transfer_Count_Status_Register from the DMA channel, we see that we have the desired numbers of samples.
In the interrupt handler, during the interrupt aknowledgement, instead of only reading the Volatile_Interrupt_Status_Register to ackowledge the interrupt, if I increase the Channel_Total_Transfer_Count_Compare_Register_
It seems that we mis-configured the DMA channel. But don't manage to find the error.
Two interrupts generated
Moreover, we always get 2 FIFO_Count interrupts. Even configuring conversion, sampling and interrupt frequencies at very low value (conversion 1KHz, sampling 1Hz, interrupt generation: 1Hz). The delay between the two interrupts is about few nano seconds.
I attach to this post the source code we use to play/test this configuration. There is a Visual Studio workspace that we used to play with INtime and a CMake configuration file that we used to manage our Linux tests. You can find all the informations you need to build the binary in the README file.
Thanks in advance for your help with these issues.
Reading again the documentation, DMA storage is not a FIFO (not specified).
Forget when I speak about FIFO count, in fact it's just the number of bytes in the DMA.
Sorry for this misunderstanding.
The source code to your driver and application isn't nearly as important as the register accesses it is making. We are experts in how to access the DAQ card, but we have limited knowledge of the OS you are using. In order to proceed, please provide the following.
1. A trace of the execution of your example that includes every register access (read/write). The register access would need to give us the offset of the register, the chip object making the call, and the contents of the register.
2. Your expectations of what each group of register accesses is accomplishing.
3. Denote the beginning and end of ISRs.
With these two pieces we can compare your register accesses to the manual to debug this further. An easy way of accomplishing 1. is to modify all Read/Write functions in each Chip Object to print this information.
We would expect the following operations in your ISR.
1. Disable Interrupts if INTime repeatedly calls the ISR for the single interrupt condition.
2. Possibly copy data from the DMA buffer to a local/application buffer...although it is not best for an ISR to do this.
3. Acknowledge the DMA Total Count Interrupt.
4. Enable Interrupts if they needed to be disabled.
5. Feed the Total Count Compare to allow DMA to transfer more data after the data is copied.
Please post back if you have additional questions.
I will generate this report ASAP.
I have to switch on another project for few days. I hope to work on this issue on Wednesday. I will keep you informed.