summaryrefslogtreecommitdiffstats
path: root/reverse_engineering/accel.pl
diff options
context:
space:
mode:
Diffstat (limited to 'reverse_engineering/accel.pl')
-rwxr-xr-xreverse_engineering/accel.pl372
1 files changed, 372 insertions, 0 deletions
diff --git a/reverse_engineering/accel.pl b/reverse_engineering/accel.pl
new file mode 100755
index 0000000..ac17a0e
--- /dev/null
+++ b/reverse_engineering/accel.pl
@@ -0,0 +1,372 @@
+#!/usr/bin/env perl
+use strict;
+
+use IO::Socket::INET;
+use Data::Dumper;
+
+my $prompt = '> ';
+
+sub my_readline_worker($) {
+ my $sock = shift;
+ my $ret = "";
+ my $d = "";
+
+ while (1) {
+ return $ret if $sock->read( $d, 1 ) != 1;
+
+ next if $d eq "\n";
+
+ $ret .= $d;
+
+ return $ret if $d eq "\r";
+ return $ret if $ret =~ /> $/;
+
+ }
+
+}
+
+sub my_readline($) {
+ my $sock = shift;
+ my $ret = my_readline_worker($sock);
+
+ #print $ret."\n";
+ return $ret;
+}
+
+sub wait_for_prompt($) {
+ my $ocd = shift;
+
+ 1 while ( my_readline($ocd) ne $prompt );
+}
+
+sub open_ocd($) {
+ my $addr = shift;
+ my $sock = IO::Socket::INET->new($addr);
+ wait_for_prompt($sock);
+ $sock->printf( "reset halt\n");
+ wait_for_prompt($sock);
+ return $sock;
+}
+
+sub write_reg($$$) {
+ my ( $ocd, $r, $v ) = @_;
+
+ $ocd->printf( "mww 0x%08x 0x%08x\n", $r, $v );
+ wait_for_prompt($ocd);
+}
+
+sub read_reg($$) {
+ my ( $ocd, $r ) = @_;
+ my $ret;
+
+ $ocd->printf( "mdw 0x%08x\n", $r );
+
+ $ret = my_readline($ocd);
+ $ret = my_readline($ocd);
+
+ wait_for_prompt($ocd);
+
+ $ret =~ s/[\r\n\s]//g;
+
+ if ( $ret =~ /0x[0-9A-Fa-f]+:([0-9a-fA-F]+)/ ) {
+ return hex($1);
+ }
+
+ return undef;
+}
+
+sub dir_set($$) {
+ my ( $ocd, $v ) = @_;
+ write_reg( $ocd, 0x50000518, $v );
+}
+
+sub dir_clr($$) {
+ my ( $ocd, $v ) = @_;
+ write_reg( $ocd, 0x5000051c, $v );
+}
+
+sub io_set($$) {
+ my ( $ocd, $v ) = @_;
+ write_reg( $ocd, 0x50000508, $v );
+}
+
+sub io_clr($$) {
+ my ( $ocd, $v ) = @_;
+ write_reg( $ocd, 0x5000050c, $v );
+}
+
+sub io_get($) {
+ my $ocd = shift;
+ return read_reg( $ocd, 0x50000510 );
+}
+
+my $SDABIT = 1 << 12;
+my $SCLBIT = 1 << 13;
+
+sub i2c_set($$$) {
+ my ( $ocd, $scl, $sda ) = @_;
+ my $clr = 0;
+ my $set = 0;
+
+ if ($scl) {
+ $clr |= $SCLBIT;
+ }
+ else {
+ $set |= $SCLBIT;
+ }
+
+ if ($sda) {
+ $clr |= $SDABIT;
+ }
+ else {
+ $set |= $SDABIT;
+ }
+
+ dir_set( $ocd, $set );
+ dir_clr( $ocd, $clr );
+}
+
+sub i2c_get($) {
+ my $ocd = shift;
+
+ return ( io_get($ocd) & $SDABIT ) ? 1 : 0;
+}
+
+sub i2c_start($) {
+ my $ocd = shift;
+
+ i2c_set( $ocd, 1, 1 );
+ i2c_set( $ocd, 1, 0 );
+ i2c_set( $ocd, 0, 0 );
+
+ #print "S";
+}
+
+sub i2c_stop($) {
+ my $ocd = shift;
+
+ i2c_set( $ocd, 0, 0 );
+ i2c_set( $ocd, 1, 0 );
+ i2c_set( $ocd, 1, 1 );
+
+ #print "T\n";
+}
+
+sub i2c_sendbyte($$) {
+ my ( $ocd, $byte ) = @_;
+
+ for ( my $c = 0x80 ; $c ; $c >>= 1 ) {
+ my $v = ( $c & $byte ) ? 1 : 0;
+
+ #print $v;
+
+ i2c_set( $ocd, 0, $v );
+ i2c_set( $ocd, 1, $v );
+ i2c_set( $ocd, 0, $v );
+ }
+
+}
+
+sub i2c_recvbyte($) {
+ my ($ocd) = @_;
+
+ my $byte = 0;
+
+ for ( my $c = 0x80 ; $c ; $c >>= 1 ) {
+ my $v;
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ $v = i2c_get($ocd);
+
+ #print $v;
+
+ $byte |= $c if $v;
+
+ i2c_set( $ocd, 0, 1 );
+ }
+
+ return $byte;
+
+}
+
+sub i2c_startaddr($$) {
+ my ( $ocd, $addr ) = @_;
+ my $ret;
+
+ i2c_start($ocd);
+ i2c_sendbyte( $ocd, $addr );
+
+ #print " ";
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ $ret = i2c_get($ocd);
+ i2c_set( $ocd, 0, 1 );
+
+ #print $ret;
+
+ return $ret;
+
+}
+
+sub i2c_ping($$) {
+ my ( $ocd, $addr ) = @_;
+ my $ret;
+ $ret = i2c_startaddr( $ocd, $addr );
+ i2c_stop($ocd);
+ return $ret;
+}
+
+my $LIS_ADDR = 0x32;
+
+sub lis_write($$$) {
+ my ( $ocd, $reg, $v ) = @_;
+
+ my $ret;
+
+ i2c_startaddr( $ocd, $LIS_ADDR );
+
+ i2c_sendbyte( $ocd, $reg );
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ $ret = i2c_get($ocd);
+ i2c_set( $ocd, 0, 1 );
+
+ i2c_sendbyte( $ocd, $v );
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ i2c_set( $ocd, 0, 1 );
+
+ i2c_stop($ocd);
+}
+
+sub lis_read($$) {
+ my ( $ocd, $reg ) = @_;
+
+ my $ret;
+
+ i2c_startaddr( $ocd, $LIS_ADDR );
+
+ i2c_sendbyte( $ocd, $reg );
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ $ret = i2c_get($ocd);
+ i2c_set( $ocd, 0, 1 );
+
+ # mad repeated start
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+
+ i2c_startaddr( $ocd, $LIS_ADDR | 1 );
+
+ $ret = i2c_recvbyte($ocd);
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ i2c_set( $ocd, 0, 1 );
+
+ i2c_stop($ocd);
+
+ return $ret;
+}
+
+sub lis_read16($$) {
+ my ( $ocd, $reg ) = @_;
+
+ my $ret;
+
+ i2c_startaddr( $ocd, $LIS_ADDR );
+
+ i2c_sendbyte( $ocd, $reg | 0x80 );
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ $ret = i2c_get($ocd);
+ i2c_set( $ocd, 0, 1 );
+
+ # mad repeated start
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+
+ i2c_startaddr( $ocd, $LIS_ADDR | 1 );
+
+ $a = i2c_recvbyte($ocd);
+
+ i2c_set( $ocd, 0, 0 );
+ i2c_set( $ocd, 1, 0 );
+ i2c_set( $ocd, 0, 0 );
+
+ $b = i2c_recvbyte($ocd);
+
+ i2c_set( $ocd, 0, 1 );
+ i2c_set( $ocd, 1, 1 );
+ i2c_set( $ocd, 0, 1 );
+
+ i2c_stop($ocd);
+
+ $ret = $a | ( $b << 8 );
+
+ return $ret;
+}
+
+my $ocd = open_ocd('127.0.0.1:4444');
+
+io_clr( $ocd, $SCLBIT | $SDABIT );
+
+i2c_start($ocd);
+i2c_stop($ocd);
+
+
+lis_write($ocd,0x20,0x27);
+lis_write($ocd,0x22,0x0);
+printf "%02x\n",lis_read($ocd,0x22);
+my $a=io_get($ocd);
+lis_write($ocd,0x22,0xfe);
+printf "%02x\n",lis_read($ocd,0x22);
+my $b=io_get($ocd);
+
+my $v=$a;
+printf "%04b %04b %04b %04b %04b %04b %04b %04b\n",
+ ($v >>28) &0xf,
+ ($v >>24) &0xf,
+
+ ($v >>20) &0xf,
+ ($v >>16) &0xf,
+
+ ($v >>12) &0xf,
+ ($v >>8) &0xf,
+
+ ($v >>4) &0xf,
+ ($v) &0xf;
+$v=$b;
+
+
+printf "%04b %04b %04b %04b %04b %04b %04b %04b\n",
+ ($v >>28) &0xf,
+ ($v >>24) &0xf,
+
+ ($v >>20) &0xf,
+ ($v >>16) &0xf,
+
+ ($v >>12) &0xf,
+ ($v >>8) &0xf,
+
+ ($v >>4) &0xf,
+ ($v) &0xf;
+
+
+lis_write($ocd,0x22,0x0);
+
+
+while (1) {
+ printf "%04x %04x %04x\n", lis_read16( $ocd, 0x28 ),
+ lis_read16( $ocd, 0x2a ), lis_read16( $ocd, 0x2c );
+
+}
+
+die;
+