#!/usr/bin/perl -w use strict; use Device::SerialPort; use Data::Dumper; use Time::HiRes qw(usleep ualarm gettimeofday tv_interval nanosleep clock_gettime clock_getres clock); my $FT_APPLICATION = 0xAA; my $FT_CSF = 0xCC; my $FT_DCD = 0xEE; my $DS_8 = 0x08; my $DS_16= 0x10; my $DS_32= 0x20; my $commands = { 'read_memory' => "CCNCNCCCCC", 'write_memory'=> "CCNCCCCCNC", 'get_status' => pack("CCCCCCCCCCCCCCCC", 0x05, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 'write_file' => "CCNCNCCCCC", }; sub read_memory { my ($ser, $address, $size, $numwords) = @_; if (!defined $numwords) { $numwords = 1; } my $cmd = pack($commands->{'read_memory'} , 0x01, 0x01, # read command $address, $size, $numwords, 0, 0, 0, 0, 0); $ser->write($cmd); my $ack_str = $ser->read(4); my $ack = unpack("N", $ack_str); my $ack_res = pack("N", 0x56787856); my $sizeof = undef; my $result = undef; if ($ack eq $ack_res) { if ($size == $DS_8) { $sizeof = 1; } if ($size == $DS_16) { $sizeof = 2; } if ($size == $DS_32) { $sizeof = 4; } my $result_str = $ser->read($numwords*$sizeof); $result = unpack("N$numwords", $result_str); } else { printf ("oops, read failed, ack=0x%08x\n", $ack); } return $result; } sub write_memory { my ($ser, $address, $size, $value) = @_; my $cmd = pack($commands->{'write_memory'}, 0x02, 0x02, $address, $size, 0, 0, 0, 0, $value, 0); $ser->write($cmd); my $ack_str = $ser->read(4); my $ack0 = unpack("N", $ack_str); printf ("0x%08x\n", $ack0); $ack_str = $ser->read(4); $ack0 = unpack("N", $ack_str); printf ("0x%08x\n", $ack0); } sub get_status { my ($ser) = @_; my $cmd = $commands->{'get_status'}; $ser->write($cmd); usleep(100); my $result = $ser->read(4); $result = unpack("B", $result); return $result; } sub print_status { my ($status) = @_; printf($status . "\n"); if (defined $status) { printf ("Status = 0x%02x\n", $status); } else { printf ("Error. Status undefined\n"); } } sub write_file { my ($ser, $address, $header_filename, $filename, $filetype) = @_; if (!defined $filetype) { $filetype = $FT_APPLICATION; } my $header_file = new FileHandle($header_filename, "rb"); my $filesize = -s $header_file; my $header = $header_file->read($filesize); $header_file->close(); my $file = new FileHandle($filename, "rb"); $filesize = -s $filename; my $filestring = $file->read(); $file->close(); write_file_from_data($ser, $address, $header . $filestring, $filetype); } sub write_file_from_data { my ($ser, $address, $filestring, $filetype) = @_; if (!define $filetype) { $filetype = $FT_APPLICATION; } my $nbytes = len($filestring); printf ("Writing %d bytes\n", $nbytes); my $cmd = pack($commands->{'write_file'}, 0x04, 0x04, $address, 0x00, $nbytes, 0, 0, 0, 0, $filetype); $ser->write($cmd); my $result = $ser->read(4); printf ("%08x\n", unpack("N", $result)); $ser->write($filestring); # write the file # get_status(ser) } sub run_script { my ($ser, $script_filename) = @_; my $f = new FileHandle($script_filename, "r"); my @lines = <$f>; foreach my $line (@lines) { $line =~ s:;.*$::; if ($line =~ m:^\s*mem\s+write(\d+)\s+([0-9a-fA-Fx]+)\s+([0-9a-fA-Fx]+):) { my $bits_s = $1; my $address_s = $2; my $value_s = $3; my $bits = undef; if ($bits_s == 8) { $bits = $DS_8; } elsif ($bits_s == 16) { $bits = $DS_16; } elsif ($bits_s == 32) { $bits = $DS_32; } my $address = eval($address_s); my $value = eval($value_s); printf ("%d %x %x\n", $bits, $address, $value); write_memory($ser, $address, $bits, $value); } } } my $com = "/dev/ttyUSB0"; my $junk = 0; my $ser = new Device::SerialPort($com); $ser->baudrate(115200); $ser->databits(8); $ser->parity("none"); $ser->stopbits(1); $ser->handshake("xoff"); my $status = get_status($ser); print_status($status); #my $sram_address = 0x78000000; # baby ###my $sram_address = 0x1001FFF0; # fab4 #write_memory($ser, $sram_address, $DS_32, 0xdeadbeef); #my $result = read_memfory($ser, $sram_address, $DS_32); #for i in range(len(result)): # print "0x%08x "%result[i], # #v = read_memory(ser, 0x53f80008, DS_32) #print "0x%08x" % v # ## Initializing the DDR2 #run_script(ser, "baby_ddr2.txt") #status = get_status(ser) #print_status(status) ## Checking the DDR2 #result = read_memory(ser, 0x80000000, DS_32) #print "VERIFY = 0x%08x" % result[0] ## Load the program #write_file(ser, 0x83EFFFE0, 'header.bin', 'redboot-baby.bin') #status = get_status(ser) #print_status(status) # #ser.close() #ser = serial.Serial( # port=com, # baudrate=57600, # parity='N', # stopbits=serial.STOPBITS_ONE, # timeout=2, # ) #done = False #cnt = 0; #error= False #while (not done): # prompt = ser.readline() # if (prompt.startswith("RedBoot>")): # done = True # cnt = cnt + 1 # if (cnt > 50): # error = True # print "Error: Couldn't find redboot prompt." #if (not error): # ser.write("baudrate -b 1843200\n") # print ser.readline() # print ser.readline() # print "Resetting baud" # ser.setBaudrate(921600) # print "Changed baud to 921600. Sleeping for 3 seconds." # time.sleep(1) # ser.write("y\n") # ser.write("\n\n") # print ser.readline() # print ser.readline() # print ser.readline() # print ser.readline() # # ## result = read_memory(ser, 0x83f00000, DS_32) ##print "VERIFY = 0x%08x" % result[0] ##write_file_from_data(ser, 0x80000000, pack(">I", 0xFEFFFFEA))