Device-Serial-SLuRM
view release on metacpan or search on metacpan
lib/Device/Serial/MSLuRM.pm view on Meta::CPAN
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
# (C) Paul Evans, 2023-2025 -- leonerd@leonerd.org.uk
use v5.26;
use warnings;
use Object::Pad 0.807 ':experimental(inherit_field)';
package Device::Serial::MSLuRM 0.10;
class Device::Serial::MSLuRM;
inherit Device::Serial::SLuRM
qw( $_protocol );
use Carp;
use Future::AsyncAwait;
use Future::Mutex;
=encoding UTF-8
=head1 NAME
C<Device::Serial::MSLuRM> - communicate Multi-drop SLµRM over a serial port
=head1 SYNOPSIS
=for highlighter language=perl
use v5.36;
use Device::Serial::MSLuRM;
my $slurm = Device::Serial::MSLuRM->new(
dev => "/dev/ttyUSB0",
baud => 19200,
);
$slurm->run(
on_notify => sub ($node_id, $payload) {
printf "NOTIFY(%d): %v02X\n", $node_id, $payload;
}
)->await;
=head1 DESCRIPTION
This variant of L<Device::Serial::SLuRM> allows communication with a
collection of nodes using Multi-drop SLµRM over a serial port, such as over
an RS-485 bus.
The endpoint running with this module takes the role of the bus controller.
Currently this module does not support being a non-controller node.
=cut
use constant is_multidrop => 1;
=head1 METHODS
=head2 run
$run_f = $slurm->run( %args );
Starts the receiver run-loop, which can be used to wait for incoming NOTIFY
packets. This method returns a future, but the returned future will not
complete in normal circumstances. It will remain pending while the run-loop is
running. If an unrecoverable error happens (such as an IO error on the
underlying serial port device) then this future will fail.
Takes the following named arguments:
=over 4
=item on_notify => CODE
$on_notify->( $node_id, $payload )
Optional. Invoked on receipt of a NOTIFY packet.
=back
Note that unlike in the single-peer case, a multi-drop controller cannot
C<reset> all the nodes before starting this, as it does not know the full set
of nodes that need resetting.
=cut
async method _autoreset () {}
async method _reset ( $node_id )
{
# Node ID zero is the special broadcast address; do not attempt to reset it
return if $node_id == 0;
await $self->SUPER::_reset( $node_id );
}
=head2 recv_packet
( $pktctrl, $addr, $payload ) = await $slurm->recv_packet;
Waits for and returns the next packet to be received from the serial port.
Note that in a multi-drop scenario this packet may well be a reflection of one
sent by the controller, depending on how the serial port adapter works.
=cut
method recv_packet () { $_protocol->recv; }
=head2 send_packet
( run in 0.866 second using v1.01-cache-2.11-cpan-524268b4103 )