Skip to content

Commit

Permalink
Use newest Device::BusPirate for macOS support
Browse files Browse the repository at this point in the history
  • Loading branch information
a3f committed Jun 6, 2018
1 parent f4eb602 commit 2f08de3
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 63 deletions.
17 changes: 12 additions & 5 deletions README.pod
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,21 @@ version 0.001

=head1 DESCRIPTION

The Nintendo Gameboy Advance can either boot from cartridge or over link cable. The latter is caled multiboot mode and is basically SPI and a homebrew encoding scheme.
This utility allows uploading multiboot GBA images with the L<BusPirate|Device::BusPirate>. Don't forget to pass C<-specs=gba_mb.specs> to GCC if you want to link a multiboot image. The package's C<share/> subdirectory contains an L<example Makefile|https://github.com/athreef/Device-GBA/blob/master/share/testimg/Makefile> for cross-compilation.
The Nintendo Gameboy Advance can either boot from cartridge or over link cable. The latter is caled multiboot mode and is basically SPI and a homebrew encoding scheme. Unfortunately, the Bus Pirate doesn't have a 100k SPI mode, so we are using 125k instead. If you encounter problems with booting, use the next lower speed (30k) as bitrate.
This utility allows uploading multiboot GBA images with the L<BusPirate|Device::BusPirate>. Don't forget to pass C<-specs=gba_mb.specs> to devkitARM GCC if you want to link a multiboot image. The package's C<share/> subdirectory contains an L<example Makefile|https://github.com/athreef/Device-GBA/blob/master/share/testimg/Makefile> for cross-compilation. The wiring is as follows:

GBA Bus Pirate
SO --> MISO
SI <-- MOSI
CLK <-- CLK

Note: This is still work in progress!

=head1 OPTIONS

=head2 pirate

Buspirate COM port
Buspirate COM port/device file

$ gba -p <COM_port>

Expand Down Expand Up @@ -85,7 +92,7 @@ Ahmad Fatoum C<< <[email protected]> >>, L<http://a3f.at>

Copyright (C) 2018 Ahmad Fatoum

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License v2.0 or later.

=cut
88 changes: 70 additions & 18 deletions bin/gba
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use open qw( :encoding(UTF-8) :std );
use Module::Load qw(load);
use Getopt::Long::Descriptive;
use Device::GBA;
use Scalar::Util 'looks_like_number';

use utf8;

Expand Down Expand Up @@ -56,14 +57,21 @@ gba - Command-line code uploader for the Gameboy Advance
=head1 DESCRIPTION
The Nintendo Gameboy Advance can either boot from cartridge or over link cable. The latter is caled multiboot mode and is basically SPI and a homebrew encoding scheme.
This utility allows uploading multiboot GBA images with the L<BusPirate|Device::BusPirate>. Don't forget to pass C<-specs=gba_mb.specs> to GCC if you want to link a multiboot image. The package's C<share/> subdirectory contains an L<example Makefile|https://github.com/athreef/Device-GBA/blob/master/share/testimg/Makefile> for cross-compilation.
The Nintendo Gameboy Advance can either boot from cartridge or over link cable. The latter is caled multiboot mode and is basically SPI and a homebrew encoding scheme. Unfortunately, the Bus Pirate doesn't have a 100k SPI mode, so we are using 125k instead. If you encounter problems with booting, use the next lower speed (30k) as bitrate.
This utility allows uploading multiboot GBA images with the L<BusPirate|Device::BusPirate>. Don't forget to pass C<-specs=gba_mb.specs> to devkitARM GCC if you want to link a multiboot image. The package's C<share/> subdirectory contains an L<example Makefile|https://github.com/athreef/Device-GBA/blob/master/share/testimg/Makefile> for cross-compilation. The wiring is as follows:
GBA Bus Pirate
SO --> MISO
SI <-- MOSI
CLK <-- CLK
Note: This is still work in progress!
=head1 OPTIONS
=head2 pirate
Buspirate COM port
Buspirate COM port/device file
$ gba -p <COM_port>
Expand Down Expand Up @@ -95,15 +103,28 @@ sub opt_spec {
: '/dev/ttyUSB0' }],

