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

Reply via email to