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 )