From 472ebcbfaccd62adc0c4ab1c59a967c1d7034385 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 7 Sep 2015 11:52:14 +0100 Subject: fish --- reverse_engineering/Makefile | 37 ++++ reverse_engineering/accel.pl | 372 +++++++++++++++++++++++++++++++++ reverse_engineering/bits.pl | 150 ++++++++++++++ reverse_engineering/eeprom.pl | 304 +++++++++++++++++++++++++++ reverse_engineering/fish.png | Bin 0 -> 1622 bytes reverse_engineering/gdb.script | 2 + reverse_engineering/main | 0 reverse_engineering/openocd.cfg | 13 ++ reverse_engineering/scani2c-1.pl | 301 +++++++++++++++++++++++++++ reverse_engineering/scani2c-2.pl | 363 +++++++++++++++++++++++++++++++++ reverse_engineering/scani2c-3.pl | 367 +++++++++++++++++++++++++++++++++ reverse_engineering/screen.pl | 429 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 2338 insertions(+) create mode 100644 reverse_engineering/Makefile create mode 100755 reverse_engineering/accel.pl create mode 100755 reverse_engineering/bits.pl create mode 100755 reverse_engineering/eeprom.pl create mode 100644 reverse_engineering/fish.png create mode 100644 reverse_engineering/gdb.script create mode 100644 reverse_engineering/main create mode 100644 reverse_engineering/openocd.cfg create mode 100755 reverse_engineering/scani2c-1.pl create mode 100755 reverse_engineering/scani2c-2.pl create mode 100755 reverse_engineering/scani2c-3.pl create mode 100755 reverse_engineering/screen.pl (limited to 'reverse_engineering') diff --git a/reverse_engineering/Makefile b/reverse_engineering/Makefile new file mode 100644 index 0000000..4bcb255 --- /dev/null +++ b/reverse_engineering/Makefile @@ -0,0 +1,37 @@ +PROG=main + +BDADDR=CF:5F:D0:0C:8D:FC + + +OOCD=openocd +OOCD_CFG=openocd.cfg + + +CROSS=arm-none-eabi- +CC := $(CROSS)gcc +AS := $(CROSS)as +AR := $(CROSS)ar +LD := $(CROSS)ld +NM := $(CROSS)nm +OBJDUMP := $(CROSS)objdump +OBJCOPY := $(CROSS)objcopy +SIZE := $(CROSS)size +GDB := $(CROSS)gdb +NRFUTIL := nrfutil + +ds: + $(OOCD) -f $(OOCD_CFG) + +debug: ${PROG} + ${GDB} -x gdb.script ${PROG} + +reset: + ${OOCD} -f ${OOCD_CFG} \ + -c "init" \ + -c "reset init" \ + -c "reset" \ + -c "shutdown" + +scani2c: + perl scani2c.pl + 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; + diff --git a/reverse_engineering/bits.pl b/reverse_engineering/bits.pl new file mode 100755 index 0000000..c6b3c7f --- /dev/null +++ b/reverse_engineering/bits.pl @@ -0,0 +1,150 @@ +#!/usr/bin/env perl +use strict; + +use IO::Socket::INET; +use Data::Dumper; +#use IO::Socket::Timeout; +# +# + +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); +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_get($) { +my $ocd=shift; +return read_reg($ocd,0x50000514); +} + + +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 $ocd=open_ocd('127.0.0.1:4444' ); + + +my $ov=-1; +while (1) { +my $v=dir_get($ocd); + +next if $v == $ov; + +$ov=$v; + + +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; + +} + diff --git a/reverse_engineering/eeprom.pl b/reverse_engineering/eeprom.pl new file mode 100755 index 0000000..695ef48 --- /dev/null +++ b/reverse_engineering/eeprom.pl @@ -0,0 +1,304 @@ +#!/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 << 9; +my $SCLBIT = 1 << 8; + +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 $EE_ADDR = 0xa0; + +#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 ee_read($$) { + my ( $ocd, $a ) = @_; + + my $ret; + + i2c_startaddr( $ocd, $EE_ADDR ); + + i2c_sendbyte( $ocd, ($a >> 8 ) & 0xff ); + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + i2c_set( $ocd, 0, 1 ); + + i2c_sendbyte( $ocd, $a & 0xff ); + + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + i2c_set( $ocd, 0, 1 ); + + + # mad repeated start + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + + i2c_startaddr( $ocd, $EE_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; +} + +my $ocd = open_ocd('127.0.0.1:4444'); + +io_clr( $ocd, $SCLBIT | $SDABIT ); + +i2c_start($ocd); +i2c_stop($ocd); + + +$|=1; + +for (my $i=0;$i<0x100;$i+=0x10) { +printf "%04x ",$i; +for (my $j=0;$j<0x10;$j++) { +printf " %02x",ee_read($ocd,$i+$j); +} +printf "\n"; +} + +die; + diff --git a/reverse_engineering/fish.png b/reverse_engineering/fish.png new file mode 100644 index 0000000..5eb87c8 Binary files /dev/null and b/reverse_engineering/fish.png differ diff --git a/reverse_engineering/gdb.script b/reverse_engineering/gdb.script new file mode 100644 index 0000000..7cf9d09 --- /dev/null +++ b/reverse_engineering/gdb.script @@ -0,0 +1,2 @@ +target remote localhost:3333 +cont diff --git a/reverse_engineering/main b/reverse_engineering/main new file mode 100644 index 0000000..e69de29 diff --git a/reverse_engineering/openocd.cfg b/reverse_engineering/openocd.cfg new file mode 100644 index 0000000..b8d024a --- /dev/null +++ b/reverse_engineering/openocd.cfg @@ -0,0 +1,13 @@ +# nF51822 Target +source [find interface/stlink-v2.cfg] + +#source [find interface/jlink.cfg] +#transport select swd + + +#set WORKAREASIZE 0x4000 +set WORKAREASIZE 0x0 +source [find target/nrf51.cfg] + +# use hardware reset, connect under reset +#reset_config srst_only srst_nogate diff --git a/reverse_engineering/scani2c-1.pl b/reverse_engineering/scani2c-1.pl new file mode 100755 index 0000000..5897492 --- /dev/null +++ b/reverse_engineering/scani2c-1.pl @@ -0,0 +1,301 @@ +#!/usr/bin/env perl +use strict; + +use IO::Socket::INET; +use Data::Dumper; +#use IO::Socket::Timeout; +# +# + +$SIG{INT}=\&quit; +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); +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<<23; +my $SCLBIT=1<<24; + + + +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_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 $SDADDR=0x78; + +sub sd_write($$$) { +my ($ocd,$dnc,$v)=@_; + +my $ack1; +my $ack2; + +i2c_startaddr($ocd,$SDADDR); +i2c_sendbyte($ocd,0x80| ($dnc ? 0x40:0x00)); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack1=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_sendbyte($ocd,$v); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack2=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_stop($ocd); + +return $ack1 | $ack2; +} + +sub sd_cmd($$) +{ +my ($ocd,$c)=@_; + +return sd_write($ocd,0,$c); +} + +sub sd_dat($$) +{ +my ($ocd,$d)=@_; + +return sd_write($ocd,1,$d); +} + + + + + +my $LED=1<<22; +my $SCREEN_PWR=1<<25; +my $SCREEN_NRESET=1<<30; + +my $ocd=open_ocd('127.0.0.1:4444' ); + + +sub quit +{ + io_clr($ocd,$SCREEN_PWR); + io_set($ocd,$LED); + kill 9,$$; +} + + +io_clr($ocd,$SCLBIT | $SDABIT); + +dir_set($ocd,$LED | $SCREEN_PWR); +io_clr($ocd,$LED); +io_clr($ocd,$SCREEN_PWR); + +i2c_start($ocd); +i2c_stop($ocd); + +for (my $a=0;$a<0x100;$a++) { +printf "a=0x%02x ",$a; +i2c_ping($ocd,$a); +} + + + + + + + diff --git a/reverse_engineering/scani2c-2.pl b/reverse_engineering/scani2c-2.pl new file mode 100755 index 0000000..0b0cdcf --- /dev/null +++ b/reverse_engineering/scani2c-2.pl @@ -0,0 +1,363 @@ +#!/usr/bin/env perl +use strict; + +use IO::Socket::INET; +use Data::Dumper; +#use IO::Socket::Timeout; +# +# + +$SIG{INT}=\&quit; +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); +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<<9; +my $SCLBIT=1<<8; + + + +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_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 $SDADDR=0x78; + +sub sd_write($$$) { +my ($ocd,$dnc,$v)=@_; + +my $ack1; +my $ack2; + +i2c_startaddr($ocd,$SDADDR); +i2c_sendbyte($ocd,0x80| ($dnc ? 0x40:0x00)); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack1=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_sendbyte($ocd,$v); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack2=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_stop($ocd); + +return $ack1 | $ack2; +} + +sub sd_cmd($$) +{ +my ($ocd,$c)=@_; + +return sd_write($ocd,0,$c); +} + +sub sd_dat($$) +{ +my ($ocd,$d)=@_; + +return sd_write($ocd,1,$d); +} + + + + + +my $LED=1<<22; +my $SCREEN_PWR=1<<25; +my $SCREEN_NRESET=1<<30; + +my $ocd=open_ocd('127.0.0.1:4444' ); + + +sub quit +{ + io_clr($ocd,$SCREEN_PWR); + io_set($ocd,$LED); + kill 9,$$; +} + + + +#dir_set($ocd,$LED | $SCREEN_PWR); +io_clr($ocd,$SCLBIT | $SDABIT); +#io_clr($ocd,$LED); + +i2c_start($ocd); +i2c_stop($ocd); + +for (my $a=0;$a<0x100;$a++) { +printf "a=0x%02x ",$a; +i2c_ping($ocd,$a); +} + + +die; + + + +#Power cycle screen +io_clr($ocd,$SCREEN_PWR); +io_set($ocd,$SCREEN_PWR); + +# off +sd_cmd($ocd,0xae); + +# set clock freq +sd_cmd($ocd,0xd5); +sd_cmd($ocd,0xa0); + +#set multiplex ratio +sd_cmd($ocd,0xa8); +sd_cmd($ocd,0x1f); + +#set display offset +sd_cmd($ocd,0xd3); +sd_cmd($ocd,0x00); + +#set display start +sd_cmd($ocd,0x40); + +#set charge pump using DC/DC +sd_cmd($ocd,0x8d); +sd_cmd($ocd,0x14); + +#set segment remap +sd_cmd($ocd,0xa1); + +#set com scan direction +sd_cmd($ocd,0xc8); + +# set com pins hardware config. +sd_cmd($ocd,0xda); +sd_cmd($ocd,0x02); + +#set contrast +sd_cmd($ocd,0x81); +sd_cmd($ocd,0x8f); + +#set precharge period using DC/DC +sd_cmd($ocd,0xd9); +sd_cmd($ocd,0xf1); + +#set deselect voltage +sd_cmd($ocd,0xdb); +sd_cmd($ocd,0x40); + +#set display on/off +sd_cmd($ocd,0xa4); + +#set display on +sd_cmd($ocd,0xaf); + +while (1) { +sd_cmd($ocd,0xa7); +sleep(1); +sd_cmd($ocd,0xa6); +sleep(1); +} + + + + diff --git a/reverse_engineering/scani2c-3.pl b/reverse_engineering/scani2c-3.pl new file mode 100755 index 0000000..5898ac1 --- /dev/null +++ b/reverse_engineering/scani2c-3.pl @@ -0,0 +1,367 @@ +#!/usr/bin/env perl +use strict; + +use IO::Socket::INET; +use Data::Dumper; +#use IO::Socket::Timeout; +# +# + +$SIG{INT}=\&quit; +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); +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_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 $SDADDR=0x78; + +sub sd_write($$$) { +my ($ocd,$dnc,$v)=@_; + +my $ack1; +my $ack2; + +i2c_startaddr($ocd,$SDADDR); +i2c_sendbyte($ocd,0x80| ($dnc ? 0x40:0x00)); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack1=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_sendbyte($ocd,$v); + +i2c_set($ocd,0,1); +i2c_set($ocd,1,1); +$ack2=i2c_get($ocd); +i2c_set($ocd,0,1); + +i2c_stop($ocd); + +return $ack1 | $ack2; +} + +sub sd_cmd($$) +{ +my ($ocd,$c)=@_; + +return sd_write($ocd,0,$c); +} + +sub sd_dat($$) +{ +my ($ocd,$d)=@_; + +return sd_write($ocd,1,$d); +} + + + + + +my $LED=1<<22; +my $SCREEN_PWR=1<<25; +my $SCREEN_NRESET=1<<30; + +my $ocd=open_ocd('127.0.0.1:4444' ); + + +sub quit +{ + io_clr($ocd,$SCREEN_PWR); + io_set($ocd,$LED); + kill 9,$$; +} + + + +#dir_set($ocd,$LED | $SCREEN_PWR); +io_clr($ocd,$SCLBIT | $SDABIT); +#io_clr($ocd,$LED); + +i2c_start($ocd); +i2c_stop($ocd); + +for (my $a=0;$a<0x100;$a++) { +printf "a=0x%02x ",$a; +i2c_ping($ocd,$a); +i2c_start($ocd); +i2c_stop($ocd); +i2c_start($ocd); +i2c_stop($ocd); +} + + +die; + + + +#Power cycle screen +io_clr($ocd,$SCREEN_PWR); +io_set($ocd,$SCREEN_PWR); + +# off +sd_cmd($ocd,0xae); + +# set clock freq +sd_cmd($ocd,0xd5); +sd_cmd($ocd,0xa0); + +#set multiplex ratio +sd_cmd($ocd,0xa8); +sd_cmd($ocd,0x1f); + +#set display offset +sd_cmd($ocd,0xd3); +sd_cmd($ocd,0x00); + +#set display start +sd_cmd($ocd,0x40); + +#set charge pump using DC/DC +sd_cmd($ocd,0x8d); +sd_cmd($ocd,0x14); + +#set segment remap +sd_cmd($ocd,0xa1); + +#set com scan direction +sd_cmd($ocd,0xc8); + +# set com pins hardware config. +sd_cmd($ocd,0xda); +sd_cmd($ocd,0x02); + +#set contrast +sd_cmd($ocd,0x81); +sd_cmd($ocd,0x8f); + +#set precharge period using DC/DC +sd_cmd($ocd,0xd9); +sd_cmd($ocd,0xf1); + +#set deselect voltage +sd_cmd($ocd,0xdb); +sd_cmd($ocd,0x40); + +#set display on/off +sd_cmd($ocd,0xa4); + +#set display on +sd_cmd($ocd,0xaf); + +while (1) { +sd_cmd($ocd,0xa7); +sleep(1); +sd_cmd($ocd,0xa6); +sleep(1); +} + + + + diff --git a/reverse_engineering/screen.pl b/reverse_engineering/screen.pl new file mode 100755 index 0000000..f78bbdf --- /dev/null +++ b/reverse_engineering/screen.pl @@ -0,0 +1,429 @@ +#!/usr/bin/env perl +use strict; + +use GD::Image; + +use IO::Socket::INET; +use Data::Dumper; + +#use IO::Socket::Timeout; +# +# + +$SIG{INT} = \&quit; +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 << 23; +my $SCLBIT = 1 << 24; + +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_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 $SDADDR = 0x78; + +sub sd_write($$$) { + my ( $ocd, $dnc, $v ) = @_; + + my $ack1; + my $ack2; + + i2c_startaddr( $ocd, $SDADDR ); + i2c_sendbyte( $ocd, 0x80 | ( $dnc ? 0x40 : 0x00 ) ); + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + $ack1 = i2c_get($ocd); + i2c_set( $ocd, 0, 1 ); + + i2c_sendbyte( $ocd, $v ); + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + $ack2 = i2c_get($ocd); + i2c_set( $ocd, 0, 1 ); + + i2c_stop($ocd); + + return $ack1 | $ack2; +} + +sub sd_cmd($$) { + my ( $ocd, $c ) = @_; + + return sd_write( $ocd, 0, $c ); +} + +sub sd_dat($$) { + my ( $ocd, $d ) = @_; + + return sd_write( $ocd, 1, $d ); +} + +sub sd_address_mode($$) { + my ( $ocd, $m ) = @_; + + sd_cmd( $ocd, 0x20 ); + sd_cmd( $ocd, $m ); +} + +sub sd_cols($$$) { + my ( $ocd, $s, $e ) = @_; + + sd_cmd( $ocd, 0x21 ); + sd_cmd( $ocd, $s ); + sd_cmd( $ocd, $e ); +} + +sub sd_rows($$$) { + my ( $ocd, $s, $e ) = @_; + + sd_cmd( $ocd, 0x22 ); + sd_cmd( $ocd, $s ); + sd_cmd( $ocd, $e ); +} + +sub sd_init($) { + my $ocd = shift; + + # off + sd_cmd( $ocd, 0xae ); + + # set clock freq + sd_cmd( $ocd, 0xd5 ); + sd_cmd( $ocd, 0xa0 ); + + #set multiplex ratio + sd_cmd( $ocd, 0xa8 ); + sd_cmd( $ocd, 0x1f ); + + #set display offset + sd_cmd( $ocd, 0xd3 ); + sd_cmd( $ocd, 0x00 ); + + #set display start + sd_cmd( $ocd, 0x40 ); + + #set charge pump using DC/DC + sd_cmd( $ocd, 0x8d ); + sd_cmd( $ocd, 0x14 ); + + #set segment remap + sd_cmd( $ocd, 0xa1 ); + + #set com scan direction + sd_cmd( $ocd, 0xc8 ); + + # set com pins hardware config. + sd_cmd( $ocd, 0xda ); + sd_cmd( $ocd, 0x02 ); + + #set contrast + sd_cmd( $ocd, 0x81 ); + sd_cmd( $ocd, 0x8f ); + + #set precharge period using DC/DC + sd_cmd( $ocd, 0xd9 ); + sd_cmd( $ocd, 0xf1 ); + + #set deselect voltage + sd_cmd( $ocd, 0xdb ); + sd_cmd( $ocd, 0x40 ); + + #set display on/off + sd_cmd( $ocd, 0xa4 ); + + #set display on + sd_cmd( $ocd, 0xaf ); +} + +sub sd_display($$) { + my ( $ocd, $fn ) = @_; + +my $ack; + + my $file=GD::Image->new($fn); + + my $img=GD::Image->new(128,32,1); + + $img->copy($file,0,0,0,0,128,32); + + sd_cols($ocd,0,127); + sd_rows($ocd,0,63); + + + for (my $y=0;$y<32;$y+=8) { + + print "y=$y\n"; + i2c_startaddr( $ocd, $SDADDR ); + i2c_sendbyte( $ocd, 0x40 ); + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + + $ack = i2c_get($ocd); + i2c_set( $ocd, 0, 1 ); + print " "; + + + for (my $x=0;$x<128;++$x) { + + my $v=0; + my $c=0x1; + + for (my $i=0;$i<8;++$i) { + my $w=$img->getPixel($x,$i+$y); + +# print "r=$r,g=$g,b=$b\n"; + + $v|=$c if $w>8388607; + + $c<<=1; + } + + + i2c_sendbyte( $ocd, $v ); + + i2c_set( $ocd, 0, 1 ); + i2c_set( $ocd, 1, 1 ); + + $ack = i2c_get($ocd); + i2c_set( $ocd, 0, 1 ); + + print " "; + + + } + i2c_stop($ocd); + } + + + +} + +my $ocd = open_ocd('127.0.0.1:4444'); + +my $LED = 1 << 22; +my $SCREEN_PWR = 1 << 25; +my $SCREEN_BRIGHT = 1 << 30; + +sub quit +{ + io_clr( $ocd, $SCREEN_PWR ); + io_clr( $ocd, $SCREEN_BRIGHT ); + io_set( $ocd, $LED ); + kill 9, $$; +} + +dir_set( $ocd, $LED | $SCREEN_PWR | $SCREEN_BRIGHT ); +io_clr( $ocd, $SCLBIT | $SDABIT ); +io_clr( $ocd, $LED ); + +i2c_start($ocd); +i2c_stop($ocd); + +#for (my $a=0;$a<0x100;$a++) { +#printf "a=0x%02x ",$a; +#i2c_ping($ocd,$a); +#} +# + +#Power down screen +io_clr( $ocd, $SCREEN_PWR | $SCREEN_BRIGHT ); + +#power up screen +io_set( $ocd, $SCREEN_PWR | $SCREEN_BRIGHT ); +sd_init($ocd); + +sd_address_mode( $ocd, 0x0 ); + +sd_display($ocd,"fish.png"); + +while (1) { + sd_cmd( $ocd, 0xa7 ); + sleep(1); + sd_cmd( $ocd, 0xa6 ); + sleep(1); +} + -- cgit v1.2.3