Device-BusPirate-Chip-AVR_HVSP

 view release on metacpan or  search on metacpan

lib/Device/BusPirate/Chip/AVR_HVSP.pm  view on Meta::CPAN

Returns the total number of words that are available.

=item * can_write

Returns true if the memory type can be written (in general; this does not take
into account the lock bits that might futher restrict a particular chip).

=back

=cut

sub memory_info
{
   my $self = shift;
   my ( $name ) = @_;

   my $memories = $self->{memories};
   $memories->[$_*2] eq $name and return $memories->[$_*2 + 1]
      for 0 .. $#$memories/2;

   die "$self->{part} does not have a $name memory";
}

=head2 %memories = $avr->memory_infos

Returns a key/value list of all the known device memories.

=cut

sub memory_infos
{
   my $self = shift;
   return @{ $self->{memories} };
}

=head2 $fuseinfo = $avr->fuseinfo

Returns a L<Device::BusPirate::Chip::AVR_HVSP::FuseInfo> instance containing
information on the fuses in the attached device type.

=cut

sub fuseinfo
{
   my $self = shift;

   require Device::BusPirate::Chip::AVR_HVSP::FuseInfo;
   return Device::BusPirate::Chip::AVR_HVSP::FuseInfo->for_part( $self->partname );
}

sub _transfer
{
   my $self = shift;

   my ( $sdi, $sii ) = @_;

   my $sdo = 0;
   my $mode = $self->mode;

   # A "byte" transfer consists of 11 clock transitions; idle low. Each bit is
   # clocked in from SDO on the falling edge of clocks 0 to 7, but clocked out
   # of SDI and SII on clocks 1 to 8.
   # We'll therefore toggle the clock 11 times; on each of the first 8 clocks
   # we raise it, then simultaneously lower it, writing out the next out bits
   # and reading in the input.
   # Serial transfer is MSB first in both directions
   #
   # We cheat massively here and rely on pipeline ordering of the actual
   # ->write calls, by writing all 22 of the underlying bytes to the Bus
   # Pirate serial port, then waiting on all 22 bytes to come back.

   Future->needs_all( map {
      my $mask = $_ < 8 ? (1 << 7-$_) : 0;

      Future->needs_all(
         $mode->write( $SCI => 1 ),

         $mode->writeread(
            $SDI => ( $sdi & $mask ),
            $SII => ( $sii & $mask ),
            $SCI => 0
         )->on_done( sub {
            $sdo |= $mask if shift->{$SDO};
         })
      )
   } 0 .. 10 )
      ->then( sub { Future->done( $sdo ) } );
}

sub _await_SDO_high
{
   my $self = shift;

   my $mode = $self->mode;

   my $count = 50;
   repeat {
      $count-- or return Future->fail( "Timeout waiting for device to ACK" );

      $mode->${\"read_$SDO"}
   } until => sub { $_[0]->failure or $_[0]->get };
}

# The AVR datasheet on HVSP does not name any of these operations, only
# giving them bit patterns. We'll use the names invented by RikusW. See also
#   https://sites.google.com/site/megau2s/

use constant {
   # SII values
   HVSP_CMD  => 0x4C, # Command
   HVSP_LLA  => 0x0C, # Load Lo Address
   HVSP_LHA  => 0x1C, # Load Hi Address
   HVSP_LLB  => 0x2C, # Load Lo Byte
   HVSP_LHB  => 0x3C, # Load Hi Byte
   HVSP_WLB  => 0x64, # Write Lo Byte = WRL = WFU0
   HVSP_WHB  => 0x74, # Write Hi Byte = WRH = WFU1
   HVSP_WFU2 => 0x66, # Write Extended Fuse
   HVSP_RLB  => 0x68, # Read Lo Byte
   HVSP_RHB  => 0x78, # Read Hi Byte
   HVSP_RSIG => 0x68, # Read Signature
   HVSP_RFU0 => 0x68, # Read Low Fuse



( run in 0.650 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )