build/openocd: add stream method for JTAG UART
This commit is contained in:
parent
b356204f95
commit
bd6ec63be4
|
@ -1,9 +1,11 @@
|
||||||
# This file is Copyright (c) 2015 Robert Jordens <jordens@gmail.com>
|
# This file is Copyright (c) 2015-2017 Robert Jordens <jordens@gmail.com>
|
||||||
# This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
|
# This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
|
||||||
|
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# License: BSD
|
# License: BSD
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from litex.build.tools import write_to_file
|
||||||
from litex.build.generic_programmer import GenericProgrammer
|
from litex.build.generic_programmer import GenericProgrammer
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,3 +34,107 @@ class OpenOCD(GenericProgrammer):
|
||||||
"exit"
|
"exit"
|
||||||
])
|
])
|
||||||
subprocess.call(["openocd", "-f", self.config, "-c", script])
|
subprocess.call(["openocd", "-f", self.config, "-c", script])
|
||||||
|
|
||||||
|
|
||||||
|
def stream(self, port=20000):
|
||||||
|
"""
|
||||||
|
Create a Telnet server to stream data to/from the internal JTAG TAP of the FPGA
|
||||||
|
|
||||||
|
Wire format: 10 bits LSB first
|
||||||
|
Host to Target:
|
||||||
|
- TX ready : bit 0
|
||||||
|
- RX data: : bit 1 to 8
|
||||||
|
- RX valid : bit 9
|
||||||
|
|
||||||
|
Target to Host:
|
||||||
|
- RX ready : bit 0
|
||||||
|
- TX data : bit 1 to 8
|
||||||
|
- TX valid : bit 9
|
||||||
|
"""
|
||||||
|
cfg = """
|
||||||
|
proc jtagstream_poll {tap tx n} {
|
||||||
|
set m [string length $tx]
|
||||||
|
set n [expr ($m>$n)?$m:$n]
|
||||||
|
set txi [lrepeat $n {10 0x001}]
|
||||||
|
set i 0
|
||||||
|
foreach txj [split $tx ""] {
|
||||||
|
lset txi $i 1 [format 0x%4.4X [expr 0x201 | ([scan $txj %c] << 1)]]
|
||||||
|
incr i
|
||||||
|
}
|
||||||
|
set txi [concat {*}$txi]
|
||||||
|
set rxi [split [drscan $tap {*}$txi -endstate DRPAUSE] " "]
|
||||||
|
#echo $txi:$rxi
|
||||||
|
set rx ""
|
||||||
|
set writable 1
|
||||||
|
foreach {rxj} $rxi {
|
||||||
|
set readable [expr 0x$rxj & 0x200]
|
||||||
|
set writable [expr 0x$rxj & $writable]
|
||||||
|
if {$readable} {
|
||||||
|
append rx [format %c [expr (0x$rxj >> 1) & 0xff]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [list $rx $readable $writable]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc jtagstream_drain {tap tx chunk_rx max_rx} {
|
||||||
|
lassign [jtagstream_poll $tap $tx $chunk_rx] rx readable writable
|
||||||
|
while {[expr $writable && ($readable > 0) && ([string length $rx] < $max_rx)]} {
|
||||||
|
lassign [jtagstream_poll $tap "" $chunk_rx] rxi readable writable
|
||||||
|
append rx $rxi
|
||||||
|
}
|
||||||
|
if {!$writable} {
|
||||||
|
echo "write overflow"
|
||||||
|
}
|
||||||
|
return $rx
|
||||||
|
}
|
||||||
|
|
||||||
|
proc jtagstream_rxtx {tap client is_poll} {
|
||||||
|
if {![$client eof]} {
|
||||||
|
if {!$is_poll} {
|
||||||
|
set tx [$client gets]
|
||||||
|
} else {
|
||||||
|
set tx ""
|
||||||
|
}
|
||||||
|
set rx [jtagstream_drain $tap $tx 64 4096]
|
||||||
|
if {[string length $rx]} {
|
||||||
|
$client puts -nonewline $rx
|
||||||
|
}
|
||||||
|
if {$is_poll} {
|
||||||
|
after 1 [list jtagstream_rxtx $tap $client 1]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$client readable {}
|
||||||
|
$client onexception {}
|
||||||
|
$client close
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc jtagstream_client {tap sock} {
|
||||||
|
set client [$sock accept]
|
||||||
|
fconfigure $client -buffering none
|
||||||
|
$client readable [list jtagstream_rxtx $tap $client 0]
|
||||||
|
$client onexception [list $client close]
|
||||||
|
after 1 [list jtagstream_rxtx $tap $client 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc jtagstream_exit {sock} {
|
||||||
|
stdin readable {}
|
||||||
|
$sock readable {}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc jtagstream_serve {tap port} {
|
||||||
|
set sock [socket stream.server $port]
|
||||||
|
$sock readable [list jtagstream_client $tap $sock]
|
||||||
|
stdin readable [list jtagstream_exit $sock]
|
||||||
|
vwait forever
|
||||||
|
$sock close
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
write_to_file("stream.cfg", cfg)
|
||||||
|
script = "; ".join([
|
||||||
|
"init",
|
||||||
|
"irscan $_CHIPNAME.tap $_USER1",
|
||||||
|
"jtagstream_serve $_CHIPNAME.tap {:d}".format(port),
|
||||||
|
"exit",
|
||||||
|
])
|
||||||
|
subprocess.call(["openocd", "-f", self.config, "-f", "stream.cfg", "-c", script])
|
||||||
|
|
Loading…
Reference in New Issue