Driver Development Kit (DDK) http://forums.ni.com/ni/board?board.id=90 ---------------- Knowledge base MH_DDK http://search.ni.com/nisearch/nisearchservlet?nistype=default&ddown=2&filter=%2Btaxonomy:knowledgebase+%2Blanguage:en&q=MH_DDK -------------------- compiling niddk unzip ../nimhddk_linux.zip unzip ../nimseries.zip cd 100a2/osinterface rm -r -f * mv ../../Linux/OSinterface/* . cd ../make #edit line 6 of Makefile to refer to linux.mak make #deal with ../examples/main.cpp:18: error: invalid conversion from const char*' to `u32' This requires knowing the devicePCI_ID for the board. See below #deal with /usr/bin/ld: cannot find -lvisa get rid of that in linux.mak #easy to get rid of warnings. ../osinterface/osiTypes.h:39:1: warning: "NULL" redefined by enclosing with #define NULL ... #endif ------------------- The devicePCI_ID After installing the PCI-6229 and the software /usr/local/bin/nilsdev -a NI PCI-6229: "Dev1" Serial Number: 0x1195482 Bus Type: PCI PCI Bus: 0x2 PCI Device: 0x8 IRQ Level: 0xB Memory Range: 0xFF6FE000-0xFF6FEFFF Memory Range: 0xFF6FD000-0xFF6FDFFF The PCI Bus and PCI Device can be looked for in cat /proc/pci ... Bus 2, device 8, function 0: Class ff00: PCI device 1093:70aa (rev 0). IRQ 11. Master Capable. Latency=64. Non-prefetchable 32 bit memory at 0xff6fe000 [0xff6fefff]. Non-prefetchable 32 bit memory at 0xff6fd000 [0xff6fdfff]. ... Then the devicePCI_ID is 0x109370aa ------------------- The best test is to become root and in this source directory launch with nrngui test5.hoc and use the hardware timed checkbox. This can be done in normal linux. Then, with the rtai patched linux booted, and as root, ./run and use the realtime checkbox see the run script and the .runinfo script in this directory. This runs test5.hoc ------------- Some messages: -------------- http://forums.ni.com/ni/board/message?board.id=90&message.id=301 Re: What is the required order of operations for the M-series DAQ (PCI-6229)? Options Options DiegoF Trusted Active Regular DiegoF Reply 6 of 6 Viewed 208 times 1 rating - 5.0 average Hi Aaron, The calibration constants won't change. These are store when the board is externally calibrated at the factory. Any temperature correction is done by the driver. In DAQmx this is what's called self-calibration. At the moment, MHDDK doesn't have any examples on self-calibration. Regarding your application, it seems that you are trying to do some sort of control loop where you get 1 point from each channel, process (pid or something) and output the response. If that's the case, you don't need to reconfigure the hardware for each point. It's all one big task!. Here's an outline of what you would do for AI and AO: - Put the device in a known state: reset AI, AO - Configure AO for on-demand output. In this mode when you write a value to the DACs it goes out inmediately. - Configure AI for continuous acquisition. Set up a interrupt source to determine when there's data avaliable. You can use the FIFO condition interrupt or the scan clock interrupt. - How you handle the interrupt and where you proccess the data depends on you system. Assuming you process everything in the ISR: - Get the latest sample(s) from the FIFO by emptying it - Process the data point - Write the response to the DAC(s). Output is generated inmediately - Goes on forever... In DAQmx terminology you would be doing a Hardware-Timed Single Point acquisition. If you are using static DIO, just configure the port and use it. It's pretty much independent of AI and AO. For a 1kHz loop is not worth setting up DMA. Most systems can handle that rate easily. You'll probably get less performance trying to determine where the DMA is at. Hope it helps!, Diego. --------------------- control loop - HardwareTimed Single Point Acquisition Options Options neuron Member neuron Reply 1 of 4 Viewed 73 times I was reading the " What is the required order of operations for the M series DAQ (PCI-6229)?" thread and saw a reply which is closely analogous to what I want to do: " - Put the device in a known state: reset AI, AO - Configure AO for on-demand output. In this mode when you write a value to the DACs it goes out inmediately. - Configure AI for continuous acquisition. Set up a interrupt source to determine when there's data avaliable. You can use the FIFO condition interrupt or the scan clock interrupt. - How you handle the interrupt and where you proccess the data depends on you system. Assuming you process everything in the ISR: - Get the latest sample(s) from the FIFO by emptying it - Process the data point - Write the response to the DAC(s). Output is generated inmediately - Goes on forever... In DAQmx terminology you would be doing a Hardware-Timed Single Point acquisition. " I have a PCI-6229 and BNC-2120 and am having difficulty making sense of the 13 thousand line chipobjects/tMSeries.h file. The examples contain a lot of useful idioms but are just a bit too non-parallel to my goal and I wonder if someone has some example code more similar to the following or advice on whether I am being foolishly fastidious. I imagined setting up a continuous pulse stream on the 6229 available on one of the digital output lines. The interval between the rising edges is my time step and the pulse width is wide enough so that the on chip ADC portion of ai was initiated on the rising edge and would not be affected by the on chip DAC ao initiated on the falling edge. The interrupt would occur on the falling edge and by then the computer could read the ai buffer. Some computation would occur which fills the ao buffer ready for transfer atthe next falling edge. I'd also like DI and DO to be synchronized to the rising and falling edges. By the way, before I bought the 6229, I verified that with RTAI linux I could work comfortably with a time step of 0.025 ms (those interrupts came from the computer clock). In practice, I'll be working somewhere between that and 1 ms steps. 01-28-2006 08:14 AM Re: control loop - HardwareTimed Single Point Acquisition Options Options DiegoF Trusted Active Regular DiegoF Reply 2 of 4 Viewed 35 times Check out this post Clocked M-Series DIO. It seems you are trying to do something very similar. The tMSeries class is just a description of the registers available in the device. Each register is an object that manages a soft-copy of the register Each register class defines some methods to read and write to the register as a whole or to the bitfiled of the register. Using the a tMSeries object you don't need to worry about register offsets or shifting bitfields. Diego Re: control loop - HardwareTimed Single Point Acquisition Options Options neuron Member neuron Reply 3 of 4 Viewed 29 times I was partly mistaken about the examples not being parallel to my goals. Beginning with aiex2.cpp, dividing it into several functions, and adding the http://forums.ni.com/ni/board/message?board.id=90&message.id 387 "Clocked M-Series DIO" fragment, have gotten me a fair ways along the path toward a prototype control loop. But I'm having trouble merging in the aoex4.cpp example and I guess need to experiment with that part in isolation. Since the fundamental clock for my control loop is (I'm guessing given by the aiex2 aiTrigger (board, tMSeries::tAI_Trigger_Select::kAI_START1_SelectPulse, tMSeries::tAI_Trigger_Select::kAI_START1_PolarityRising_Edge, tMSeries::tAI_Trigger_Select::kAI_START2_SelectPulse, tMSeries::tAI_Trigger_Select::kAI_START2_PolarityRising_Edge); I am curious, why that pulse does not appear on my BNC block at the "AI CONV CLK" output (PFI 2)? Nevertheless, with the Clocked M-Series DIO example I am able to see a pulse train on P0.0. My main question is how to get the AO triggered by the aiTrigger instead of the aoTrigger (board, tMSeries::tAO_Trigger_Select::kAO_START1_SelectPulse, tMSeries::tAO_Trigger_Select::kAO_START1_PolarityRising_Edge); or do I need to externally trigger from P0.0? 02-01-2006 05:43 PM Reply Reply Re: control loop - HardwareTimed Single Point Acquisition Options Options neuron Member neuron Reply 4 of 4 Viewed 8 times My control loop is working well using the idioms for AO on demand output from aoex2.cpp and AI continuous acquisition from aiex1.cpp. However the interrupt follows the LXRT extension to RTAI example for processor generated periodic interrupts using start_rt_timer(period_); rt_make_hard_real_time(); nrn_fake_step(); // get as much as possible into the cache // saves up to 10 us on the first step rt_task_make_periodic(rtrun_task_, rt_get_time() + period_, period_); rt_task_wait_period(); while (t < tstop_) { t1 = rt_get_cpu_time_ns(); nrn_fixed_step(); // start ai scan, compute, ai read, ao write nrn_rtstep_time_ = (double)(rt_get_cpu_time_ns() - t1); ovrn += rt_task_wait_period(); if (stoprun) { break; } } rt_make_soft_real_time(); stop_rt_timer(); Now I'd like to have the 6229 generate the interrupt and I wonder if anyone can give advice on how to carry out the transformation. There was some mention about using the FIFO condition interrupt or the scan clock interrupt and there are some intriguing lines in http://forums.ni.com/ni/board/message?board.id=90&message.id=287&query.id=4559#M287 but I have to admit to being somewhat at a loss as to how this connects to the rtai api. The only thing I've found that is remotely analogous is http://www.captain.at/programming/rtai/parportintlxrt-magma2.php that gives an example using things like rt_request_irq_task, rt_startup_irq rt_enable_irq, rt_irq_wait, rt_ack_irq,... Is that the avenue I should explore? I should mention that my experiments with AO on demand and AI hardware time acquisition from aiex2.cpp also worked nicely and I expect to use that idiom after I get this interrupt driven. However I was unable to get the AO hardware timed generation from aiex4.cpp to work hardly at all Sometimes it hung in aoArm at while (board->Joint_Status_2.readAO_TMRDACWRs_In_Progress_St ()) { // Wait } and could only get it going again by running the aoex4 example itself, More often no output I was writing appeared at the BNC connector, and when I did see output it was delayed by a dozen or so steps. Obviously I do not know how to manage the fifo. The serious conceptual error, though was using kCDO_Update_Source_SelectAI_Convert to toggle P0.0 and then connecting that to AI CONV CLK and using kAO_START1_SelectAI_START_1 for the trigger and kAO_UPDATE_Source_SelectPFI2 for the aoUpdate. The problem is that the rising edge is every two steps so my output is half the rate I want. Sorry for the long message and my glaring naivety. I suspect that a few minutes from someone with experience will save days of my flailing around. Thanks! Michael