Hi, Dear Chuck and all,
I modified your "mimic_ai.h/c" to fit my NI PCI6035E DAQ card, and compilation
has passed. However, when I "insmod mimic_ai.o", my computer froze.
At the same time, there is a DC voltage (around 2V) generated in the Analog
Output(channel 0), since I use this AO signal to drive a DC motor, the motor
keeps running contineously. I have to reboot the computer to stop it.
Several days ago, I tried Comedi trigger functions in my computer for the
kernel usage. I found that it was ok for its Analog Output, and Digital IO, but
every time when I tried it for Analog Input, my computer froze.
Attached please find the codes modified for my computer(Pentium III +
NI PCI6035E) .
I think there is only something wrong with my Analog Input, could you please
kindly help me and point out where I was wrong?? I have been annoyed by this
problem for more than one week and could not find the reason.
Thanks a lot !!!
Yuhong
[EMAIL PROTECTED] wrote:
> Oops - so I forgot to include the files...here they are.
>
> On Mon, 2 Oct 2000, Olaf Petzold wrote:
>
> > Hallo Chuck,
> >
> > ...material deleted...
> > > if, you remove the lines where you set the rt_thread periodic.
> > > pthread_make_periodic_np(?) would be required if you were
> > > using mode 0 in comedi, and you wanted the cpu to trigger the board,
> > > as opposed to the other way around.
> > > However, by setting rt_thread as periodic, the system is trying
> > > to wake it up at the same frequency that comedi is trying to wake
> > > it up.
> >
> > This periodic mode was only to test it. At first stage there was only
> > pthread_create(), phtread_setfpu_np(), pthread_suspend(),
> > pthread_wakeup(). The thread was geted suspended by the thread itself
> > and wakeuped by pthread_wakeup inside the callback function of
> > comedi. Was I have seen was that the system was frozen at
> > pthread_suspend() and I have no idea why.
> >
> There could be other problems with your code, but I'd have to see it to
> identify it. Possible culprits are your 'struct comedi_trig' .trig*
> settings.
>
> > Do you have an code example which is working for you so that I can see the
> > difference ?
> >
> Sure. I'm including 2 files, mimic_ai.c & mimic_ai.h. You may need to
> change some values in mimic_ai.h, depending on what board you're using.
> Compile it with standard options set in rtl.mk. This little test code
> reads analog in values and 'mimic's them on the analog out channels.
>
> It's not really set up for generic use, but you can definately get it to
> work, +/- some DC offset and gain factors. At any rate, you can compare
> the setup to your code...
>
> -Chuck
>
> _______________________________________________
> comedi mailing list
> [EMAIL PROTECTED]
> http://stm.lbl.gov/cgi-bin/mailman/listinfo/comedi
>
> ------------------------------------------------------------------------
> Name: mimic_ai.h
> mimic_ai.h Type: Plain Text (TEXT/PLAIN)
> Encoding: BASE64
>
> Name: mimic_ai.c
> mimic_ai.c Type: Plain Text (TEXT/PLAIN)
> Encoding: BASE64
/* whatami:....mimic_ai.h
why:........To test DAQ board operation
ally:.......mimic_ai.c
requi:......rtlinux, comedi
totry:......compile, insert mimic_ai.o, check dmesg for errors
apply:......AnalogOut_0 should mimic AnalogIn_0
comply:.....GNU General Public License
supply:.....Freely to all kind souls, the world over!
by:.........Chuck Dorval
reply:[EMAIL PROTECTED]
good-bye:...September 26, 2000
*/
#ifndef __RT_DAQ_H
#define __RT_DAQ_H
// What will System do?
#define READ_DAQ
#define WRITE_DAQ
// Time associated constants
#define T_US 5000 // thread period in micro seconds
#define T0_US 1000 // sample duration in micro seconds
// These numbers are set by needs of particular DAQ case
#define NUM_AI_ACTIVE 1 // number of used analog inputs
#define NUM_AO_ACTIVE 1 // number of used analog outputs
// Values usually not used
#define DEFAULT_AI_GAIN 0 // ai gain setting
#define DEFAULT_AI_ZERO 32768 // zero value of ai gain setting
#define DEFAULT_AI_RANGE 10000 // ai range in mV
#define AO_ZERO 0 // ao zero value
#endif // __RT_DAQ_H
/* whatami:....mimic_ai.c
why:........To test DAQ board operation
ally:.......mimic_ai.h
requi:......rtlinux, comedi
totry:......compile, insert mimic_ai.o, check dmesg for errors
apply:......AnalogOut_0 should mimic AnalogIn_0
comply:.....GNU General Public License
supply:.....Freely to all kind souls, the world over!
by:.........Chuck Dorval
reply:[EMAIL PROTECTED]
good-bye:...September 26, 2000
*/
// ***** System Headers ***** //
#include <rtl.h>
#include <pthread.h>
#include <comedi.h>
#include "mimic_ai.h"
// ***** Function Declarations *****/
int callback(unsigned int, void*); // Comedi Callback function
void *daq_code(void*); // DAQ Periodic function
int init_daq_channels(void); // Initialize DAQ channels
// ***** Global Variables ***** //
// RT required
pthread_t daq_thread; // main rtlinux thread
// DAQ Board Required External Variables; some from comedi_config
comedi_trig ai_trig; // main comedi structure
unsigned int ai_dev = 0; // comedi device for analog input
unsigned int ai_subd = 0; // comedi subdev for analog input
unsigned int ai_chan[NUM_AI_ACTIVE]; // comedi AI channel
sampl_t ai_data[NUM_AI_ACTIVE]; // comedi AI data points
comedi_trig ao_trig; // main comedi structure
unsigned int ao_dev = 0; // comedi device for analog output
unsigned int ao_subd = 1; // comedi subdev for analog output
unsigned int ao_chan[NUM_AO_ACTIVE]; // comedi AO channel
sampl_t ao_data[NUM_AO_ACTIVE]; // comedi AO data point
// ***** Operational Functions (2) ***** //
// Function called by DAQ trigger
int callback(unsigned int flags, void *arg)
{
pthread_wakeup_np( daq_thread );
return 1;
}
// Task reads/writes data to DAQ board
void *daq_code(void *param)
{
short signed_ai_data, signed_ao_data;
while (1) // periodic task, must loop
{
pthread_wait_np( );
#ifndef READ_DAQ
// Fake ai_data
ai_data[0] = (ai_data[0] + 1) % AI_RESOLUTION;
#endif
// Balanced version of ai_data
signed_ai_data = (short)ai_data[0] - DEFAULT_AI_ZERO;
// Convert to ao_data
signed_ao_data = (signed_ai_data + 8)/ 16;
ao_data[0] = signed_ao_data + AO_ZERO;
#ifdef WRITE_DAQ
// Write analog out to DAQ
if ( comedi_trig_ioctl(ao_dev,ao_subd,&ao_trig) != 1 )
printk( "Cannot write ouput value to DAC\n" );
#endif
}
}
// ***** Initialization Functions (1) ***** //
// Board init - should change from 'trig' to 'cmd' format soon
int init_daq_channels(void)
{
int i, error_flag=0;
// Pack analog channels
for(i=0;i<NUM_AI_ACTIVE;i++)
ai_chan[i] = CR_PACK(i,DEFAULT_AI_GAIN,AREF_DIFF);
for (i=0;i<NUM_AO_ACTIVE;i++)
ao_chan[i] = CR_PACK(i,0,AREF_GROUND);
// Set up AI trigger structure
ai_trig.subdev = ai_subd; // ai subdevice
ai_trig.mode = 2; // continuous mode
ai_trig.flags = TRIG_WAKE_EOS;
ai_trig.n_chan = NUM_AI_ACTIVE;
ai_trig.chanlist = ai_chan;
ai_trig.data = ai_data;
ai_trig.data_len = sizeof(sampl_t)*NUM_AI_ACTIVE;
ai_trig.n = 1; //num samples?
ai_trig.trigsrc = TRIG_ANY;
ai_trig.trigvar = (int)( T_US *1000); //period [=] ns
ai_trig.trigvar1 = (int)( T0_US *1000); //sample_time [=] ns
// Set up AO trigger structure
ao_trig.subdev = ao_subd; // ao subdevice
ao_trig.mode = 0; // one-shot mode
ao_trig.flags = 0;
ao_trig.n_chan = NUM_AO_ACTIVE;
ao_trig.chanlist = ao_chan;
ao_trig.data = ao_data;
ao_trig.data_len = sizeof(sampl_t)*NUM_AO_ACTIVE;
ao_trig.n = 1;
ao_trig.trigsrc = 0;
ao_trig.trigvar = 0;
ao_trig.trigvar1 = 0;
// lock subdevices
error_flag = comedi_lock_ioctl(ai_dev,ai_subd);
error_flag += comedi_lock_ioctl(ao_dev,ao_subd);
// register callback function
error_flag += comedi_register_callback
(ai_dev, ai_subd, COMEDI_CB_EOS, &callback, (void *)0);
return(error_flag);
}
// ***** Module Standard Functions (2) ***** //
int init_module(void)
{
pthread_attr_t attr;
// initialize daq board A/D & D/A channels
if ( init_daq_channels() )
printk( "Cannot establish AIn or AOut channels\n" );
// initialize pthread attributes
if( pthread_attr_init(&attr) )
printk( "Cannot initialize pthread attributes\n" );
// initialize the main thread
if( pthread_create(&daq_thread, &attr, daq_code,(void *)1) )
printk( "Cannot create pthread\n" );
// start data acquisition
if ( comedi_trig_ioctl(ai_dev,ai_subd,&ai_trig) )
printk( "Comedi trigger not correctly implemented\n" );
return 0;
}
void cleanup_module(void)
{
// Inactivate comedi triggering mechanism
if ( comedi_cancel_ioctl(ai_dev,ai_subd) )
printk( "Comedi trigger not inactivated\n" );
// Unlock AI subdevice so other comedi programs can use
if ( comedi_unlock_ioctl(ai_dev,ai_subd) )
printk( "AI channel(s) remain inappropriately locked\n" );
// Unlock AO subdevice so other comedi programs can use
if ( comedi_unlock_ioctl(ao_dev,ao_subd) )
printk( "AO channel(s) remain inappropriately locked\n" );
// Destroy periodic thread
if ( pthread_delete_np(daq_thread) )
printk( "Thread not destroyed\n" );
}
all: mimic_ai.o
include rtl.mk
mimic_ai.o: my_ai.c
$(CC) ${INCLUDE} ${CFLAGS} -c my_ai.c -o my_ai.o
clean:
rm -f *.o