- From: Tim Beamish <tbeamish_at_cs.ubc.ca>
- Date: Tue, 16 Jul 2002 18:29:00 -0700 (PDT)
I'm having trouble using the comedi_parport driver to cause an interrupt.
If you're inclined to help, please read on.
I'm trying to cause an interrupt on the parallel port. I have a two
channel encoder and I've attached one channel to pin 10 of the parallel
port. I think this is the interrupt pin. I'm using RTLinux and I've loaded
the comedi_parport driver into the kernel. I've configured the
comedi_parport driver with the following line:
/usr/sbin/comedi_config /dev/comedi1 comedi_parport 0x0378,3
I picked IRQ 3 because it was empty. I've also tried configuring the
driver at base address 0x03bc and 0x0278. Finally, I load the following
program into the kernel to produce the interrupt:
-----------------------------------------
#include <rtl.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <comedi.h>
#include <linux/comedilib.h>
#define INT_DEVICE 1 // "/dev/comedi1"
#define NUM_INT_CHANNELS 1
sampl_t intData[1];
comedi_cmd cINT, *cmdINT = &cINT; // The command for handling interrupts
int devPARPORT = -1;
unsigned int chanlistINT[NUM_INT_CHANNELS];
unsigned int subdeviceINT = 3;
static int counter = 0;
static int motorMotionCallback(unsigned int i, void *arg) {
// Invoked when the encoder on the motor triggers an interrupt on parallel port pin 10
counter++;
if (counter >= 4000) {
counter = 0;
}
rtl_printf("counter == %d\n", counter);
return 0;
}
void createEncoderInterruptCommand(void) {
int i;
memset(cmdINT, 0x00, sizeof(*cmdINT));
for(i=0;i<NUM_INT_CHANNELS;i++)
{
chanlistINT[i]=CR_PACK(i,0, 0);
}
cmdINT->subdev = subdeviceINT;
cmdINT->flags = TRIG_WAKE_EOS|TRIG_RT;
cmdINT->start_src = TRIG_NOW;
cmdINT->start_arg = 0;
cmdINT->scan_begin_src = TRIG_EXT;
cmdINT->scan_begin_arg = 0;
cmdINT->convert_src = TRIG_FOLLOW;
cmdINT->convert_arg = 0;
cmdINT->scan_end_src = TRIG_COUNT;
cmdINT->scan_end_arg = NUM_INT_CHANNELS;
cmdINT->stop_src = TRIG_NONE;
cmdINT->stop_arg = 0;
cmdINT->chanlist_len = NUM_INT_CHANNELS;
cmdINT->chanlist = chanlistINT;
cmdINT->data = intData;
cmdINT->data_len = sizeof(intData);
}
int init_module(void) {
int ret;
devPARPORT = comedi_open(INT_DEVICE);
if (devPARPORT == -1) {
rtl_printf("Error in comedi_open when trying to open the parallel port\n");
return -1;
} else {
rtl_printf("Parport seems to be open and devPARPORT == %d\n", devPARPORT);
}
createEncoderInterruptCommand();
ret = comedi_command_test(devPARPORT, cmdINT);
rtl_printf("comedi_command_test = %d\n", ret);
ret = comedi_register_callback(devPARPORT, subdeviceINT, COMEDI_CB_EOS, motorMotionCallback, NULL);
rtl_printf("comedi_register_callback on card %d, subdevice %d = %d\n", devPARPORT, subdeviceINT, ret);
ret = comedi_command(devPARPORT, cmdINT);
rtl_printf("comedi_command = %d\n", ret);
return 0;
}
void cleanup_module(void) {
comedi_cancel(devPARPORT, subdeviceINT);
rtl_printf("cleanup_module done\n");
}
----------------------------------------
So ideally, when the encoder moves, I should call the motorMotionCallback
function which should increment the counter and write it to the kernel
log. I added a line to the top of each function in comedi_parport that is
something like "printk("<nameOfFunction> called");".
Here's some output I get when I run the program (The lines with *** are
comments I added afterwards):
-------------------------------------------
[root_at_baker]# dmesg -c
*** check to see that dmesg is clean ***
[root_at_baker]# insmod intDemo.o
[root_at_baker]# dmesg -c
parport_intr_cmdtest called
Parport seems to be open and devPARPORT == 1
comedi_command_test = 0
comedi_register_callback on card 1, subdevice 3 = 0
parport_intr_cmd called
comedi_command = 0
[root_at_baker]# dmesg -c
*** I'm moving the encoder here. It should be causing interupts.***
[root_at_baker]# dmesg -c
*** dmesg is blank so nothing is happening. ***
------------------------------------------
Unfortunatly it's not working. Can anyone tell me why?
Thanks in advance,
Tim
Received on 2002-07-17Z00:29:00