mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-04-21 12:27:27 +03:00
Adding lm32 demo to SAKC project
This commit is contained in:
128
lm32/logic/sakc/tools/lac-tool/lac-tool
Executable file
128
lm32/logic/sakc/tools/lac-tool/lac-tool
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Tool to control a LogicAnalyzerComponent
|
||||
#
|
||||
# You need to install ruby 1.8 (or later) and ruby-serialport
|
||||
# There are various programs to view .vcd files -- e.g. GtkWave
|
||||
#
|
||||
|
||||
require "serialport.so"
|
||||
require "optparse"
|
||||
|
||||
$PORT_PATH = "/dev/ttyUSB0"
|
||||
$PORT_BAUD = 115200
|
||||
$TIMESCALE = "10ns"
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: lac-tool [options] SELECT TRIGGER TRIGGERMASK FILENAME\n"
|
||||
o.separator ""
|
||||
o.separator " SELECT Hexadevimal select value transferred to the LAC"
|
||||
o.separator " TRIGGER Hexadecimal trigger value"
|
||||
o.separator " TRIGGERMASK Haxadevimal triggermask"
|
||||
o.separator " FILENAME .vcd file to be written"
|
||||
o.separator ""
|
||||
|
||||
o.on( "-b", "--baud BAUDRATE", Integer,
|
||||
"Serial port baudrate (default: #{$PORT_BAUD})" ) do |baud|
|
||||
$PORT_BAUD = baud
|
||||
end
|
||||
|
||||
o.on( "-s", "--serial SERIALPORT",
|
||||
"Path to serial port (default: #{$PORT_PATH})" ) do |port|
|
||||
$PORT_PATH = port
|
||||
end
|
||||
|
||||
o.on( "-t", "--timescale TIMESCALE",
|
||||
"Timescale announced in .vcd file (default: 10ns)" ) do |ts|
|
||||
$TIMESCALE = ts
|
||||
end
|
||||
|
||||
o.on( "-h", "--help", "Display this help message" ) do
|
||||
puts o
|
||||
exit 0
|
||||
end
|
||||
|
||||
o.separator ""
|
||||
o.separator "Example:"
|
||||
o.separator " ./lac-tool 0x00 0x02 0x03 trace.vcd -- Sets SELECT to 0 and waits for probe to be ??????10"
|
||||
o.separator ""
|
||||
end
|
||||
|
||||
###
|
||||
# Check arguments
|
||||
begin
|
||||
opts.parse!( ARGV )
|
||||
|
||||
raise "Missing arguments" if ARGV.length != 4;
|
||||
|
||||
select = ARGV[1].hex
|
||||
trig = ARGV[2].hex
|
||||
trigmask = ARGV[3].hex
|
||||
filename = ARGV[4]
|
||||
rescue => e
|
||||
STDERR.puts "\n#{e.message}"
|
||||
STDERR.puts
|
||||
STDERR.puts opts
|
||||
exit 1
|
||||
end
|
||||
|
||||
###
|
||||
# Open serial port
|
||||
begin
|
||||
ser = SerialPort.new( $PORT_PATH, $PORT_BAUD, 8, 1, SerialPort::NONE )
|
||||
ser.flow_control=SerialPort::NONE;
|
||||
rescue => e
|
||||
STDERR.puts "\nCould not open serial port: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
begin
|
||||
f = File.open( filename, mode="w" );
|
||||
rescue => e
|
||||
STDERR.puts "\nCould not open output file: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
# Write VCD header
|
||||
f.puts "$date"
|
||||
f.puts "\t" + Time.now.to_s
|
||||
f.puts "$end"
|
||||
f.puts "$version"
|
||||
f.puts "\tLogicAnalyzerComponent (http://www.das-labor.org/)"
|
||||
f.puts "$end"
|
||||
f.puts "$timescale"
|
||||
f.puts "\t#{$TIMESCALE}"
|
||||
f.puts "$end"
|
||||
|
||||
# Declare wires
|
||||
f.puts "$scope module lac $end"
|
||||
f.puts "$var wire 8 P probe[7:0] $end"
|
||||
f.puts "$enddefinitions $end"
|
||||
|
||||
# RESET LM
|
||||
6.times do
|
||||
ser.putc 0x00 # CMD_DISARM
|
||||
end
|
||||
|
||||
# Here we go
|
||||
ser.putc 0x01 # send CMD_ARM
|
||||
ser.putc select # set select value
|
||||
ser.putc trigmask # set trigger mask
|
||||
ser.putc trig # set trigger compare value
|
||||
ser.putc 0x00 # set pre-trigger value
|
||||
|
||||
puts "LAC armed; waiting for trigger condition..."
|
||||
|
||||
size = ser.getc;
|
||||
size = 1 << size;
|
||||
|
||||
printf( "TRIGGERED -- Reading 0x%x bytes...\n", size );
|
||||
|
||||
size.times { |step|
|
||||
byte = ser.getc
|
||||
f.puts "\##{step}"
|
||||
f.printf "b%08b P\n", byte
|
||||
}
|
||||
|
||||
ser.close
|
||||
f.close
|
||||
10
lm32/logic/sakc/tools/srec2vram/Makefile
Normal file
10
lm32/logic/sakc/tools/srec2vram/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -O2 -Wall
|
||||
|
||||
all: srec2vram
|
||||
|
||||
srec2vram: srec2vram.c
|
||||
$(CC) $(CFLAGS) -o srec2vram srec2vram.c
|
||||
|
||||
clean:
|
||||
rm -f srec2vram
|
||||
BIN
lm32/logic/sakc/tools/srec2vram/srec2vram
Executable file
BIN
lm32/logic/sakc/tools/srec2vram/srec2vram
Executable file
Binary file not shown.
158
lm32/logic/sakc/tools/srec2vram/srec2vram.c
Normal file
158
lm32/logic/sakc/tools/srec2vram/srec2vram.c
Normal file
@@ -0,0 +1,158 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
uint32_t rambase;
|
||||
uint32_t ramsize;
|
||||
uint8_t *ram;
|
||||
|
||||
#define HAVE_STRNDUP
|
||||
#ifndef HAVE_STRNDUP
|
||||
char* strndup(const char* s, size_t n) {
|
||||
char* ret = malloc(n + 1);
|
||||
if (ret == NULL) return(ret);
|
||||
ret[n] = '\0';
|
||||
return(memcpy(ret, s, n));
|
||||
}
|
||||
#endif
|
||||
|
||||
void help()
|
||||
{
|
||||
printf( "\nUsage: srec2vram <srect-file> <bram-base> <bram-size>\n\n" );
|
||||
printf( " <bram-base> \t \n" );
|
||||
printf( " <bram-size> \t \n\n" );
|
||||
};
|
||||
|
||||
|
||||
uint32_t parsehex(char *line, int start, int len)
|
||||
{
|
||||
char *str;
|
||||
uint32_t val;
|
||||
|
||||
str = strndup(line+start, len);
|
||||
sscanf(str, "%x", &val);
|
||||
free(str);
|
||||
|
||||
// fprintf( stderr, "parsehex: %x\n", val );
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void parseline(char *line, int start, int bytes, uint32_t addr)
|
||||
{
|
||||
int i;
|
||||
uint8_t val;
|
||||
|
||||
// fprintf( stderr, "parsline: [0x%08x, 0x%08x)\n", addr, addr+bytes );
|
||||
|
||||
for(i=0; i<bytes; i++) {
|
||||
if ( (rambase <= addr+i) && (addr+i < rambase+ramsize) ) {
|
||||
val = (uint8_t)parsehex(line, start+(i*2), 2);
|
||||
ram[addr-rambase+i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define LINESIZE 200
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int err;
|
||||
FILE *infile;
|
||||
|
||||
if (argc != 4) {
|
||||
help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
err = sscanf(argv[2], "%x", &rambase);
|
||||
if (err != 1) {
|
||||
printf( "ERROR: Could not parse <bram-base> (%s)\n", argv[2] );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
err = sscanf(argv[3], "%i", &ramsize);
|
||||
if (err != 1) {
|
||||
printf( "ERROR: Could not parse <bram-size> (%s)\n", argv[3] );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ram = malloc( ramsize );
|
||||
fprintf( stderr, "Extracting [%08x,%08x) (size=0x%x)\n",
|
||||
rambase, rambase+ramsize, ramsize );
|
||||
|
||||
// Open SREC file
|
||||
infile = fopen( argv[1], "r" );
|
||||
if (infile == NULL) {
|
||||
perror( "Could not open infile" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Read SREC file
|
||||
while( !feof(infile) ) {
|
||||
char errmsg[] = "Could not parse '%s'\n";
|
||||
char line[LINESIZE];
|
||||
uint32_t addr;
|
||||
int len;
|
||||
|
||||
|
||||
fgets(line, LINESIZE, infile);
|
||||
|
||||
// Is this a sane SREC line?
|
||||
if (strlen(line) < 4) {
|
||||
fprintf( stderr, errmsg, line );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] != 'S') {
|
||||
fprintf( stderr, errmsg, line );
|
||||
continue;
|
||||
}
|
||||
|
||||
// record length
|
||||
len = parsehex(line, 2, 2);
|
||||
|
||||
switch ( line[1] ) {
|
||||
case '0':
|
||||
continue;
|
||||
case '1': // data, 2-byte address
|
||||
addr = parsehex(line, 4, 4);
|
||||
parseline(line, 8, len-3, addr);
|
||||
break;
|
||||
case '2': // data, 3-byte address
|
||||
addr = parsehex(line, 4, 6);
|
||||
parseline(line, 10, len-4, addr);
|
||||
break;
|
||||
case '3': // data, 4-byte address
|
||||
addr = parsehex(line, 4, 8);
|
||||
parseline(line, 12, len-5, addr);
|
||||
break;
|
||||
case '7': // 4-byte start address
|
||||
break;
|
||||
case '8': // 3-byte start address
|
||||
break;
|
||||
case '9': // 2-byte start address
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, errmsg, line );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fclose( infile );
|
||||
|
||||
// Write output
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ramsize; i+=4) {
|
||||
printf( "%02x%02x%02x%02x\n", ram[i+0], ram[i+1], ram[i+2], ram[i+3] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
150
lm32/logic/sakc/tools/uploader/memtest
Executable file
150
lm32/logic/sakc/tools/uploader/memtest
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "serialport.so"
|
||||
require "optparse"
|
||||
|
||||
port_baud = 115200
|
||||
port_path = "/dev/ttyUSB0"
|
||||
terminal_mode = false
|
||||
verose = false
|
||||
|
||||
#############################################################################
|
||||
# Extend SerialPort class with low-leven binary communication
|
||||
class SerialPort
|
||||
BOOT_SIG = "**soc-lm32/bootloader**"
|
||||
|
||||
def put_uint32(i)
|
||||
putc( (i >> 24) & 0xff )
|
||||
putc( (i >> 16) & 0xff )
|
||||
putc( (i >> 8) & 0xff )
|
||||
putc( (i >> 0) & 0xff )
|
||||
end
|
||||
|
||||
def download(addr, size)
|
||||
a = Array.new(size)
|
||||
putc 'd'
|
||||
put_uint32 addr
|
||||
put_uint32 size
|
||||
size.times do |i|
|
||||
a[i] = getc
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
def upload(addr, data)
|
||||
putc 'u'
|
||||
put_uint32 addr
|
||||
put_uint32 data.length
|
||||
data.each do |c|
|
||||
putc c
|
||||
end
|
||||
end
|
||||
|
||||
def find_bootloader(max_tries = 32)
|
||||
old_timeout = read_timeout
|
||||
read_timeout = 500
|
||||
count = 0;
|
||||
begin
|
||||
count = count + 1
|
||||
if (count == max_tries) then
|
||||
raise "Bootloader (#{BOOT_SIG}) not not found"
|
||||
end
|
||||
putc '\r'
|
||||
l = gets
|
||||
end while l.nil? or not l.index( BOOT_SIG )
|
||||
read_timeout = old_timeout
|
||||
end
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
# Main
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: upload.rb [options] <file.srec>"
|
||||
|
||||
o.on( "-b", "--baud BAUDRATE", Integer,
|
||||
"Serial port baudrate (default: #{port_baud})" ) do |baud|
|
||||
port_baud = baud
|
||||
end
|
||||
|
||||
o.on( "-s", "--serial SERIALPORT",
|
||||
"Path to serial port (default: #{port_path})" ) do |port|
|
||||
port_path = port
|
||||
end
|
||||
|
||||
o.on( "-v", "--verbose",
|
||||
"Be verbose and show serial I/O" ) do
|
||||
verbose = true
|
||||
end
|
||||
|
||||
o.on_tail( "-h", "--help", "Display this help message" ) do
|
||||
puts o
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
||||
# Check arguments, open serial port and file
|
||||
begin
|
||||
opts.parse!(ARGV)
|
||||
|
||||
port = SerialPort.new(port_path, port_baud, 8, 1, SerialPort::NONE)
|
||||
raise "Could not open serial port." if not port;
|
||||
|
||||
rescue => e
|
||||
STDERR.puts "\nERROR: #{e.message}"
|
||||
STDERR.puts
|
||||
STDERR.puts opts
|
||||
STDERR.puts
|
||||
exit 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
begin
|
||||
BLOCK_SIZE = 0x800
|
||||
TEST_SIZE = 0x10000
|
||||
TEST_BASE = 0x40000000
|
||||
|
||||
STDOUT.sync = true
|
||||
|
||||
# Find bootloader
|
||||
print "Looking for soc-lm32 bootloader..."
|
||||
port.find_bootloader
|
||||
puts "found."
|
||||
|
||||
# generate random data
|
||||
data = Array.new( TEST_SIZE )
|
||||
data.map! do |e| e = rand(256) end
|
||||
|
||||
# upload random data
|
||||
print "Uploading 0x%X random bytes to 0x%X..." % [TEST_SIZE, TEST_BASE]
|
||||
(TEST_SIZE / BLOCK_SIZE).times do |i|
|
||||
print "."
|
||||
offset = i*BLOCK_SIZE
|
||||
block = data[ offset .. (offset+BLOCK_SIZE-1) ]
|
||||
port.upload( TEST_BASE + i*BLOCK_SIZE, block )
|
||||
end
|
||||
puts "done."
|
||||
|
||||
# download again
|
||||
print "Downloading again..."
|
||||
ddata = Array.new
|
||||
(TEST_SIZE / BLOCK_SIZE).times do |i|
|
||||
print "."
|
||||
ddata += port.download( TEST_BASE + i*BLOCK_SIZE, BLOCK_SIZE )
|
||||
end
|
||||
puts "done."
|
||||
|
||||
puts "Checking for memory errors..."
|
||||
TEST_SIZE.times do |i|
|
||||
if data[i] != ddata[i] then
|
||||
puts "0x%08x: %02x %02x" % [i, data[i], ddata[i] ]
|
||||
end
|
||||
end
|
||||
puts "done."
|
||||
ensure
|
||||
port.close unless port.nil?
|
||||
end
|
||||
|
||||
|
||||
|
||||
217
lm32/logic/sakc/tools/uploader/upload
Executable file
217
lm32/logic/sakc/tools/uploader/upload
Executable file
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "serialport.so"
|
||||
require "optparse"
|
||||
|
||||
port_baud = 115200
|
||||
port_path = "/dev/ttyUSB0"
|
||||
terminal_mode = false
|
||||
verbose = false
|
||||
check = false
|
||||
|
||||
#############################################################################
|
||||
# Extend SerialPort class with bootloader communication
|
||||
class SerialPort
|
||||
BOOT_SIG = "**soc-lm32/bootloader**"
|
||||
|
||||
def put_uint32(i)
|
||||
putc( (i >> 24) & 0xff )
|
||||
putc( (i >> 16) & 0xff )
|
||||
putc( (i >> 8) & 0xff )
|
||||
putc( (i >> 0) & 0xff )
|
||||
end
|
||||
|
||||
def download(addr, size)
|
||||
a = Array.new(size)
|
||||
putc 'd'
|
||||
put_uint32 addr
|
||||
put_uint32 size
|
||||
size.times do |i|
|
||||
a[i] = getc
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
def upload(addr, data)
|
||||
putc 'u'
|
||||
put_uint32 addr
|
||||
put_uint32 data.length
|
||||
data.each do |c|
|
||||
putc c
|
||||
end
|
||||
end
|
||||
|
||||
def find_bootloader(max_tries = 32)
|
||||
old_timeout = read_timeout
|
||||
read_timeout = 500
|
||||
count = 0;
|
||||
begin
|
||||
count = count + 1
|
||||
if (count == max_tries) then
|
||||
raise "Bootloader (#{BOOT_SIG}) not not found"
|
||||
end
|
||||
putc '\r'
|
||||
l = gets
|
||||
end while l.nil? or not l.index( BOOT_SIG )
|
||||
read_timeout = old_timeout
|
||||
end
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
# Main
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: upload [options] <file.srec>"
|
||||
|
||||
o.on( "-b", "--baud BAUDRATE", Integer,
|
||||
"Serial port baudrate (default: #{port_baud})" ) do |baud|
|
||||
port_baud = baud
|
||||
end
|
||||
|
||||
o.on( "-s", "--serial SERIALPORT",
|
||||
"Path to serial port (default: #{port_path})" ) do |port|
|
||||
port_path = port
|
||||
end
|
||||
|
||||
o.on( "-v", "--verbose",
|
||||
"Be verbose and show serial I/O" ) do
|
||||
verbose = true
|
||||
end
|
||||
|
||||
o.on( "-t", "--terminal",
|
||||
"Switch to terminal mode after upload" ) do
|
||||
terminal_mode = true
|
||||
end
|
||||
|
||||
o.on( "-c", "--check",
|
||||
"Check RAM after upload and verify everything is correct" ) do
|
||||
check = true
|
||||
end
|
||||
|
||||
o.on_tail( "-h", "--help", "Display this help message" ) do
|
||||
puts o
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
||||
# Check arguments, open serial port and file
|
||||
begin
|
||||
opts.parse!(ARGV)
|
||||
|
||||
raise "SREC file argument missing" if ARGV.length != 1;
|
||||
|
||||
file_path = ARGV[0]
|
||||
|
||||
uploadFile = File.open( file_path, "r" )
|
||||
raise "Could not SREC file." if not uploadFile;
|
||||
|
||||
fileSize = File.size( file_path )
|
||||
|
||||
port = SerialPort.new(port_path, port_baud, 8, 1, SerialPort::NONE)
|
||||
raise "Could not open serial port." if not port;
|
||||
|
||||
rescue => e
|
||||
STDERR.puts "\nERROR: #{e.message}"
|
||||
STDERR.puts
|
||||
STDERR.puts opts
|
||||
STDERR.puts
|
||||
exit 1
|
||||
end
|
||||
|
||||
begin
|
||||
STDOUT.sync = true
|
||||
|
||||
print "Looking for soc-lm32 bootloader..."
|
||||
port.find_bootloader
|
||||
puts "found."
|
||||
|
||||
data = Array.new(0x2000).map do |e| e = 0x23 end
|
||||
port.upload(0x40000000, data );
|
||||
|
||||
# ist_data = port.download(0x40000000, 0x2000)
|
||||
#p ist_data
|
||||
|
||||
# read SREC file
|
||||
startAddress = nil
|
||||
|
||||
print "Uploading SREC file..."
|
||||
uploadFile.each_line do |line|
|
||||
line.chomp!
|
||||
if line[0..1] == "S7" then
|
||||
startAddress = line[4..11].hex
|
||||
end
|
||||
if line[0..1] == "S3" then
|
||||
count = line[2..3].hex
|
||||
addr = line[4..11].hex
|
||||
dat = line[12..-3]
|
||||
cksum = line[-2..-1].hex
|
||||
|
||||
count = count - 5
|
||||
data = Array.new( count )
|
||||
count.times do |i|
|
||||
data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex
|
||||
end
|
||||
port.upload(addr, data)
|
||||
if verbose then
|
||||
print " [0x%08x] " % addr
|
||||
data.each do |e| print " %02x" % e; end
|
||||
puts
|
||||
else
|
||||
print "."
|
||||
end
|
||||
end
|
||||
end
|
||||
puts "done."
|
||||
|
||||
if check then
|
||||
print "verifieing RAM content..."
|
||||
uploadFile.seek(0)
|
||||
|
||||
uploadFile.each_line do |line|
|
||||
printf "."
|
||||
line.chomp!
|
||||
if line[0..1] == "S3" then
|
||||
count = line[2..3].hex
|
||||
addr = line[4..11].hex
|
||||
dat = line[12..-3]
|
||||
chsum = line[-2..-1].hex
|
||||
|
||||
count = count/2 - 1
|
||||
soll_data = Array.new( count )
|
||||
count.times do |i|
|
||||
soll_data[i] = ( dat[ (2*i) .. (2*i+1) ] ).hex
|
||||
end
|
||||
ist_data = port.download(addr, count)
|
||||
|
||||
count.times do |i|
|
||||
if soll_data[i] != ist_data[i] then
|
||||
puts "0x%08x: 0x%02x <-> 0x%02x" % [addr+i, soll_data[i], ist_data[i]]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
puts "done."
|
||||
end
|
||||
|
||||
if not startAddress.nil? then
|
||||
puts "Jumping to start address 0x%08x." % startAddress
|
||||
port.putc 'g'
|
||||
port.put_uint32 startAddress
|
||||
end
|
||||
|
||||
|
||||
if terminal_mode
|
||||
puts "------ entering terminal mode ------"
|
||||
while true do
|
||||
a = select( [port, STDIN], nil, nil );
|
||||
|
||||
STDOUT.putc(port.getc) if a[0].include?( port )
|
||||
port.putc(STDIN.getc) if a[0].include?( STDIN )
|
||||
end
|
||||
end
|
||||
|
||||
ensure
|
||||
uploadFile.close unless uploadFile.nil?
|
||||
port.close unless port.nil?
|
||||
end
|
||||
Reference in New Issue
Block a user