Added external trigger support to the driver.
authorBernd Porr <Bernd.Porr@f2s.com>
Mon, 4 Dec 2006 23:24:07 +0000 (23:24 +0000)
committerBernd Porr <Bernd.Porr@f2s.com>
Mon, 4 Dec 2006 23:24:07 +0000 (23:24 +0000)
Added a define for 2.6.19 because the completion function is without register arguments (as was pre 2.6.0).
Changed the GPIF programming so that it does no longer loops through the idle state. Instead I use the first states to reset the counter for channels.

comedi/drivers/usbduxfast.c

index 80adde838d3c5cf77a0f1a99c4e63abb5d20f744..f6965cd5d6d24456a0dfe933cf8c7bceb664cfea 100644 (file)
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v0.99"
+#define DRIVER_VERSION "v0.99a"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
 /*
@@ -25,7 +25,7 @@ Driver: usbduxfast.c
 Description: ITL USB-DUXfast
 Devices: [ITL] USB-DUX (usbduxfast.o)
 Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 21 Oct 2006
+Updated: 04 Dec 2006
 Status: testing
 */
 
@@ -44,6 +44,7 @@ Status: testing
  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
  *       Added insn command basically for testing. Sample rate is 1MHz/16ch=62.5kHz
  * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
+ * 0.99a: added external trigger.
  */
 
 
@@ -116,7 +117,8 @@ Status: testing
 // Analogue in subdevice
 #define SUBDEV_AD             0
 
-// min delay steps
+// min delay steps for more than one channel
+// basically when the mux gives up. ;-)
 #define MIN_SAMPLING_PERIOD 9 // steps at 30MHz in the FX2
 
 // Max number of 1/30MHz delay steps:
@@ -214,7 +216,7 @@ static int send_dux_commands(usbduxfastsub_t* this_usbduxfastsub,int cmd_type) {
                                              CHANNELLISTEP),
                              this_usbduxfastsub->dux_commands,
                              SIZEOFDUXBUFFER,
-                             &nsent,
+                             &nsent, 
                              10000);
        if (result<0) {
                printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n",
@@ -273,7 +275,7 @@ static int usbduxfast_ai_stop(usbduxfastsub_t* this_usbduxfastsub,
 #endif
 
 
-       this_usbduxfastsub->ai_cmd_running=0;
+       this_usbduxfastsub->ai_cmd_running=0;           
 
        if (do_unlink) {
                // stop aquistion
@@ -311,7 +313,7 @@ static int usbduxfast_ai_cancel(comedi_device *dev,
        // unlink
        res=usbduxfast_ai_stop(this_usbduxfastsub,1);
        up(&this_usbduxfastsub->sem);
-
+       
        return res;
 }
 
@@ -320,7 +322,7 @@ static int usbduxfast_ai_cancel(comedi_device *dev,
 
 // analogue IN
 // interrupt service routine
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
 static void usbduxfastsub_ai_Irq(struct urb *urb)
 #else
 static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs)
@@ -382,7 +384,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs)
                // tell this comedi
                s->async->events |= COMEDI_CB_EOA;
                s->async->events |= COMEDI_CB_ERROR;
-               comedi_event(this_usbduxfastsub->comedidev,
+               comedi_event(this_usbduxfastsub->comedidev, 
                             s,
                             s->async->events);
                // stop the transfer w/o unlink
@@ -395,8 +397,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs)
                       urb->status);
                s->async->events |= COMEDI_CB_EOA;
                s->async->events |= COMEDI_CB_ERROR;
-               comedi_event(this_usbduxfastsub->comedidev,
-                            s,
+               comedi_event(this_usbduxfastsub->comedidev, 
+                            s, 
                             s->async->events);
                usbduxfast_ai_stop(this_usbduxfastsub,0);
                return;
@@ -416,21 +418,21 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs)
                                                   0);
                                // say comedi that the acquistion is over
                                s->async->events |= COMEDI_CB_EOA;
