Skip to content

Commit

Permalink
trying some raw filehandle support for serial ports under unix
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyler Riddle committed Aug 5, 2012
1 parent 2cd6e71 commit d7cfe37
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 23 deletions.
2 changes: 1 addition & 1 deletion lib/Device/Firmdata.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sub build_io {
if ($^O eq 'MSWin32') {
$ioRole = 'Device::Firmdata::Role::IO::Win32Serial';
} else {
$ioRole = 'Device::Firmdata::Role::IO::DeviceSerial';
$ioRole = 'Device::Firmdata::Role::IO::Serial';
}

unless(defined($portName)) {
Expand Down
45 changes: 23 additions & 22 deletions lib/Device/Firmdata/Role/IO/DeviceSerial.pm
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,44 @@ sub build_driver {
my ($self) = @_;

my $driver = Device::SerialPort->new($self->portName());
#$driver->debug(1);
$driver->debug(1);

#$driver->datatype("raw");
$driver->handshake('none');
$driver->baudrate(57600) or die "Could not set baud: $^E";
$driver->databits(8);
$driver->parity('none') or die "Could not set parity: $^E";
$driver->stopbits(1) or die "Could not set stopbits: $^E";

#$driver->read_interval(0);
$driver->read_const_time(10000); # block at least 500ms
#$driver->read_char_time(10); # block 5us more for each character requested
$driver->stty_echo(0);

#$driver->write_settings();
$driver->read_const_time(10000);
$driver->read_char_time(0);

$driver->write_settings();

return $driver;
}

sub read {
my ($self, $bytes) = @_;

my ($bytesRead, $buf) = $self->driver->read($bytes);

if (0) {
use bytes;
my $ascii = $buf;
$ascii =~ s/([^ -~])/sprintf '\x{%02x}', ord($1)/eg;
warn "<<< $bytes ($buf) ($ascii)\n";
my $buf;

while(1) {
my ($bytesRead);

($bytesRead, $buf) = $self->driver->read($bytes);

next if $bytesRead == 0;

if ($bytesRead != $bytes) {
die "Tried to read $bytes bytes but only got $bytesRead";
}

last;
}

if ($bytesRead < 0) {
die "Could not read: $!";
} elsif ($bytesRead != $bytes) {
die "read of $bytes requested but only read $bytesRead";
}


return $buf;

}

sub write {
Expand All @@ -80,4 +81,4 @@ sub write {
return;
}

1;
1;
63 changes: 63 additions & 0 deletions lib/Device/Firmdata/Role/IO/Serial.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package Device::Firmdata::Role::IO::Serial;

use Moose::Role;

with 'Device::Firmdata::Role::IO';

has fh => ( is => 'ro', isa => 'GlobRef', required => 1, lazy => 1, builder => 'build_fh' );

sub build_fh {
my ($self) = @_;
my $path = $self->portName;
my $fh;

die "Could not open $path for read/write" unless open($fh, '+>', $path);

return $fh;
}

sub read {
my ($self, $wantBytes) = @_;
my $bytesLeft = $wantBytes;
my $readBytes = 0;
my $outputBuf;

while($bytesLeft > 0) {
my $readBuf;
my $bytesRead = sysread($self->fh, $readBuf, $bytesLeft);

if ($bytesRead == -1) {
die "Could not read from fh: $!";
}

$bytesLeft -= $bytesRead;

$outputBuf .= $readBuf;
}

if ($bytesLeft < 0) {
die "read too much data";
}

return $outputBuf;
}

sub write {
my ($self, $content) = @_;
my $length = length($content);
my $bytesLeft = length($content);

while($bytesLeft > 0) {
my $bytesSent = syswrite($self->fh, $content, $bytesLeft, $length - $bytesLeft);

if ($bytesSent == -1) {
die "could not write to fh: $!";
}

$bytesLeft -= $bytesSent;
}

return;
}

1;

0 comments on commit d7cfe37

Please sign in to comment.