[
verbosity => [
[ 'verbose' => "Verbose output" ],
verbosity => hidden => { one_of => [
[ 'verbose' => "Verbose output" ],
[ 'no-verbose' => "Don't output verbosely" ],
],
] },
],
[
mb => hidden => { one_of => [
[ 'multiboot' => "Upload firmware image over multiboot protocol" ],
[ 'no-multiboot|raw' => "Upload directly without multiboot handshakes" ],
] },
],
[
bus => hidden => { one_of => [
#[ 'uart' => "Communicate over UART" ],
[ 'spi' => "Communicate over 32-bit SPI" ],
] },
],
[ 'cat|c' => "Cat", { default => '125k' } ],
[ 'bitrate|b=s' => "BusPirate SPI speed", { default => '125k' } ],
#[ 'spi|s=s' => "Linux SPI device file" ],
[ 'version|v' => "show version number" ],
[ 'help|h' => "display a usage message" ],
[ 'version|v' => "show version number" ],
[ 'help|h' => "display a usage message" ],
);
}

Expand All @@ -127,13 +148,36 @@ sub validate_args {
exit;
}

if (@$args > 1) {
if ($opt->{multiboot} and $opt->{uart}) {
$self->usage_error(
"You can specify at most one GBA program to upload\n"
"Multiboot is only possible over SPI\n"
);
} elsif ( @$args == 0) {
print STDERR "No image specified. Uploading test image...\n";
push @$args, dist_file 'Device-GBA', 'testimg/test.gba';
}

$opt->{bus} = $opt->{bus} // 'spi';
if ($opt->{bus} eq 'uart' && not defined $opt->{mb}) {
$self->{multiboot} = 0;
} else {
$self->{multiboot} = ($opt->{mb} // 'multiboot') eq 'multiboot';
}
my $default_verbosity = $self->{multiboot} ? 'verbose' : 'no-verbose';
$self->{verbose} = ($opt->{verbosity} // $default_verbosity) eq 'verbose';

if ($self->{verbose} && not $self->{multiboot}) {
$self->usage_error(
"Verbose output is not possible when running in raw mode\n"
);
}

if ($self->{multiboot}) {
if (@$args > 1) {
$self->usage_error(
"You can specify at most one GBA program to upload\n"
);
} elsif ( @$args == 0) {
print STDERR "No image specified. Uploading test image...\n";
push @$args, dist_file 'Device-GBA', 'testimg/test.gba';
}
}

return;
Expand All @@ -142,9 +186,17 @@ sub validate_args {
sub execute {
my ($self, $opt, $args) = @_;

$opt->{verbosity} = $opt->{verbosity} // 'verbose';
my $gba = Device::GBA->new(buspirate => $opt->{pirate}, verbose => $opt->{verbosity} eq 'verbose', bitrate => $opt->{bitrate});
$gba->upload($args->[0]);
my $gba = Device::GBA->new(buspirate => $opt->{pirate}, verbose => $self->{verbose}, bitrate => $opt->{bitrate});
if ($self->{multiboot}) {
$gba->upload($args->[0]);
} else {
@ARGV = @$args;
my $num = 0xFFFF_FFFF;
while (<>) {
my $num = looks_like_number($_) ? $_ : $num;
printf "%08x\n", $gba->spi_writeread($num);
}
}

return;
}
Expand Down Expand Up @@ -176,7 +228,7 @@ Ahmad Fatoum C<< <[email protected]> >>, L<http://a3f.at>
Copyright (C) 2018 Ahmad Fatoum
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License v2.0 or later.
=cut
67 changes: 27 additions & 40 deletions lib/Device/GBA.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package Device::GBA;
use strict;
use warnings;
use integer;
use IO::Termios;
use Fcntl;
use Time::HiRes;
use Device::BusPirate;
use Device::BusPirate v0.15;
use File::stat;
use Term::ProgressBar;

Expand All @@ -21,13 +19,25 @@ use Carp;
=head1 NAME
Device::GBA - Perl Interface to the Gameboy Advance
=head1 SYNOPSIS
use Device::GBA;
my $gba = Device::GBA->new(buspirate => '/dev/ttyUSB0') or die "No such device!\n";
$gba->upload('helloworld.gba');
=head1 DESCRIPTION
The Nintendo Gameboy Advance can either boot from cartridge or over link cable. The latter is caled multiboot mode and is basically SPI and a homebrew encoding scheme. Unfortunately, the Bus Pirate doesn't have a 100k SPI mode, so we are using 125k instead. If you encounter problems with booting, use the next lower speed (30k) as bitrate.
This utility allows uploading multiboot GBA images with the L<BusPirate|Device::BusPirate>. Don't forget to pass C<-specs=gba_mb.specs> to devkitARM GCC if you want to link a multiboot image. The package's C<share/> subdirectory contains an L<example Makefile|https://github.com/athreef/Device-GBA/blob/master/share/testimg/Makefile> for cross-compilation. The wiring is as follows:
GBA Bus Pirate
SO --> MISO
SI <-- MOSI
CLK <-- CLK
Note: This is still work in progress!
=head1 METHODS AND ARGUMENTS
Expand All @@ -44,10 +54,6 @@ if an attempt to open the device has failed. Accepts following parameters:
COM port or handle of the BusPirate connected to the Gameboy Advance.
=item B<spi>
L<Device::BusPirate::Mode::SPI> instance.
=item B<verbose>
if true, methods on this instance will narrate what they're doing. Default is C<0>.
Expand All @@ -66,46 +72,24 @@ sub new {

$self->{log} = $self->{verbose} ? sub { printf @_ } : sub { };

if (!$self->{spi}) {
if (ref $self->{buspirate} ne 'Device::BusPirate') {
$self->{buspirate} = new_buspirate('Device::BusPirate', serial => $self->{buspirate}, %$self) or return;
}
$self->{spi} = $self->{buspirate}->enter_mode( "SPI" )->get;
if (ref $self->{buspirate} ne 'Device::BusPirate') {
$self->{buspirate} = Device::BusPirate->new(serial => $self->{buspirate}, %$self)
or return;
}

$self->{spi}->configure(mode => 3, speed => $self->{bitrate})->get;
enter_spi($self);

bless $self, $class;
return $self;
}

sub new_buspirate
sub enter_spi
{
my $class = shift;
my %args = @_;

my $serial = $args{serial} || Device::BusPirate::BUS_PIRATE;
my $baud = $args{baud} || 115200;

sysopen my $fd, $serial, O_RDWR|O_NDELAY|O_NOCTTY
or croak "Cannot open serial port $serial - $!";
my $fh = IO::Termios->new($fd)
or croak "Cannot wrap serial port $serial - $!";
$fh->set_mode( "$baud,8,n,1" )
or croak "Cannot set mode on serial port $serial";

$fh->setflag_icanon( 0 );
$fh->setflag_echo( 0 );

$fh->blocking( 0 );
$fh->setflag_cread( 1 );
$fh->setflag_clocal( 1 );

return bless {
fh => $fh,
alarms => [],
readers => [],
}, $class;
my $self = shift;
return if defined $self->{spi};

$self->{spi} = $self->{buspirate}->enter_mode( "SPI" )->get;
$self->{spi}->configure(mode => 3, speed => $self->{bitrate})->get;
}

=item upload
Expand Down Expand Up @@ -136,6 +120,8 @@ sub upload {
$self->log(".....GBA file length 0x%08x\r\n\n", $fsize);
$self->log("BusPirate(mstr) GBA(slave) \r\n\n");

$self->enter_spi;

$self->spi_handshake(0x00006202, 0x72026202, "Looking for GBA");

$self->spi_writeread(0x00006202, "Found GBA");
Expand Down Expand Up @@ -205,6 +191,7 @@ reads and writes 32 bit from the SPI bus.
sub spi_writeread {
my $self = shift;
my ($w, $msg) = @_;
$self->enter_spi;
my $r = unpack 'L>', $self->{spi}->writeread(pack 'L>', shift)->get;
$self->log("0x%08x 0x%08x ; %s\n", $r , $w, $msg) if defined $msg;
return $r;
Expand Down Expand Up @@ -273,6 +260,6 @@ Based on The uploader written by Ken Kaarvik.
Copyright (C) 2018 Ahmad Fatoum
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
it under the terms of the GNU General Public License v2.0 or later.
=cut
File renamed without changes.

0 comments on commit 2f08de3

Please sign in to comment.