Device-Chip-AVR_HVSP

 view release on metacpan or  search on metacpan

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


Returns the number of words per page; the smallest amount that can be
written in one go.

=item * words

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

method memory_info ( $name )
{
   $_memories[$_*2] eq $name and return $_memories[$_*2 + 1]
      for 0 .. $#_memories/2;

   die "$_partname does not have a $name memory";
}

=head2 %memories = $avr->memory_infos

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

=cut

method memory_infos ()
{
   return @_memories;
}

=head2 $fuseinfo = $avr->fuseinfo

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

=cut

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

async method _transfer ( $sdi, $sii )
{
   my $SCI = $_pins{sci};
   my $SDI = $_pins{sdi};
   my $SII = $_pins{sii};
   my $SDO = $_pins{sdo};

   my $sdo = 0;
   my $proto = $self->protocol;

   # 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 bit transitions to the
   # underlying device, then waiting on all 11 reads to come back.

   my @f;
   foreach my $i ( 0 .. 10 ) {
      my $mask = $i < 8 ? (1 << 7-$i) : 0;

      push @f, $proto->write_gpios( { $SCI => 1 } );

      if( !$mask ) {
         push @f, $proto->write_gpios( { $SCI => 0 } );
         next;
      }

      # TODO: this used to be
      #   $mode->writeread
      # on the BusPirate version
      push @f,
         $proto->write_gpios( {
            $SDI => ( $sdi & $mask ),
            $SII => ( $sii & $mask ),
            $SCI => 0
         } ),

         $proto->read_gpios( [ $SDO ] )->on_done( sub ( $v ) {
            $sdo |= $mask if $v->{$SDO};
         });
   }

   await Future->needs_all( @f );

   return $sdo;
}

async method _await_SDO_high ()
{
   my $SDO = $_pins{sdo};

   my $proto = $self->protocol;

   my $count = 50;
   while(1) {
      $count-- or die "Timeout waiting for device to ACK";

      last if ( await $proto->read_gpios( [ $SDO ] ) )->{$SDO};
   }
}

# 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 {



( run in 1.251 second using v1.01-cache-2.11-cpan-f56aa216473 )