Archived:Development: USB based video drivers: Difference between revisions

From LinuxTVWiki
Jump to navigation Jump to search
Line 2: Line 2:


see [[Em2820]] for more informations about how to write an usb video driver
see [[Em2820]] for more informations about how to write an usb video driver

1. download usbsnoop for windows
2. set up usbsnoop and attach it to the device you want to sniff
3. start a tv application (usbsnoop might slow down the whole box but it logs important device informations)

the logfile will contain all necessary code for enabling the datatransfer, following perlscript generated the code which can directly get pasted into the em2820 init function. As soon as the data transfer is enabled the IRQ function gets called and deinterlaces the received framedata.
The logfile also shows up the starting sequence of the videoframes, you might also have to adjust these values in the usb complete/IRQ function.
if you have any questions about it just join the #v4l on irc.freenode.org

<pre><nowiki>
#!/usr/bin/perl
$urbrequest=0;
$enabled=1;
$setuppacket=0;
while (<>){
# <<< URB 1 coming back <<<
if(/>>>/){
if(/URB (\d{1,})/){
$urbrequest=sprintf("%06d",$1);
}
$enabled=1;
$setuppacket=0;
}
if(/<<</){
if(/URB (\d{1,})/){
$urbrequest=sprintf("%06d",$1);
}
$enabled=1;
$setuppacket=0;
}
if(/ISOCH_TRANSFER/){
$enabled=0;
}
if(/URB_FUNCTION_SELECT_INTERFACE/){
$selectinterface=1;
}
if($enabled==1){
if(/AlternateSetting = 0x(\d{1,})/){
push(@{$urbhash{$urbrequest}{'remark'}},"Changing to Alternative Setting 0x$1\n");
}
if($setuppacket==1){
if(/0000: (.*)/){
if (@{$urbhash{$urbrequest}{'out'}} eq ""){
push(@{$urbhash{$urbrequest}{'out'}},$1);
} else {
push(@{$urbhash{$urbrequest+1000}{'out'}},$1);
}
}
} else {
if(/0000: (.*)/){
if (@{$urbhash{$urbrequest}{'in'}} eq ""){
push(@{$urbhash{$urbrequest}{'in'}},$1);
} else {
push(@{$urbhash{$urbrequest+1000}{'in'}},$1);
}
}
}
if(/SetupPacket.*/){
$setuppacket=1;
}
} else {
${$urbhash{$urbrequest}{'remark'}}[0]="don't know how to handle ISOCH_TRANSFER\n";
}

}


foreach $indexkey (sort keys %urbhash){
if($urbhash{$indexkey}{'remark'}[0] ne ""){
print $urbhash{$indexkey}{'remark'}[0];
next;
}
foreach $outkey (@{$urbhash{$indexkey}{'out'}}){
if(substr($outkey,0,1) eq "4"){
$outgoing=1;
$reg=substr($outkey,12,2);
$breq=substr($outkey,3,2);
} else {
$outgoing=0;
}
}
if($outgoing == 1){
print "em2800_write_regs_req(dev,0x$breq,0x$reg,\"";
foreach $inkey (@{$urbhash{$indexkey}{'in'}}){
$fullinkey=$inkey;
$inkey=~s/[^A-Za-z0-9 ]//g;
$inkey=~s/ *$//;

# print "stripped inkey $inkey))";
@inarray=split(/ /,$inkey);
$cntx=0;
foreach $value (@inarray){
if(substr($value,0,1) ne " "){
# print "(".substr($value,0,1).")";
print "\\x$value";
$cntx++;
}
}
print "\",$cntx);";
# print "($fullinkey vs $inkey)\n";
}
} else {
print "em2800_read_reg(dev,0x$breq,0x$reg);";

}
print "\n";
}
</nowiki></pre>

''Markus Rechberger/irc mrec''

Revision as of 16:29, 1 October 2005

USB Video

see Em2820 for more informations about how to write an usb video driver

1. download usbsnoop for windows 2. set up usbsnoop and attach it to the device you want to sniff 3. start a tv application (usbsnoop might slow down the whole box but it logs important device informations)

the logfile will contain all necessary code for enabling the datatransfer, following perlscript generated the code which can directly get pasted into the em2820 init function. As soon as the data transfer is enabled the IRQ function gets called and deinterlaces the received framedata. The logfile also shows up the starting sequence of the videoframes, you might also have to adjust these values in the usb complete/IRQ function. if you have any questions about it just join the #v4l on irc.freenode.org

#!/usr/bin/perl
$urbrequest=0;
$enabled=1;
$setuppacket=0;
while (<>){
#  <<<  URB 1 coming back  <<<
        if(/>>>/){
                if(/URB (\d{1,})/){
                        $urbrequest=sprintf("%06d",$1);
                }
                $enabled=1;
                $setuppacket=0;
        }
        if(/<<</){
                if(/URB (\d{1,})/){
                        $urbrequest=sprintf("%06d",$1);
                }
                $enabled=1;
                $setuppacket=0;
        }
        if(/ISOCH_TRANSFER/){
                $enabled=0;
        }
        if(/URB_FUNCTION_SELECT_INTERFACE/){
                $selectinterface=1;
        }
        if($enabled==1){
                if(/AlternateSetting  = 0x(\d{1,})/){
                        push(@{$urbhash{$urbrequest}{'remark'}},"Changing to Alternative Setting 0x$1\n");
                }
                if($setuppacket==1){
                        if(/0000: (.*)/){
                                if (@{$urbhash{$urbrequest}{'out'}} eq ""){
                                        push(@{$urbhash{$urbrequest}{'out'}},$1);
                                } else {
                                        push(@{$urbhash{$urbrequest+1000}{'out'}},$1);
                                }
                        }
                } else {
                        if(/0000: (.*)/){
                                if (@{$urbhash{$urbrequest}{'in'}} eq ""){
                                        push(@{$urbhash{$urbrequest}{'in'}},$1);
                                } else {
                                        push(@{$urbhash{$urbrequest+1000}{'in'}},$1);
                                }
                        }
                }
                if(/SetupPacket.*/){
                        $setuppacket=1;
                }
        } else {
                ${$urbhash{$urbrequest}{'remark'}}[0]="don't know how to handle ISOCH_TRANSFER\n";
        }

}


foreach $indexkey (sort keys %urbhash){
        if($urbhash{$indexkey}{'remark'}[0] ne ""){
                print $urbhash{$indexkey}{'remark'}[0];
                next;
        }
        foreach $outkey (@{$urbhash{$indexkey}{'out'}}){
                if(substr($outkey,0,1) eq "4"){
                        $outgoing=1;
                        $reg=substr($outkey,12,2);
                        $breq=substr($outkey,3,2);
                } else {
                        $outgoing=0;
                }
        }
        if($outgoing == 1){
                print "em2800_write_regs_req(dev,0x$breq,0x$reg,\"";
                foreach $inkey (@{$urbhash{$indexkey}{'in'}}){
                        $fullinkey=$inkey;
                        $inkey=~s/[^A-Za-z0-9 ]//g;
                        $inkey=~s/ *$//;

#               print "stripped inkey $inkey))";
                        @inarray=split(/ /,$inkey);
                        $cntx=0;
                        foreach $value (@inarray){
                                if(substr($value,0,1) ne " "){
#                               print "(".substr($value,0,1).")";
                                        print "\\x$value";
                                        $cntx++;
                                }
                        }
                        print "\",$cntx);";
#               print "($fullinkey vs $inkey)\n";
                }
        } else {
                print "em2800_read_reg(dev,0x$breq,0x$reg);";

        }
        print "\n";
}

Markus Rechberger/irc mrec