Browse files

trying some raw filehandle support for serial ports under unix

  • Loading branch information...
1 parent 2cd6e71 commit d7cfe3736997b7e578d45df0c4e2e74ea09e93ed Tyler Riddle committed Aug 5, 2012
Showing with 87 additions and 23 deletions.
  1. +1 −1 lib/Device/Firmdata.pm
  2. +23 −22 lib/Device/Firmdata/Role/IO/DeviceSerial.pm
  3. +63 −0 lib/Device/Firmdata/Role/IO/Serial.pm
View
2 lib/Device/Firmdata.pm
@@ -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)) {
View
45 lib/Device/Firmdata/Role/IO/DeviceSerial.pm
@@ -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 {
@@ -80,4 +81,4 @@ sub write {
return;
}
-1;
+1;
View
63 lib/Device/Firmdata/Role/IO/Serial.pm
@@ -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.