-                               comedi_event(this_usbduxfastsub->comedidev,
-                                            s,
+                               comedi_event(this_usbduxfastsub->comedidev, 
+                                            s, 
                                             s->async->events);
                                return;
                        }
                        this_usbduxfastsub->ai_sample_count-=n;
                }
-
+               
                // write the full buffer to comedi
                cfc_write_array_to_buffer(s,
                                          urb->transfer_buffer,
                                          urb->actual_length);
-
+               
                // tell comedi that data is there
-               comedi_event(this_usbduxfastsub->comedidev,
+               comedi_event(this_usbduxfastsub->comedidev, 
                             s,
                             s->async->events);
 
@@ -449,7 +451,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs)
                       err);
                s->async->events |= COMEDI_CB_EOA;
                s->async->events |= COMEDI_CB_ERROR;
-               comedi_event(this_usbduxfastsub->comedidev,
+               comedi_event(this_usbduxfastsub->comedidev, 
                             s,
                             s->async->events);
                usbduxfast_ai_stop(this_usbduxfastsub,0);
@@ -466,17 +468,17 @@ static int usbduxfastsub_start(usbduxfastsub_t* usbduxfastsub) {
 
        if (usbduxfastsub->probed) {
                // 7f92 to zero
-               local_transfer_buffer[0]=0;
+               local_transfer_buffer[0]=0; 
                errcode=USB_CONTROL_MSG
                        (usbduxfastsub->usbdev,
                         // create a pipe for a control transfer
                         usb_sndctrlpipe(usbduxfastsub->usbdev,0),
                         // bRequest, "Firmware"
-                        USBDUXFASTSUB_FIRMWARE,
+                        USBDUXFASTSUB_FIRMWARE, 
                         // bmRequestType
-                        VENDOR_DIR_OUT,
+                        VENDOR_DIR_OUT, 
                         // Value
-                        USBDUXFASTSUB_CPUCS,
+                        USBDUXFASTSUB_CPUCS, 
                         // Index
                         0x0000,
                         // address of the transfer buffer
@@ -484,7 +486,7 @@ static int usbduxfastsub_start(usbduxfastsub_t* usbduxfastsub) {
                         // Length
                         1,
                         // Timeout
-                        EZTIMEOUT
+                        EZTIMEOUT 
                         );
                if (errcode<0) {
                        printk("comedi_: usbduxfast_: control msg failed (start)\n");
@@ -503,23 +505,23 @@ static int usbduxfastsub_stop(usbduxfastsub_t* usbduxfastsub) {
        unsigned char local_transfer_buffer[16];
        if (usbduxfastsub->probed) {
                // 7f92 to one
-               local_transfer_buffer[0]=1;
+               local_transfer_buffer[0]=1; 
                errcode=USB_CONTROL_MSG
                        (usbduxfastsub->usbdev,
                         usb_sndctrlpipe(usbduxfastsub->usbdev,0),
                         // bRequest, "Firmware"
-                        USBDUXFASTSUB_FIRMWARE,
+                        USBDUXFASTSUB_FIRMWARE, 
                         // bmRequestType
                         VENDOR_DIR_OUT,
                         // Value
                         USBDUXFASTSUB_CPUCS,
                         // Index
-                        0x0000,
+                        0x0000, 
                         local_transfer_buffer,
                         // Length
                         1,
                         // Timeout
-                        EZTIMEOUT
+                        EZTIMEOUT 
                         );
                if (errcode<0) {
                        printk("comedi_: usbduxfast: control msg failed (stop)\n");
@@ -528,7 +530,7 @@ static int usbduxfastsub_stop(usbduxfastsub_t* usbduxfastsub) {
        }
        return 0;
 }
-
+               
 
 
 
@@ -583,7 +585,7 @@ return 0;
 
 
 
-int firmwareUpload(usbduxfastsub_t* usbduxfastsub,
+int firmwareUpload(usbduxfastsub_t* usbduxfastsub, 
                   unsigned char* firmwareBinary,
                   int sizeFirmware) {
        int ret;
@@ -614,7 +616,7 @@ int firmwareUpload(usbduxfastsub_t* usbduxfastsub,
        }
        return 0;
 }
-
+       
 
 
 int usbduxfastsub_submit_InURBs(usbduxfastsub_t* usbduxfastsub) {
@@ -651,8 +653,8 @@ int usbduxfastsub_submit_InURBs(usbduxfastsub_t* usbduxfastsub) {
 
 
 
-static int usbduxfast_ai_cmdtest(comedi_device *dev,
-                            comedi_subdevice *s,
+static int usbduxfast_ai_cmdtest(comedi_device *dev, 
+                            comedi_subdevice *s, 
                             comedi_cmd *cmd)
 {
        int err=0, stop_mask=0;
@@ -673,7 +675,7 @@ static int usbduxfast_ai_cmdtest(comedi_device *dev,
        /* step 1: make sure trigger sources are trivially valid */
 
        tmp = cmd->start_src;
-       cmd->start_src &= TRIG_NOW;
+       cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
        if(!cmd->start_src || tmp != cmd->start_src) err++;
 
        tmp = cmd->scan_begin_src;
@@ -698,7 +700,8 @@ static int usbduxfast_ai_cmdtest(comedi_device *dev,
        /* step 2: make sure trigger sources are unique and mutually compatible */
 
        if(cmd->start_src != TRIG_NOW &&
-               cmd->start_src != TRIG_EXT) err++;
+          cmd->start_src != TRIG_EXT &&
+          cmd->start_src != TRIG_INT) err++;
        if(cmd->scan_begin_src != TRIG_TIMER &&
                cmd->scan_begin_src != TRIG_FOLLOW &&
                cmd->scan_begin_src != TRIG_EXT) err++;
@@ -906,7 +909,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
        }
        steps=0;
        if(cmd->scan_begin_src == TRIG_TIMER) {
-               printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n",
+               printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", 
                       dev->minor);
                up(&this_usbduxfastsub->sem);
                return -EINVAL;
@@ -915,8 +918,8 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                steps=(cmd->convert_arg*30)/1000;
        }
        if ((steps<MIN_SAMPLING_PERIOD)&&(cmd->chanlist_len!=1)) {
-               printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
-                      dev->minor,
+               printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", 
+                      dev->minor, 
                       steps,
                       cmd->scan_begin_arg);
                up(&this_usbduxfastsub->sem);
@@ -928,6 +931,12 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                up(&this_usbduxfastsub->sem);
                return -EINVAL;
        }
+       if ((cmd->start_src == TRIG_EXT)&&(cmd->chanlist_len!=1)&&(cmd->chanlist_len!=16)) {
+               printk("comedi%d: usbduxfast: ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n",
+                      dev->minor);
+               up(&this_usbduxfastsub->sem);
+               return -EINVAL;
+       }
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi%d: usbduxfast: steps=%ld, convert_arg=%u, ai_timer=%u\n",
               dev->minor,
@@ -941,66 +950,66 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                // one channel
        case 1:
                if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff;
-               // commit data to the FIFO
+
+               // for external trigger: looping in this state until the RDY0 pin
+               // becomes zero
+               if(cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
+                       this_usbduxfastsub->dux_commands[LENBASE+0]=0x01; // branch back to state 0
+                       this_usbduxfastsub->dux_commands[OPBASE+0]=0x01; // deceision state w/o data
+                       this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
+                       this_usbduxfastsub->dux_commands[LOGBASE+0]=0x00; // RDY0 = 0
+               } else { // we just proceed to state 1
+                       this_usbduxfastsub->dux_commands[LENBASE+0]=1;
+                       this_usbduxfastsub->dux_commands[OPBASE+0]=0;
+                       this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
+                       this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
+               }                               
 
                if (steps<MIN_SAMPLING_PERIOD) {
+                       // for fast single channel aqu without mux
                        if (steps<=1) {
-                               // we just stay here
-                               this_usbduxfastsub->dux_commands[LENBASE+0]=0x80; // branch back to state 0
-                               this_usbduxfastsub->dux_commands[OPBASE+0]=0x03; // deceision state with data
-                               this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
-                               this_usbduxfastsub->dux_commands[LOGBASE+0]=0xFF; // doesn't matter
+                               // we just stay here at state 1 and rexecute the same state
+                               // this gives us 30MHz sampling rate
+                               this_usbduxfastsub->dux_commands[LENBASE+1]=0x89; // branch back to state 1
+                               this_usbduxfastsub->dux_commands[OPBASE+1]=0x03; // deceision state with data
+                               this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
+                               this_usbduxfastsub->dux_commands[LOGBASE+1]=0xFF; // doesn't matter
                        } else {
-                               this_usbduxfastsub->dux_commands[LENBASE+0]=steps-1;
-                               this_usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data
-                               this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
-                               this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
+                               // we loop through two states: data and delay: max rate is 15Mhz
+                               this_usbduxfastsub->dux_commands[LENBASE+1]=steps-1;
+                               this_usbduxfastsub->dux_commands[OPBASE+1]=0x02; // data
+                               this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
+                               this_usbduxfastsub->dux_commands[LOGBASE+1]=0; // doesn't matter
+
+                               this_usbduxfastsub->dux_commands[LENBASE+2]=0x09; // branch back to state 1
+                               this_usbduxfastsub->dux_commands[OPBASE+2]=0x01; // deceision state w/o data
+                               this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask;
+                               this_usbduxfastsub->dux_commands[LOGBASE+2]=0xFF; // doesn't matter
                        }
-                       this_usbduxfastsub->dux_commands[LENBASE+1]=0x00; // branch back to state 0
-                       this_usbduxfastsub->dux_commands[OPBASE+1]=0x01; // deceision state w/o data
-                       this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+1]=0xFF; // doesn't matter
                } else {
-                       // for slower sampling rate we loop through the idle state
-                       this_usbduxfastsub->dux_commands[LENBASE+0]=1;
-                       this_usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data
-                       this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
-
-                       // we have 6 states with duration 1
-                       steps=steps-6;
+                       // we loop through 3 states: 2x delay and 1x data. This gives a min
+                       // sampling rate of 60kHz.
 
+                       // we have 1 state with duration 1
+                       steps=steps-1;
+                       
                        // do the first part of the delay
                        this_usbduxfastsub->dux_commands[LENBASE+1]=steps/2;
                        this_usbduxfastsub->dux_commands[OPBASE+1]=0;
                        this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
                        this_usbduxfastsub->dux_commands[LOGBASE+1]=0;
-
+                       
                        // and the second part
                        this_usbduxfastsub->dux_commands[LENBASE+2]=steps-steps/2;
                        this_usbduxfastsub->dux_commands[OPBASE+2]=0;
                        this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask;
                        this_usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
-                       this_usbduxfastsub->dux_commands[LENBASE+3]=1;
-                       this_usbduxfastsub->dux_commands[OPBASE+3]=0;
+                       
+                       // get the data and branch back
+                       this_usbduxfastsub->dux_commands[LENBASE+3]=0x09; // branch back to state 1
+                       this_usbduxfastsub->dux_commands[OPBASE+3]=0x03; // deceision state w data
                        this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+3]=0;
-
-                       this_usbduxfastsub->dux_commands[LENBASE+4]=1;
-                       this_usbduxfastsub->dux_commands[OPBASE+4]=0;
-                       this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
-                       this_usbduxfastsub->dux_commands[LENBASE+5]=1;
-                       this_usbduxfastsub->dux_commands[OPBASE+5]=0;
-                       this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+5]=0;
-
-                       this_usbduxfastsub->dux_commands[LENBASE+6]=1;
-                       this_usbduxfastsub->dux_commands[OPBASE+6]=0;
-                       this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
-                       this_usbduxfastsub->dux_commands[LOGBASE+6]=0;
+                       this_usbduxfastsub->dux_commands[LOGBASE+3]=0xFF; // doesn't matter
                }
                break;
 
@@ -1028,7 +1037,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                this_usbduxfastsub->dux_commands[OPBASE+2]=0;
                this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask;
                this_usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
+               
                this_usbduxfastsub->dux_commands[LENBASE+3]=1;
                this_usbduxfastsub->dux_commands[OPBASE+3]=0x02; // data
                this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask;
@@ -1049,7 +1058,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                this_usbduxfastsub->dux_commands[OPBASE+5]=0;
                this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask;
                this_usbduxfastsub->dux_commands[LOGBASE+5]=0;
-
+               
                this_usbduxfastsub->dux_commands[LENBASE+6]=1;
                this_usbduxfastsub->dux_commands[OPBASE+6]=0;
                this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
@@ -1073,7 +1082,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                        this_usbduxfastsub->dux_commands[OUTBASE+j*2+1]=0xFE & rngmask; //count
                        this_usbduxfastsub->dux_commands[LOGBASE+j*2+1]=0;
                }
-
+               
                // 2 steps with duration 1: the idele step and step 6:
                steps_tmp=steps-2;
                // commit data to the FIFO and do the first part of the delay
@@ -1081,7 +1090,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                this_usbduxfastsub->dux_commands[OPBASE+4]=0x02; // data
                this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask; // no change
                this_usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
+               
                if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff;
                // do the second part of the delay
                this_usbduxfastsub->dux_commands[LENBASE+5]=steps_tmp-steps_tmp/2;
@@ -1093,49 +1102,47 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                this_usbduxfastsub->dux_commands[OPBASE+6]=0;
                this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
                this_usbduxfastsub->dux_commands[LOGBASE+6]=0;
-
+               
        case 16:
                if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff;
+               if(cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
+                       this_usbduxfastsub->dux_commands[LENBASE+0]=0x01; // branch back to state 0
+                       this_usbduxfastsub->dux_commands[OPBASE+0]=0x01; // deceision state w/o data
+                       this_usbduxfastsub->dux_commands[OUTBASE+0]=(0xFF-0x02) & rngmask; // reset
+                       this_usbduxfastsub->dux_commands[LOGBASE+0]=0x00; // RDY0 = 0
+               } else { // we just proceed to state 1
+                       this_usbduxfastsub->dux_commands[LENBASE+0]=255; // 30us reset pulse
+                       this_usbduxfastsub->dux_commands[OPBASE+0]=0;
+                       this_usbduxfastsub->dux_commands[OUTBASE+0]=(0xFF-0x02) & rngmask; // reset
+                       this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
+               }                               
+
                // commit data to the FIFO
-               this_usbduxfastsub->dux_commands[LENBASE+0]=1;
-               this_usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data
-               this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
-               this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
+               this_usbduxfastsub->dux_commands[LENBASE+1]=1;
+               this_usbduxfastsub->dux_commands[OPBASE+1]=0x02; // data
+               this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask;
+               this_usbduxfastsub->dux_commands[LOGBASE+1]=0;
 
-               // we have 6 states with duration 1
-               steps=steps-6;
+               // we have 2 states with duration 1
+               steps=steps-2;
 
                // do the first part of the delay
-               this_usbduxfastsub->dux_commands[LENBASE+1]=steps/2;
-               this_usbduxfastsub->dux_commands[OPBASE+1]=0;
-               this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFE & rngmask;
-               this_usbduxfastsub->dux_commands[LOGBASE+1]=0;
-
-               this_usbduxfastsub->dux_commands[LENBASE+2]=1;
+               this_usbduxfastsub->dux_commands[LENBASE+2]=steps/2;
                this_usbduxfastsub->dux_commands[OPBASE+2]=0;
                this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFE & rngmask;
                this_usbduxfastsub->dux_commands[LOGBASE+2]=0;
 
-               this_usbduxfastsub->dux_commands[LENBASE+3]=1;
+               // and the second part
+               this_usbduxfastsub->dux_commands[LENBASE+3]=steps-steps/2;
                this_usbduxfastsub->dux_commands[OPBASE+3]=0;
-               this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFE & rngmask;
+               this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask;
                this_usbduxfastsub->dux_commands[LOGBASE+3]=0;
 
-               this_usbduxfastsub->dux_commands[LENBASE+4]=1;
-               this_usbduxfastsub->dux_commands[OPBASE+4]=0;
-               this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFE & rngmask;
-               this_usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
-               // and the second part
-               this_usbduxfastsub->dux_commands[LENBASE+5]=steps-steps/2;
-               this_usbduxfastsub->dux_commands[OPBASE+5]=0;
-               this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask;
-               this_usbduxfastsub->dux_commands[LOGBASE+5]=0;
+               this_usbduxfastsub->dux_commands[LENBASE+4]=0x09; // branch back to state 1
+               this_usbduxfastsub->dux_commands[OPBASE+4]=0x01; // deceision state w/o data
+               this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask;
+               this_usbduxfastsub->dux_commands[LOGBASE+4]=0xFF; // doesn't matter
 
-               this_usbduxfastsub->dux_commands[LENBASE+6]=1;
-               this_usbduxfastsub->dux_commands[OPBASE+6]=0;
-               this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask;
-               this_usbduxfastsub->dux_commands[LOGBASE+0]=0;
                break;
 
        default:
@@ -1144,7 +1151,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                up(&this_usbduxfastsub->sem);
                return -EFAULT;
        }
-
+               
 
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi %d: sending commands to the usb device\n",
@@ -1166,14 +1173,14 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s)
                        up(&this_usbduxfastsub->sem);
                        return -EFAULT;
                }
-               this_usbduxfastsub->ai_continous=0;
+               this_usbduxfastsub->ai_continous=0;     
        } else {
                // continous aquisition
                this_usbduxfastsub->ai_continous=1;
                this_usbduxfastsub->ai_sample_count=0;
        }
 
-        if(cmd->start_src == TRIG_NOW){
+        if((cmd->start_src == TRIG_NOW)||(cmd->start_src == TRIG_EXT)) {
                // enable this acquisition operation
                this_usbduxfastsub->ai_cmd_running=1;
                ret=usbduxfastsub_submit_InURBs(this_usbduxfastsub);
@@ -1243,28 +1250,28 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
        usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data
        usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask;
        usbduxfastsub->dux_commands[LOGBASE+0]=0;
-
+       
        // do the first part of the delay
        usbduxfastsub->dux_commands[LENBASE+1]=12;
        usbduxfastsub->dux_commands[OPBASE+1]=0;
        usbduxfastsub->dux_commands[OUTBASE+1]=0xFE & rngmask;
        usbduxfastsub->dux_commands[LOGBASE+1]=0;
-
+       
        usbduxfastsub->dux_commands[LENBASE+2]=1;
        usbduxfastsub->dux_commands[OPBASE+2]=0;
        usbduxfastsub->dux_commands[OUTBASE+2]=0xFE & rngmask;
        usbduxfastsub->dux_commands[LOGBASE+2]=0;
-
+               
        usbduxfastsub->dux_commands[LENBASE+3]=1;
        usbduxfastsub->dux_commands[OPBASE+3]=0;
        usbduxfastsub->dux_commands[OUTBASE+3]=0xFE & rngmask;
        usbduxfastsub->dux_commands[LOGBASE+3]=0;
-
+               
        usbduxfastsub->dux_commands[LENBASE+4]=1;
        usbduxfastsub->dux_commands[OPBASE+4]=0;
        usbduxfastsub->dux_commands[OUTBASE+4]=0xFE & rngmask;
        usbduxfastsub->dux_commands[LOGBASE+4]=0;
-
+       
        // second part
        usbduxfastsub->dux_commands[LENBASE+5]=12;
        usbduxfastsub->dux_commands[OPBASE+5]=0;
@@ -1296,7 +1303,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
               (int)(usbduxfastsub->urbIn->dev));
 #endif
        for(i=0;i<PACKETS_TO_IGNORE;i++) {
-               err=USB_BULK_MSG(usbduxfastsub->usbdev,
+               err=USB_BULK_MSG(usbduxfastsub->usbdev, 
                                 usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP),
                                 usbduxfastsub->transfer_buffer,
                                 SIZEINBUF,
@@ -1311,7 +1318,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
        }
        // data points
        for(i=0;i<insn->n;) {
-               err=USB_BULK_MSG(usbduxfastsub->usbdev,
+               err=USB_BULK_MSG(usbduxfastsub->usbdev, 
                                 usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP),
                                 usbduxfastsub->transfer_buffer,
                                 SIZEINBUF,
@@ -1329,7 +1336,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
                               dev->minor);
                        up(&usbduxfastsub->sem);
                        return -EINVAL;
-               }
+               }                       
                for(j=chan;(j<n)&&(i<insn->n);j=j+16) {
                        data[i]=((uint16_t*)(usbduxfastsub->transfer_buffer))[j];
                        i++;
@@ -1375,7 +1382,7 @@ static int read_firmware(usbduxfastsub_t* usbduxfastsub, void *firmwarePtr,long
                       );
                return -ENOMEM;
        }
-
+       
        for (;;) {
                char    buf[256],*cp;
                char    type;
@@ -1424,7 +1431,7 @@ static int read_firmware(usbduxfastsub_t* usbduxfastsub, void *firmwarePtr,long
                        printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries.");
                        return -EFAULT;
                }
-
+               
                //printk("comedi_: usbduxfast: off=%x, len=%x:",off,len);
 
                /* Read the record type */
@@ -1515,11 +1522,11 @@ static void tidy_up(usbduxfastsub_t* usbduxfastsub_tmp) {
 
 // allocate memory for the urbs and initialise them
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void* usbduxfastsub_probe(struct usb_device *udev,
+static void* usbduxfastsub_probe(struct usb_device *udev, 
                             unsigned int interfnum,
                             const struct usb_device_id *id) {
 #else
-static int usbduxfastsub_probe(struct usb_interface *uinterf,
+static int usbduxfastsub_probe(struct usb_interface *uinterf, 
                           const struct usb_device_id *id) {
         struct usb_device *udev = interface_to_usbdev(uinterf);
 #endif
@@ -1611,7 +1618,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
                tidy_up(&(usbduxfastsub[index]));
                up(&start_stop_sem);
                return PROBE_ERR_RETURN( -ENOMEM);
-       }
+       }               
        usbduxfastsub[index].transfer_buffer=
                kmalloc(SIZEINBUF,GFP_KERNEL);
        if (!(usbduxfastsub[index].transfer_buffer)) {
@@ -1622,7 +1629,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
        }
        // we've reached the bottom of the function
        usbduxfastsub[index].probed=1;
-       up(&start_stop_sem);
+       up(&start_stop_sem);    
        printk("comedi_: usbduxfast%d has been successfully initialized.\n",index);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
        return (void*)(&usbduxfastsub[index]);
@@ -1648,7 +1655,7 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) {
        if (!usbduxfastsub_tmp) {
                printk("comedi_: usbduxfast: disconnect called with null pointer.\n");
                return;
-       }
+       }               
        if (usbduxfastsub_tmp->usbdev!=udev) {
                printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n");
                return;
@@ -1699,15 +1706,15 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
        usbduxfastsub[index].comedidev=dev;
 
        // trying to upload the firmware into the chip
-       if(comedi_aux_data(it->options, 0) &&
+       if(comedi_aux_data(it->options, 0) && 
           it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]){
                read_firmware(usbduxfastsub,
                        comedi_aux_data(it->options, 0),
                              it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
-       }
+       } 
 
        dev->board_name = BOARDNAME;
-
+       
        /* set number of subdevices */
        dev->n_subdevices=N_SUBDEVICES;
 
@@ -1735,7 +1742,7 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
        // analog input
        s->type=COMEDI_SUBD_AI;
        // readable and ref is to ground
-       s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+       s->subdev_flags=SDF_READABLE|SDF_GROUND;
        // 8 channels
        s->n_chan=16;
        // length of the channellist
@@ -1894,7 +1901,7 @@ static void exit_usbduxfast(void) {
 
 
 module_init(init_usbduxfast);
-module_exit(exit_usbduxfast);
+module_exit(exit_usbduxfast);                                      
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );