Merge commit 'd594b42976e3b9640b64ef1cb2da3f74067930b8' into sam-update
# Conflicts: # README.md # src/platforms/common/cdcacm.c # src/target/adiv5_swdp.c
This commit is contained in:
commit
e174c5b503
2
HACKING
2
HACKING
@ -1 +1 @@
|
||||
See https://github.com/blacksphere/blackmagic/wiki/Hacking
|
||||
See https://github.com/blackmagic-debug/blackmagic/wiki/Hacking
|
||||
|
@ -28,7 +28,7 @@ class stm32_boot:
|
||||
|
||||
# Turn on target device in SystemMemory boot mode
|
||||
self.serial.setDTR(1)
|
||||
sleep(0.1);
|
||||
sleep(0.1)
|
||||
|
||||
self._sync()
|
||||
|
||||
@ -99,7 +99,6 @@ class stm32_boot:
|
||||
self._send(chr(len(data)-1) + data)
|
||||
self._checkack()
|
||||
|
||||
|
||||
def write_protect(self, sectors):
|
||||
# Send WP cmd
|
||||
self._sendcmd("\x63")
|
||||
@ -134,11 +133,11 @@ if __name__ == "__main__":
|
||||
from getopt import getopt
|
||||
|
||||
if platform == "linux2":
|
||||
print "\x1b\x5b\x48\x1b\x5b\x32\x4a" # clear terminal screen
|
||||
print "STM32 SystemMemory Production Programmer -- version 1.1"
|
||||
print "Copyright (C) 2011 Black Sphere Technologies"
|
||||
print "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>"
|
||||
print
|
||||
print("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen
|
||||
print("STM32 SystemMemory Production Programmer -- version 1.1")
|
||||
print("Copyright (C) 2011 Black Sphere Technologies")
|
||||
print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
|
||||
print()
|
||||
|
||||
dev = "COM1" if platform == "win32" else "/dev/ttyUSB0"
|
||||
baud = 115200
|
||||
@ -152,38 +151,38 @@ if __name__ == "__main__":
|
||||
|
||||
progfile = args[0]
|
||||
except:
|
||||
print "Usage %s [-d <dev>] [-b <baudrate>] [-a <address>] <filename>" % argv[0]
|
||||
print "\t-d : Use target on interface <dev> (default: %s)" % dev
|
||||
print "\t-b : Set device baudrate (default: %d)" % baud
|
||||
print "\t-a : Set programming address (default: 0x%X)" % addr
|
||||
print
|
||||
print("Usage %s [-d <dev>] [-b <baudrate>] [-a <address>] <filename>" % argv[0])
|
||||
print("\t-d : Use target on interface <dev> (default: %s)" % dev)
|
||||
print("\t-b : Set device baudrate (default: %d)" % baud)
|
||||
print("\t-a : Set programming address (default: 0x%X)" % addr)
|
||||
print()
|
||||
exit(-1)
|
||||
|
||||
prog = open(progfile, "rb").read()
|
||||
boot = stm32_boot(dev, baud)
|
||||
|
||||
cmds = boot.get()
|
||||
print "Target bootloader version: %d.%d\n" % (ord(cmds[0]) >> 4, ord(cmds[0]) % 0xf)
|
||||
print("Target bootloader version: %d.%d\n" % (ord(cmds[0]) >> 4, ord(cmds[0]) % 0xf))
|
||||
|
||||
print "Removing device protection..."
|
||||
print("Removing device protection...")
|
||||
boot.read_unprotect()
|
||||
boot.write_unprotect()
|
||||
print "Erasing target device..."
|
||||
print("Erasing target device...")
|
||||
boot.eraseall()
|
||||
addr = 0x8000000
|
||||
while prog:
|
||||
print ("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255))),
|
||||
stdout.flush();
|
||||
print("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255)), end=' ')
|
||||
stdout.flush()
|
||||
boot.write(addr, prog[:256])
|
||||
addr += 256
|
||||
prog = prog[256:]
|
||||
|
||||
print
|
||||
print "Enabling device protection..."
|
||||
print("Enabling device protection...")
|
||||
boot.write_protect(range(0,2))
|
||||
#boot.read_protect()
|
||||
|
||||
print "All operations completed."
|
||||
print("All operations completed.")
|
||||
print
|
||||
|
||||
|
||||
|
215
scripts/gdb.py
215
scripts/gdb.py
@ -24,18 +24,12 @@ import struct
|
||||
import time
|
||||
|
||||
def hexify(s):
|
||||
"""Convert a binary string into hex representation"""
|
||||
ret = ''
|
||||
for c in s:
|
||||
ret += "%02X" % ord(c)
|
||||
return ret
|
||||
"""Convert a bytes object into hex bytes representation"""
|
||||
return s.hex().encode()
|
||||
|
||||
def unhexify(s):
|
||||
"""Convert a hex string into binary representation"""
|
||||
ret = ''
|
||||
for i in range(0, len(s), 2):
|
||||
ret += chr(int(s[i:i+2], 16))
|
||||
return ret
|
||||
"""Convert a hex-encoded bytes into bytes object"""
|
||||
return bytes.fromhex(s.decode())
|
||||
|
||||
class FakeSocket:
|
||||
"""Emulate socket functions send and recv on a file object"""
|
||||
@ -55,145 +49,183 @@ class Target:
|
||||
else:
|
||||
self.sock = FakeSocket(sock)
|
||||
|
||||
self.PacketSize=0x100 # default
|
||||
|
||||
def getpacket(self):
|
||||
"""Return the first correctly received packet from GDB target"""
|
||||
while True:
|
||||
while self.sock.recv(1) != '$': pass
|
||||
while self.sock.recv(1) != b'$':
|
||||
pass
|
||||
|
||||
csum = 0
|
||||
packet = ''
|
||||
packet = [] # list-of-small-int
|
||||
|
||||
while True:
|
||||
c = self.sock.recv(1)
|
||||
if c == '#': break
|
||||
c, = self.sock.recv(1)
|
||||
if c == ord('#'):
|
||||
break
|
||||
|
||||
if c == '$':
|
||||
packet = ''
|
||||
if c == ord('$'):
|
||||
packet = []
|
||||
csum = 0
|
||||
continue
|
||||
|
||||
if c == '}':
|
||||
c = self.sock.recv(1)
|
||||
csum += ord(c) + ord('}')
|
||||
packet += chr(ord(c) ^ 0x20)
|
||||
if c == ord('}'):
|
||||
c, = self.sock.recv(1)
|
||||
csum += c + ord('}')
|
||||
packet.append(c ^ 0x20)
|
||||
continue
|
||||
|
||||
packet += c
|
||||
csum += ord(c)
|
||||
packet.append(c)
|
||||
csum += c
|
||||
|
||||
if (csum & 0xFF) == int(self.sock.recv(2),16): break
|
||||
if (csum & 0xFF) == int(self.sock.recv(2),16):
|
||||
break
|
||||
|
||||
self.sock.send('-')
|
||||
|
||||
self.sock.send('+')
|
||||
return packet
|
||||
self.sock.send(b'-')
|
||||
|
||||
self.sock.send(b'+')
|
||||
return bytes(packet)
|
||||
|
||||
def putpacket(self, packet):
|
||||
"""Send packet to GDB target and wait for acknowledge"""
|
||||
"""Send packet to GDB target and wait for acknowledge
|
||||
packet is bytes or string"""
|
||||
|
||||
if type(packet) == str:
|
||||
packet = packet.encode()
|
||||
|
||||
while True:
|
||||
self.sock.send('$')
|
||||
csum = 0
|
||||
out = []
|
||||
|
||||
for c in packet:
|
||||
if (c == '$') or (c == '#') or (c == '}'):
|
||||
self.sock.send('}')
|
||||
self.sock.send(chr(ord(c) ^ 0x20))
|
||||
csum += (ord(c) ^ 0x20) + ord('}')
|
||||
if (c in b'$#}'):
|
||||
out.append(ord('}'))
|
||||
out.append(c ^ 0x20)
|
||||
else:
|
||||
self.sock.send(c)
|
||||
csum += ord(c)
|
||||
self.sock.send('#')
|
||||
self.sock.send("%02X" % (csum & 0xFF))
|
||||
if self.sock.recv(1) == '+': break
|
||||
out.append(c)
|
||||
|
||||
csum = sum(out)
|
||||
outb = b'$'+bytes(out)+b'#%02X' % (csum & 0xff)
|
||||
|
||||
self.sock.send(outb)
|
||||
if self.sock.recv(1) == b'+':
|
||||
break
|
||||
|
||||
def monitor(self, cmd):
|
||||
"""Send gdb "monitor" command to target"""
|
||||
if type(cmd) == str:
|
||||
cmd = cmd.encode()
|
||||
|
||||
ret = []
|
||||
self.putpacket("qRcmd," + hexify(cmd))
|
||||
self.putpacket(b"qRcmd," + hexify(cmd))
|
||||
|
||||
while True:
|
||||
s = self.getpacket()
|
||||
if s == '': return None
|
||||
if s == 'OK': return ret
|
||||
if s.startswith('O'): ret.append(unhexify(s[1:]))
|
||||
|
||||
if s == b'':
|
||||
return None
|
||||
if s == b'OK':
|
||||
return ret
|
||||
if s.startswith(b'O'):
|
||||
ret.append(unhexify(s[1:]))
|
||||
else:
|
||||
raise Exception('Invalid GDB stub response')
|
||||
raise Exception('Invalid GDB stub response %r'%s.decode())
|
||||
|
||||
def attach(self, pid):
|
||||
"""Attach to target process (gdb "attach" command)"""
|
||||
self.putpacket("vAttach;%08X" % pid)
|
||||
self.putpacket(b"vAttach;%08X" % pid)
|
||||
reply = self.getpacket()
|
||||
if (len(reply) == 0) or (reply[0] == 'E'):
|
||||
if (reply == b'') or (reply[:1] == b'E'):
|
||||
raise Exception('Failed to attach to remote pid %d' % pid)
|
||||
|
||||
def detach(self):
|
||||
"""Detach from target process (gdb "detach" command)"""
|
||||
self.putpacket("D")
|
||||
if self.getpacket() != 'OK':
|
||||
self.putpacket(b"D")
|
||||
if self.getpacket() != b'OK':
|
||||
raise Exception("Failed to detach from remote process")
|
||||
|
||||
def reset(self):
|
||||
"""Reset the target system"""
|
||||
self.putpacket("r")
|
||||
self.putpacket(b"r")
|
||||
|
||||
def read_mem(self, addr, length):
|
||||
"""Read length bytes from target at address addr"""
|
||||
self.putpacket("m%08X,%08X" % (addr, length))
|
||||
ret = b''
|
||||
while length:
|
||||
# print "Read"
|
||||
packlen = min(length,self.PacketSize//2)
|
||||
self.putpacket(b"m%08X,%08X" % (addr, packlen))
|
||||
reply = self.getpacket()
|
||||
if (len(reply) == 0) or (reply[0] == 'E'):
|
||||
if (reply == b'') or (reply[:1] == b'E'):
|
||||
raise Exception('Error reading memory at 0x%08X' % addr)
|
||||
try:
|
||||
data = unhexify(reply)
|
||||
except Excpetion:
|
||||
except Exception:
|
||||
raise Exception('Invalid response to memory read packet: %r' % reply)
|
||||
return data
|
||||
ret += data
|
||||
length -= packlen
|
||||
addr += packlen
|
||||
|
||||
return ret
|
||||
|
||||
def write_mem(self, addr, data):
|
||||
"""Write data to target at address addr"""
|
||||
self.putpacket("X%08X,%08X:%s" % (addr, len(data), data))
|
||||
if self.getpacket() != 'OK':
|
||||
data = bytes(data)
|
||||
|
||||
while data:
|
||||
d = data[:self.PacketSize-44]
|
||||
data = data[len(d):]
|
||||
#print("Writing %d bytes at 0x%X" % (len(d), addr))
|
||||
pack = b"X%08X,%08X:%s" % (addr, len(d), d)
|
||||
self.putpacket(pack)
|
||||
|
||||
if self.getpacket() != b'OK':
|
||||
raise Exception('Error writing to memory at 0x%08X' % addr)
|
||||
addr += len(d)
|
||||
|
||||
def read_regs(self):
|
||||
"""Read target core registers"""
|
||||
self.putpacket("g")
|
||||
self.putpacket(b"g")
|
||||
reply = self.getpacket()
|
||||
if (len(reply) == 0) or (reply[0] == 'E'):
|
||||
if (reply == b'') or (reply[:1] == b'E'):
|
||||
raise Exception('Error reading memory at 0x%08X' % addr)
|
||||
try:
|
||||
data = unhexify(reply)
|
||||
except Excpetion:
|
||||
except Exception:
|
||||
raise Exception('Invalid response to memory read packet: %r' % reply)
|
||||
return struct.unpack("=20L", data)
|
||||
ret = array.array('I',data)
|
||||
return ret
|
||||
|
||||
def write_regs(self, *regs):
|
||||
"""Write target core registers"""
|
||||
data = struct.pack("=%dL" % len(regs), *regs)
|
||||
self.putpacket("G" + hexify(data))
|
||||
if self.getpacket() != 'OK':
|
||||
self.putpacket(b"G" + hexify(data))
|
||||
if self.getpacket() != b'OK':
|
||||
raise Exception('Error writing to target core registers')
|
||||
|
||||
def memmap_read(self):
|
||||
"""Read the XML memory map from target"""
|
||||
offset = 0
|
||||
ret = ''
|
||||
ret = b''
|
||||
while True:
|
||||
self.putpacket("qXfer:memory-map:read::%08X,%08X" % (offset, 512))
|
||||
self.putpacket(b"qXfer:memory-map:read::%08X,%08X" % (offset, 512))
|
||||
reply = self.getpacket()
|
||||
if (reply[0] == 'm') or (reply[0] == 'l'):
|
||||
if (reply[0] in b'ml'):
|
||||
offset += len(reply) - 1
|
||||
ret += reply[1:]
|
||||
else:
|
||||
raise Exception("Invalid GDB stub response")
|
||||
raise Exception('Invalid GDB stub response %r'%reply)
|
||||
|
||||
if reply[0] == 'l': return ret
|
||||
if reply[:1] == b'l':
|
||||
return ret
|
||||
|
||||
def resume(self):
|
||||
"""Resume target execution"""
|
||||
self.putpacket("c")
|
||||
self.putpacket(b'c')
|
||||
|
||||
def interrupt(self):
|
||||
"""Interrupt target execution"""
|
||||
self.sock.send("\x03")
|
||||
self.sock.send(b'\x03')
|
||||
|
||||
def run_stub(self, stub, address, *args):
|
||||
"""Execute a binary stub at address, passing args in core registers."""
|
||||
@ -205,11 +237,19 @@ class Target:
|
||||
regs[15] = address
|
||||
self.write_regs(*regs)
|
||||
self.resume()
|
||||
reply = self.getpacket()
|
||||
reply = None
|
||||
while not reply:
|
||||
reply = self.getpacket()
|
||||
if not reply.startswith("T05"):
|
||||
raise Exception("Invalid stop response: %r" % reply)
|
||||
if not reply.startswith(b"T05"):
|
||||
message = "Invalid stop response: %r" % reply
|
||||
try:
|
||||
message += {'T02':' (SIGINT)',
|
||||
'T05':' (SIGTRAP)',
|
||||
'T0B':' (SIGSEGV)',
|
||||
'T1D':' (SIGLOST)'}[reply]
|
||||
except KeyError:
|
||||
pass
|
||||
raise Exception(message)
|
||||
|
||||
class FlashMemory:
|
||||
def __init__(self, target, offset, length, blocksize):
|
||||
@ -217,26 +257,29 @@ class Target:
|
||||
self.offset = offset
|
||||
self.length = length
|
||||
self.blocksize = blocksize
|
||||
self.blocks = list(None for i in range(length / blocksize))
|
||||
self.blocks = list(None for i in range(length // blocksize))
|
||||
|
||||
def prog(self, offset, data):
|
||||
assert type(data)==bytes
|
||||
|
||||
assert ((offset >= self.offset) and
|
||||
(offset + len(data) <= self.offset + self.length))
|
||||
|
||||
while data:
|
||||
index = (offset - self.offset) / self.blocksize
|
||||
index = (offset - self.offset) // self.blocksize
|
||||
bloffset = (offset - self.offset) % self.blocksize
|
||||
bldata = data[:self.blocksize-bloffset]
|
||||
data = data[len(bldata):]; offset += len(bldata)
|
||||
if self.blocks[index] is None: # Initialize a clear block
|
||||
self.blocks[index] = "".join(chr(0xff) for i in range(self.blocksize))
|
||||
self.blocks[index] = bytes(0xff for i in range(self.blocksize))
|
||||
self.blocks[index] = (self.blocks[index][:bloffset] + bldata +
|
||||
self.blocks[index][bloffset+len(bldata):])
|
||||
|
||||
def commit(self, progress_cb=None):
|
||||
totalblocks = 0
|
||||
for b in self.blocks:
|
||||
if b is not None: totalblocks += 1
|
||||
if b is not None:
|
||||
totalblocks += 1
|
||||
|
||||
block = 0
|
||||
for i in range(len(self.blocks)):
|
||||
@ -247,27 +290,28 @@ class Target:
|
||||
# Erase the block
|
||||
data = self.blocks[i]
|
||||
addr = self.offset + self.blocksize * i
|
||||
if data is None: continue
|
||||
if data is None:
|
||||
continue
|
||||
#print "Erasing flash at 0x%X" % (self.offset + self.blocksize*i)
|
||||
self.target.putpacket("vFlashErase:%08X,%08X" %
|
||||
self.target.putpacket(b"vFlashErase:%08X,%08X" %
|
||||
(self.offset + self.blocksize*i, self.blocksize))
|
||||
if self.target.getpacket() != 'OK':
|
||||
if self.target.getpacket() != b'OK':
|
||||
raise Exception("Failed to erase flash")
|
||||
|
||||
while data:
|
||||
d = data[0:980]
|
||||
data = data[len(d):]
|
||||
#print "Writing %d bytes at 0x%X" % (len(d), addr)
|
||||
self.target.putpacket("vFlashWrite:%08X:%s" % (addr, d))
|
||||
self.target.putpacket(b"vFlashWrite:%08X:%s" % (addr, d))
|
||||
addr += len(d)
|
||||
if self.target.getpacket() != 'OK':
|
||||
if self.target.getpacket() != b'OK':
|
||||
raise Exception("Failed to write flash")
|
||||
|
||||
self.target.putpacket("vFlashDone")
|
||||
if self.target.getpacket() != 'OK':
|
||||
self.target.putpacket(b"vFlashDone")
|
||||
if self.target.getpacket() != b'OK':
|
||||
raise Exception("Failed to commit")
|
||||
|
||||
self.blocks = list(None for i in range(self.length / self.blocksize))
|
||||
self.blocks = list(None for i in range(self.length // self.blocksize))
|
||||
|
||||
|
||||
def flash_probe(self):
|
||||
@ -275,7 +319,8 @@ class Target:
|
||||
xmldom = parseString(self.memmap_read())
|
||||
|
||||
for memrange in xmldom.getElementsByTagName("memory"):
|
||||
if memrange.getAttribute("type") != "flash": continue
|
||||
if memrange.getAttribute("type") != "flash":
|
||||
continue
|
||||
offset = eval(memrange.getAttribute("start"))
|
||||
length = eval(memrange.getAttribute("length"))
|
||||
for property in memrange.getElementsByTagName("property"):
|
||||
@ -297,5 +342,3 @@ class Target:
|
||||
def flash_commit(self, progress_cb=None):
|
||||
for m in self.mem:
|
||||
m.commit(progress_cb)
|
||||
|
||||
|
||||
|
@ -5,36 +5,32 @@ pasting into blackmagic's nrf51.c
|
||||
|
||||
"""
|
||||
|
||||
import subprocess,re
|
||||
import subprocess
|
||||
import re
|
||||
import io
|
||||
|
||||
cmd = 'git archive --remote=git://git.code.sf.net/p/openocd/code HEAD src/flash/nor/nrf51.c | tar -xO'
|
||||
cmd = 'git archive --remote=git://git.code.sf.net/p/openocd/code HEAD src/flash/nor/nrf5.c | tar -xO'
|
||||
|
||||
class Spec():
|
||||
def __repr__(self):
|
||||
return "0x%04X: /* %s %s %s */"%(self.hwid,self.comment, self.variant,self.build_code)
|
||||
|
||||
fd = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE).stdout
|
||||
proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
|
||||
|
||||
specdict = {}
|
||||
specs = []
|
||||
spec = Spec()
|
||||
for line in fd.read().split('\n'):
|
||||
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
|
||||
m = re.search('/\*(.*)\*/',line)
|
||||
if m:
|
||||
lastcomment=m.group(1)
|
||||
|
||||
m=re.search('.hwid.*=\s*(0x[0-9A-F]*),',line)
|
||||
m = re.search('NRF51_DEVICE_DEF\((0x[0-9A-F]*),\s*"(.*)",\s*"(.*)",\s*"(.*)",\s*([0-9]*)\s*\),', line)
|
||||
if m:
|
||||
spec.hwid = int(m.group(1), base=0)
|
||||
m=re.search('.variant.*=\s*"(.*)",',line)
|
||||
if m:
|
||||
spec.variant=m.group(1)
|
||||
m=re.search('.build_code.*=\s*"(.*)",',line)
|
||||
if m:
|
||||
spec.build_code=m.group(1)
|
||||
m=re.search('.flash_size_kb.*=\s*([0-9]*),',line)
|
||||
if m:
|
||||
spec.flash_size_kb=int(m.group(1),base=0)
|
||||
spec.variant = m.group(3)
|
||||
spec.build_code = m.group(4)
|
||||
spec.flash_size_kb = int(m.group(5), base=0)
|
||||
ram, flash = {'AA':(16,256),
|
||||
'AB':(16,128),
|
||||
'AC':(32,256)}[spec.variant[-2:]]
|
||||
@ -47,14 +43,14 @@ for line in fd.read().split('\n'):
|
||||
specs.append(spec)
|
||||
spec=Spec()
|
||||
|
||||
for (ram,flash),specs in specdict.iteritems():
|
||||
for (ram,flash),specs in specdict.items():
|
||||
specs.sort(key=lambda x:x.hwid)
|
||||
for spec in specs:
|
||||
print "\tcase",spec
|
||||
print '\t\tt->driver = "Nordic nRF51";'
|
||||
print '\t\ttarget_add_ram(t, 0x20000000, 0x%X);'%(1024*ram)
|
||||
print '\t\tnrf51_add_flash(t, 0x00000000, 0x%X, NRF51_PAGE_SIZE);'%(1024*flash)
|
||||
print '\t\tnrf51_add_flash(t, NRF51_UICR, 0x100, 0x100);'
|
||||
print '\t\ttarget_add_commands(t, nrf51_cmd_list, "nRF51");'
|
||||
print '\t\treturn true;'
|
||||
print("\tcase",spec)
|
||||
print('\t\tt->driver = "Nordic nRF51";')
|
||||
print('\t\ttarget_add_ram(t, 0x20000000, 0x%X);'%(1024*ram))
|
||||
print('\t\tnrf51_add_flash(t, 0x00000000, 0x%X, NRF51_PAGE_SIZE);'%(1024*flash))
|
||||
print('\t\tnrf51_add_flash(t, NRF51_UICR, 0x100, 0x100);')
|
||||
print('\t\ttarget_add_commands(t, nrf51_cmd_list, "nRF51");')
|
||||
print('\t\treturn true;')
|
||||
|
||||
|
@ -31,15 +31,16 @@ def flash_write_hex(target, hexfile, progress_cb=None):
|
||||
f = open(hexfile)
|
||||
addrhi = 0
|
||||
for line in f:
|
||||
if line[0] != ':': raise Exception("Error in hex file")
|
||||
if line[0] != ':':
|
||||
raise Exception("Error in hex file")
|
||||
reclen = int(line[1:3], 16)
|
||||
addrlo = int(line[3:7], 16)
|
||||
rectype = int(line[7:9], 16);
|
||||
if sum(ord(x) for x in gdb.unhexify(line[1:11+reclen*2])) & 0xff != 0:
|
||||
if sum(x for x in bytes.fromhex(line[1:11+reclen*2])) & 0xff != 0:
|
||||
raise Exception("Checksum error in hex file")
|
||||
if rectype == 0: # Data record
|
||||
addr = (addrhi << 16) + addrlo
|
||||
data = gdb.unhexify(line[9:9+reclen*2])
|
||||
data = bytes.fromhex(line[9:9+reclen*2])
|
||||
target.flash_write_prepare(addr, data)
|
||||
pass
|
||||
elif rectype == 4: # High address record
|
||||
@ -55,7 +56,7 @@ def flash_write_hex(target, hexfile, progress_cb=None):
|
||||
try:
|
||||
target.flash_commit(progress_cb)
|
||||
except:
|
||||
print "Flash write failed! Is device protected?\n"
|
||||
print("Flash write failed! Is device protected?\n")
|
||||
exit(-1)
|
||||
|
||||
|
||||
@ -67,8 +68,8 @@ if __name__ == "__main__":
|
||||
if platform == "linux2":
|
||||
print ("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen
|
||||
print("Black Magic Probe -- Target Production Programming Tool -- version 1.0")
|
||||
print "Copyright (C) 2011 Black Sphere Technologies"
|
||||
print "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>"
|
||||
print("Copyright (C) 2011 Black Sphere Technologies")
|
||||
print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
|
||||
print("")
|
||||
|
||||
dev = "COM1" if platform == "win32" else "/dev/ttyACM0"
|
||||
@ -80,13 +81,20 @@ if __name__ == "__main__":
|
||||
try:
|
||||
opts, args = getopt(argv[1:], "sd:b:t:rR")
|
||||
for opt in opts:
|
||||
if opt[0] == "-s": scan = "swdp_scan"
|
||||
elif opt[0] == "-b": baud = int(opt[1])
|
||||
elif opt[0] == "-d": dev = opt[1]
|
||||
elif opt[0] == "-t": targetno = int(opt[1])
|
||||
elif opt[0] == "-r": unprot = True
|
||||
elif opt[0] == "-R": prot = True
|
||||
else: raise Exception()
|
||||
if opt[0] == "-s":
|
||||
scan = "swdp_scan"
|
||||
elif opt[0] == "-b":
|
||||
baud = int(opt[1])
|
||||
elif opt[0] == "-d":
|
||||
dev = opt[1]
|
||||
elif opt[0] == "-t":
|
||||
targetno = int(opt[1])
|
||||
elif opt[0] == "-r":
|
||||
unprot = True
|
||||
elif opt[0] == "-R":
|
||||
prot = True
|
||||
else:
|
||||
raise Exception()
|
||||
|
||||
hexfile = args[0]
|
||||
except:
|
||||
@ -101,39 +109,44 @@ if __name__ == "__main__":
|
||||
exit(-1)
|
||||
|
||||
try:
|
||||
s = Serial(dev, baud, timeout=3)
|
||||
s.setDTR(1)
|
||||
while s.read(1024):
|
||||
pass
|
||||
s = Serial(dev) #, baud, timeout=0.1)
|
||||
#s.setDTR(1)
|
||||
#s.flushInput()
|
||||
|
||||
#while s.read(1024):
|
||||
# pass
|
||||
|
||||
target = gdb.Target(s)
|
||||
|
||||
except SerialException, e:
|
||||
except SerialException as e:
|
||||
print("FATAL: Failed to open serial device!\n%s\n" % e[0])
|
||||
exit(-1)
|
||||
|
||||
try:
|
||||
r = target.monitor("version")
|
||||
for s in r: print s,
|
||||
except SerialException, e:
|
||||
for s in r:
|
||||
print(s.decode(), end=' ')
|
||||
except SerialException as e:
|
||||
print("FATAL: Serial communication failure!\n%s\n" % e[0])
|
||||
exit(-1)
|
||||
except: pass
|
||||
#except: pass
|
||||
|
||||
print "Target device scan:"
|
||||
print("Target device scan:")
|
||||
targetlist = None
|
||||
r = target.monitor(scan)
|
||||
for s in r:
|
||||
print s,
|
||||
print
|
||||
print(s.decode(), end=' ')
|
||||
print()
|
||||
|
||||
r = target.monitor("targets")
|
||||
for s in r:
|
||||
if s.startswith("No. Att Driver"): targetlist = []
|
||||
if s.startswith(b"No. Att Driver"):
|
||||
targetlist = []
|
||||
try:
|
||||
if type(targetlist) is list:
|
||||
targetlist.append(int(s[:2]))
|
||||
except: pass
|
||||
except:
|
||||
pass
|
||||
|
||||
#if not targetlist:
|
||||
# print("FATAL: No usable targets found!\n")
|
||||
@ -161,7 +174,7 @@ if __name__ == "__main__":
|
||||
print("FLASH memory -- Offset: 0x%X BlockSize:0x%X\n" % (m.offset, m.blocksize))
|
||||
|
||||
def progress(percent):
|
||||
print ("Progress: %d%%\r" % percent),
|
||||
print("Progress: %d%%\r" % percent, end=' ')
|
||||
stdout.flush()
|
||||
|
||||
print("Programming target")
|
||||
@ -179,4 +192,3 @@ if __name__ == "__main__":
|
||||
target.detach()
|
||||
|
||||
print("\nAll operations complete!\n")
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import print_function
|
||||
from time import sleep
|
||||
import struct
|
||||
import os
|
||||
@ -72,7 +71,7 @@ def stm32_read(dev):
|
||||
return data
|
||||
|
||||
def stm32_manifest(dev):
|
||||
dev.download(0, "")
|
||||
dev.download(0, b"")
|
||||
while True:
|
||||
try:
|
||||
status = dev.get_status()
|
||||
@ -236,7 +235,7 @@ if __name__ == "__main__":
|
||||
bin = file.read()
|
||||
len = len(bin)
|
||||
addr = start
|
||||
print("-")
|
||||
print("\n-")
|
||||
while bin:
|
||||
try:
|
||||
stm32_set_address(dfudev, addr)
|
||||
@ -251,7 +250,7 @@ if __name__ == "__main__":
|
||||
else :
|
||||
size = len
|
||||
if bin[:size] != bytearray(data[:size]) :
|
||||
print ("\nMitmatch in block at 0x%08X" % addr)
|
||||
print ("\nMismatch in block at 0x%08X" % addr)
|
||||
break;
|
||||
bin = bin[1024:]
|
||||
addr += 1024
|
||||
|
@ -106,9 +106,11 @@ int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
|
||||
* 22 s @ 4k and 21 s @ 64k
|
||||
*/
|
||||
uint8_t bytes[0x1000];
|
||||
uint32_t start_time = platform_time_ms();
|
||||
#else
|
||||
uint8_t bytes[128];
|
||||
#endif
|
||||
#if defined(ENABLE_DEBUG)
|
||||
uint32_t start_time = platform_time_ms();
|
||||
#endif
|
||||
uint32_t last_time = platform_time_ms();
|
||||
while (len) {
|
||||
|
@ -24,6 +24,18 @@
|
||||
* field firmware upgrade.
|
||||
*
|
||||
* The device's unique id is used as the USB serial number string.
|
||||
*
|
||||
* Endpoint Usage
|
||||
*
|
||||
* 0 Control Endpoint
|
||||
* IN 1 GDB CDC DATA
|
||||
* OUT 1 GDB CDC DATA
|
||||
* IN 2 GDB CDC CTR
|
||||
* IN 3 UART CDC DATA
|
||||
* OUT 3 UART CDC DATA
|
||||
* OUT 4 UART CDC CTRL
|
||||
* In 5 Trace Capture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "general.h"
|
||||
@ -42,7 +54,15 @@
|
||||
#include <libopencm3/cm3/scb.h>
|
||||
#include <libopencm3/usb/dfu.h>
|
||||
|
||||
#define GDB_IF_NO 0
|
||||
#define UART_IF_NO 2
|
||||
#define DFU_IF_NO 4
|
||||
#if defined(PLATFORM_HAS_TRACESWO)
|
||||
# define TRACE_IF_NO 5
|
||||
# define TOTAL_INTERFACES 6
|
||||
#else
|
||||
# define TOTAL_INTERFACES 5
|
||||
#endif
|
||||
|
||||
usbd_device * usbdev;
|
||||
|
||||
@ -78,7 +98,7 @@ static const struct usb_device_descriptor dev_desc = {
|
||||
static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x82,
|
||||
.bEndpointAddress = (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 16,
|
||||
.bInterval = 255,
|
||||
@ -87,14 +107,14 @@ static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{
|
||||
static const struct usb_endpoint_descriptor gdb_data_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x01,
|
||||
.bEndpointAddress = CDCACM_GDB_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE,
|
||||
.bInterval = 1,
|
||||
}, {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bEndpointAddress = CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE,
|
||||
.bInterval = 1,
|
||||
@ -118,7 +138,7 @@ static const struct {
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||
.bmCapabilities = 0,
|
||||
.bDataInterface = 1,
|
||||
.bDataInterface = GDB_IF_NO + 1,
|
||||
},
|
||||
.acm = {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||
@ -130,8 +150,8 @@ static const struct {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||
.bControlInterface = 0,
|
||||
.bSubordinateInterface0 = 1,
|
||||
.bControlInterface = GDB_IF_NO,
|
||||
.bSubordinateInterface0 = GDB_IF_NO + 1,
|
||||
}
|
||||
};
|
||||
|
||||
@ -155,7 +175,7 @@ static const struct usb_interface_descriptor gdb_comm_iface[] = {{
|
||||
static const struct usb_interface_descriptor gdb_data_iface[] = {{
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 1,
|
||||
.bInterfaceNumber = GDB_IF_NO + 1,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_DATA,
|
||||
@ -169,7 +189,7 @@ static const struct usb_interface_descriptor gdb_data_iface[] = {{
|
||||
static const struct usb_iface_assoc_descriptor gdb_assoc = {
|
||||
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||
.bFirstInterface = 0,
|
||||
.bFirstInterface = GDB_IF_NO,
|
||||
.bInterfaceCount = 2,
|
||||
.bFunctionClass = USB_CLASS_CDC,
|
||||
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
|
||||
@ -181,7 +201,7 @@ static const struct usb_iface_assoc_descriptor gdb_assoc = {
|
||||
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x84,
|
||||
.bEndpointAddress = (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 16,
|
||||
.bInterval = 255,
|
||||
@ -190,14 +210,14 @@ static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
||||
static const struct usb_endpoint_descriptor uart_data_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x03,
|
||||
.bEndpointAddress = CDCACM_UART_ENDPOINT,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE / 2,
|
||||
.bInterval = 1,
|
||||
}, {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x83,
|
||||
.bEndpointAddress = CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = CDCACM_PACKET_SIZE,
|
||||
.bInterval = 1,
|
||||
@ -221,7 +241,7 @@ static const struct {
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
|
||||
.bmCapabilities = 0,
|
||||
.bDataInterface = 3,
|
||||
.bDataInterface = UART_IF_NO + 1,
|
||||
},
|
||||
.acm = {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
|
||||
@ -233,15 +253,15 @@ static const struct {
|
||||
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
|
||||
.bDescriptorType = CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
|
||||
.bControlInterface = 2,
|
||||
.bSubordinateInterface0 = 3,
|
||||
.bControlInterface = UART_IF_NO,
|
||||
.bSubordinateInterface0 = UART_IF_NO + 1,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct usb_interface_descriptor uart_comm_iface[] = {{
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 2,
|
||||
.bInterfaceNumber = UART_IF_NO,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = USB_CLASS_CDC,
|
||||
@ -258,7 +278,7 @@ static const struct usb_interface_descriptor uart_comm_iface[] = {{
|
||||
static const struct usb_interface_descriptor uart_data_iface[] = {{
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 3,
|
||||
.bInterfaceNumber = UART_IF_NO + 1,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_DATA,
|
||||
@ -272,7 +292,7 @@ static const struct usb_interface_descriptor uart_data_iface[] = {{
|
||||
static const struct usb_iface_assoc_descriptor uart_assoc = {
|
||||
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||
.bFirstInterface = 2,
|
||||
.bFirstInterface = UART_IF_NO,
|
||||
.bInterfaceCount = 2,
|
||||
.bFunctionClass = USB_CLASS_CDC,
|
||||
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
|
||||
@ -307,7 +327,7 @@ const struct usb_interface_descriptor dfu_iface = {
|
||||
static const struct usb_iface_assoc_descriptor dfu_assoc = {
|
||||
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||
.bFirstInterface = 4,
|
||||
.bFirstInterface = DFU_IF_NO,
|
||||
.bInterfaceCount = 1,
|
||||
.bFunctionClass = 0xFE,
|
||||
.bFunctionSubClass = 1,
|
||||
@ -319,7 +339,7 @@ static const struct usb_iface_assoc_descriptor dfu_assoc = {
|
||||
static const struct usb_endpoint_descriptor trace_endp[] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x85,
|
||||
.bEndpointAddress = TRACE_ENDPOINT | USB_REQ_TYPE_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0,
|
||||
@ -328,7 +348,7 @@ static const struct usb_endpoint_descriptor trace_endp[] = {{
|
||||
const struct usb_interface_descriptor trace_iface = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 5,
|
||||
.bInterfaceNumber = TRACE_IF_NO,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = 0xFF,
|
||||
@ -342,7 +362,7 @@ const struct usb_interface_descriptor trace_iface = {
|
||||
static const struct usb_iface_assoc_descriptor trace_assoc = {
|
||||
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||
.bFirstInterface = 5,
|
||||
.bFirstInterface = TRACE_IF_NO,
|
||||
.bInterfaceCount = 1,
|
||||
.bFunctionClass = 0xFF,
|
||||
.bFunctionSubClass = 0xFF,
|
||||
@ -381,11 +401,7 @@ static const struct usb_config_descriptor config = {
|
||||
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||
.wTotalLength = 0,
|
||||
#if defined(PLATFORM_HAS_TRACESWO)
|
||||
.bNumInterfaces = 6,
|
||||
#else
|
||||
.bNumInterfaces = 5,
|
||||
#endif
|
||||
.bNumInterfaces = TOTAL_INTERFACES,
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = 0x80,
|
||||
@ -437,7 +453,7 @@ static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev,
|
||||
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
|
||||
cdcacm_set_modem_state(dev, req->wIndex, true, true);
|
||||
/* Ignore if not for GDB interface */
|
||||
if(req->wIndex != 0)
|
||||
if(req->wIndex != GDB_IF_NO)
|
||||
return USBD_REQ_HANDLED;
|
||||
|
||||
cdcacm_gdb_dtr = req->wValue & 1;
|
||||
@ -448,10 +464,10 @@ static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev,
|
||||
return USBD_REQ_NOTSUPP;
|
||||
|
||||
switch(req->wIndex) {
|
||||
case 2:
|
||||
case UART_IF_NO:
|
||||
usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf);
|
||||
return USBD_REQ_HANDLED;
|
||||
case 0:
|
||||
case GDB_IF_NO:
|
||||
return USBD_REQ_HANDLED; /* Ignore on GDB Port */
|
||||
default:
|
||||
return USBD_REQ_NOTSUPP;
|
||||
@ -501,6 +517,7 @@ static void cdcacm_set_modem_state(usbd_device *dev, int iface, bool dsr, bool d
|
||||
notif->wLength = 2;
|
||||
buf[8] = (dsr ? 2 : 0) | (dcd ? 1 : 0);
|
||||
buf[9] = 0;
|
||||
/* FIXME: Remove magic numbers */
|
||||
usbd_ep_write_packet(dev, 0x82 + iface, buf, 10);
|
||||
}
|
||||
|
||||
@ -510,26 +527,29 @@ static void cdcacm_set_config(usbd_device *dev, uint16_t wValue)
|
||||
|
||||
/* GDB interface */
|
||||
#if defined(STM32F4) || defined(LM4F) || defined(SAMD)
|
||||
usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK,
|
||||
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, gdb_usb_out_cb);
|
||||
#else
|
||||
usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK,
|
||||
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, NULL);
|
||||
#endif
|
||||
usbd_ep_setup(dev, 0x81, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, NULL);
|
||||
usbd_ep_setup(dev, 0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN,
|
||||
USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
|
||||
usbd_ep_setup(dev, (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN,
|
||||
USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
|
||||
/* Serial interface */
|
||||
usbd_ep_setup(dev, 0x03, USB_ENDPOINT_ATTR_BULK,
|
||||
usbd_ep_setup(dev, CDCACM_UART_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE / 2, usbuart_usb_out_cb);
|
||||
usbd_ep_setup(dev, 0x83, USB_ENDPOINT_ATTR_BULK,
|
||||
usbd_ep_setup(dev, CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN,
|
||||
USB_ENDPOINT_ATTR_BULK,
|
||||
CDCACM_PACKET_SIZE, usbuart_usb_in_cb);
|
||||
usbd_ep_setup(dev, 0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
usbd_ep_setup(dev, (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN,
|
||||
USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||
|
||||
#if defined(PLATFORM_HAS_TRACESWO)
|
||||
/* Trace interface */
|
||||
usbd_ep_setup(dev, 0x85, USB_ENDPOINT_ATTR_BULK,
|
||||
usbd_ep_setup(dev, TRACE_ENDPOINT | USB_REQ_TYPE_IN, USB_ENDPOINT_ATTR_BULK,
|
||||
64, trace_buf_drain);
|
||||
#endif
|
||||
|
||||
@ -541,8 +561,8 @@ static void cdcacm_set_config(usbd_device *dev, uint16_t wValue)
|
||||
/* Notify the host that DCD is asserted.
|
||||
* Allows the use of /dev/tty* devices on *BSD/MacOS
|
||||
*/
|
||||
cdcacm_set_modem_state(dev, 0, true, true);
|
||||
cdcacm_set_modem_state(dev, 2, true, true);
|
||||
cdcacm_set_modem_state(dev, GDB_IF_NO, true, true);
|
||||
cdcacm_set_modem_state(dev, UART_IF_NO, true, true);
|
||||
}
|
||||
|
||||
/* We need a special large control buffer for this device: */
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
#define CDCACM_UART_ENDPOINT 3
|
||||
#define TRACE_ENDPOINT 5
|
||||
|
||||
extern usbd_device *usbdev;
|
||||
|
||||
|
@ -169,7 +169,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
|
||||
continue;
|
||||
}
|
||||
/* Exclude hubs from testing. Probably more classes could be excluded here!*/
|
||||
if (desc.bDeviceClass == LIBUSB_CLASS_HUB) {
|
||||
switch (desc.bDeviceClass) {
|
||||
case LIBUSB_CLASS_HUB:
|
||||
case LIBUSB_CLASS_WIRELESS:
|
||||
continue;
|
||||
}
|
||||
libusb_device_handle *handle;
|
||||
|
@ -48,7 +48,7 @@ int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;}
|
||||
int dap_swdptap_init(ADIv5_DP_t *dp) {return -1;}
|
||||
int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;}
|
||||
void dap_swd_configure(uint8_t cfg) {};
|
||||
void dap_srst_set_val(assert) {};
|
||||
void dap_srst_set_val(bool assert) {};
|
||||
# pragma GCC diagnostic pop
|
||||
|
||||
#endif
|
||||
|
@ -290,7 +290,6 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
||||
opt->opt_targetid = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'M':
|
||||
opt->opt_mode = BMP_MODE_MONITOR;
|
||||
if (optarg)
|
||||
opt->opt_monitor = optarg;
|
||||
break;
|
||||
@ -321,7 +320,11 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
||||
if (opt->opt_mode == BMP_MODE_DEBUG)
|
||||
opt->opt_mode = BMP_MODE_FLASH_WRITE;
|
||||
opt->opt_flash_file = argv[optind];
|
||||
} else if ((opt->opt_mode == BMP_MODE_DEBUG) &&
|
||||
(opt->opt_monitor)) {
|
||||
opt->opt_mode = BMP_MODE_MONITOR; // To avoid DEBUG mode
|
||||
}
|
||||
|
||||
/* Checks */
|
||||
if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) ||
|
||||
(opt->opt_mode == BMP_MODE_SWJ_TEST) ||
|
||||
@ -448,10 +451,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
||||
default:
|
||||
DEBUG_WARN("No test for this core type yet\n");
|
||||
}
|
||||
} else if (opt->opt_mode == BMP_MODE_MONITOR) {
|
||||
res = command_process(t, opt->opt_monitor);
|
||||
if (res)
|
||||
DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor);
|
||||
}
|
||||
if ((opt->opt_mode == BMP_MODE_TEST) ||
|
||||
(opt->opt_mode == BMP_MODE_SWJ_TEST))
|
||||
@ -480,6 +479,11 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
||||
if (opt->opt_flash_size < map.size)
|
||||
/* restrict to size given on command line */
|
||||
map.size = opt->opt_flash_size;
|
||||
if (opt->opt_monitor) {
|
||||
res = command_process(t, opt->opt_monitor);
|
||||
if (res)
|
||||
DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor);
|
||||
}
|
||||
if (opt->opt_mode == BMP_MODE_RESET) {
|
||||
target_reset(t);
|
||||
} else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) {
|
||||
@ -510,6 +514,8 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
||||
unsigned int flashed = target_flash_write(t, opt->opt_flash_start,
|
||||
map.data, map.size);
|
||||
/* Buffered write cares for padding*/
|
||||
if (!flashed)
|
||||
flashed = target_flash_done(t);
|
||||
if (flashed) {
|
||||
DEBUG_WARN("Flashing failed!\n");
|
||||
res = -1;
|
||||
@ -518,7 +524,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
||||
DEBUG_INFO("Success!\n");
|
||||
}
|
||||
}
|
||||
target_flash_done(t);
|
||||
uint32_t end_time = platform_time_ms();
|
||||
DEBUG_WARN("Flash Write succeeded for %d bytes, %8.3f kiB/s\n",
|
||||
(int)map.size, (((map.size * 1.0)/(end_time - start_time))));
|
||||
|
@ -398,7 +398,7 @@ static uint32_t cortexm_initial_halt(ADIv5_AP_t *ap)
|
||||
*/
|
||||
static bool cortexm_prepare(ADIv5_AP_t *ap)
|
||||
{
|
||||
#if PC_HOSTED == 1
|
||||
#if ((PC_HOSTED == 1) || (ENABLE_DEBUG == 1))
|
||||
uint32_t start_time = platform_time_ms();
|
||||
#endif
|
||||
uint32_t dhcsr = cortexm_initial_halt(ap);
|
||||
@ -834,9 +834,15 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
||||
adiv5_ap_unref(ap);
|
||||
}
|
||||
/* We halted at least CortexM for Romtable scan.
|
||||
* Release the devices now. Attach() will halt them again.*/
|
||||
for (target *t = target_list; t; t = t->next)
|
||||
* With connect under reset, keep the devices halted.
|
||||
* Otherwise, release the devices now.
|
||||
* Attach() will halt them again.
|
||||
*/
|
||||
for (target *t = target_list; t; t = t->next) {
|
||||
if (!connect_assert_srst) {
|
||||
target_halt_resume(t, false);
|
||||
}
|
||||
}
|
||||
adiv5_dp_unref(dp);
|
||||
}
|
||||
|
||||
|
@ -471,8 +471,6 @@ bool cortexm_probe(ADIv5_AP_t *ap)
|
||||
PROBE(lpc17xx_probe);
|
||||
}
|
||||
#undef PROBE
|
||||
/* Restart the CortexM we stopped for Romtable scan. Allow pure debug.*/
|
||||
target_halt_resume(t, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1217,8 +1215,8 @@ static int cortexm_hostio_request(target *t)
|
||||
|
||||
t->tc->interrupted = false;
|
||||
target_regs_read(t, arm_regs);
|
||||
target_mem_read(t, params, arm_regs[1], sizeof(params));
|
||||
uint32_t syscall = arm_regs[0];
|
||||
if (syscall != SYS_EXIT) target_mem_read(t, params, arm_regs[1], sizeof(params));
|
||||
int32_t ret = 0;
|
||||
|
||||
DEBUG_INFO("syscall 0"PRIx32"%"PRIx32" (%"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32")\n",
|
||||
@ -1608,7 +1606,7 @@ static int cortexm_hostio_request(target *t)
|
||||
#endif
|
||||
|
||||
case SYS_EXIT: /* _exit() */
|
||||
tc_printf(t, "_exit(0x%x)\n", params[0]);
|
||||
tc_printf(t, "_exit(0x%x)\n", arm_regs[1]);
|
||||
target_halt_resume(t, 1);
|
||||
break;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
* programming.
|
||||
*
|
||||
* Tested with
|
||||
* * SAMD09D14A (rev B)
|
||||
* * SAMD20E17A (rev C)
|
||||
* * SAMD20J18A (rev B)
|
||||
* * SAMD21J18A (rev B)
|
||||
@ -128,7 +129,7 @@ const struct command_s samd_cmd_list[] = {
|
||||
#define SAMD_STATUSB_PROT (1 << 16)
|
||||
|
||||
/* Device Identification Register (DID) */
|
||||
#define SAMD_DID_MASK 0xFF3C0000
|
||||
#define SAMD_DID_MASK 0xFF380000
|
||||
#define SAMD_DID_CONST_VALUE 0x10000000
|
||||
#define SAMD_DID_DEVSEL_MASK 0xFF
|
||||
#define SAMD_DID_DEVSEL_POS 0
|
||||
@ -341,6 +342,8 @@ struct samd_descr {
|
||||
uint8_t series;
|
||||
char revision;
|
||||
char pin;
|
||||
uint32_t ram_size;
|
||||
uint32_t flash_size;
|
||||
uint8_t mem;
|
||||
char variant;
|
||||
char package[3];
|
||||
@ -351,6 +354,8 @@ struct samd_descr samd_parse_device_id(uint32_t did)
|
||||
uint8_t i = 0;
|
||||
const struct samd_part *parts = samd_d21_parts;
|
||||
memset(samd.package, 0, 3);
|
||||
samd.ram_size = 0x8000;
|
||||
samd.flash_size = 0x40000;
|
||||
|
||||
uint8_t family = (did >> SAMD_DID_FAMILY_POS)
|
||||
& SAMD_DID_FAMILY_MASK;
|
||||
@ -380,6 +385,7 @@ struct samd_descr samd_parse_device_id(uint32_t did)
|
||||
}
|
||||
break;
|
||||
case 3: samd.series = 11; break;
|
||||
case 4: samd.series = 9; break;
|
||||
default: samd.series = 0; break;
|
||||
}
|
||||
/* Revision */
|
||||
@ -419,6 +425,23 @@ struct samd_descr samd_parse_device_id(uint32_t did)
|
||||
samd.mem = 14 - (devsel % 3);
|
||||
samd.variant = 'A';
|
||||
break;
|
||||
case 9: /* SAM D09 */
|
||||
samd.ram_size = 4096;
|
||||
switch (devsel) {
|
||||
case 0:
|
||||
samd.pin = 'D';
|
||||
samd.mem = 14;
|
||||
samd.flash_size = 16384;
|
||||
samd.package[0] = 'M';
|
||||
break;
|
||||
case 7:
|
||||
samd.pin = 'C';
|
||||
samd.mem = 13;
|
||||
samd.flash_size = 8192;
|
||||
break;
|
||||
}
|
||||
samd.variant = 'A';
|
||||
break;
|
||||
}
|
||||
|
||||
return samd;
|
||||
@ -475,14 +498,14 @@ bool samd_probe(target *t)
|
||||
/* Part String */
|
||||
if (protected) {
|
||||
sprintf(priv_storage->samd_variant_string,
|
||||
"Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)",
|
||||
"Atmel SAM%c%02d%c%d%c%s (rev %c) (PROT=1)",
|
||||
samd.family,
|
||||
samd.series, samd.pin, samd.mem,
|
||||
samd.variant,
|
||||
samd.package, samd.revision);
|
||||
} else {
|
||||
sprintf(priv_storage->samd_variant_string,
|
||||
"Atmel SAM%c%d%c%d%c%s (rev %c)",
|
||||
"Atmel SAM%c%02d%c%d%c%s (rev %c)",
|
||||
samd.family,
|
||||
samd.series, samd.pin, samd.mem,
|
||||
samd.variant,
|
||||
@ -513,8 +536,8 @@ bool samd_probe(target *t)
|
||||
t->attach = samd_protected_attach;
|
||||
}
|
||||
|
||||
target_add_ram(t, 0x20000000, 0x8000);
|
||||
samd_add_flash(t, 0x00000000, 0x40000);
|
||||
target_add_ram(t, 0x20000000, samd.ram_size);
|
||||
samd_add_flash(t, 0x00000000, samd.flash_size);
|
||||
target_add_commands(t, samd_cmd_list, "SAMD");
|
||||
|
||||
/* If we're not in reset here */
|
||||
|
@ -52,6 +52,9 @@
|
||||
#define FLASH_MEMORY_SIZE 0x1FFF75E0
|
||||
#define FLASH_PAGE_SIZE 0x800
|
||||
#define FLASH_BANK2_START_PAGE_NB 256U
|
||||
#define FLASH_OTP_START 0x1FFF7000
|
||||
#define FLASH_OTP_SIZE 0x400
|
||||
#define FLASH_OTP_BLOCKSIZE 0x8
|
||||
#define FLASH_SIZE_MAX_G03_4 (64U * 1024U) // 64 kiB
|
||||
#define FLASH_SIZE_MAX_G05_6 (64U * 1024U) // 64 kiB
|
||||
#define FLASH_SIZE_MAX_G07_8 (128U * 1024U) // 128 kiB
|
||||
@ -189,7 +192,7 @@ static void stm32g0_add_flash(target *t, uint32_t addr, size_t length,
|
||||
f->blocksize = blocksize;
|
||||
f->erase = stm32g0_flash_erase;
|
||||
f->write = stm32g0_flash_write;
|
||||
f->buf_size = FLASH_PAGE_SIZE;
|
||||
f->buf_size = blocksize;
|
||||
f->erased = 0xFF;
|
||||
target_add_flash(t, f);
|
||||
}
|
||||
@ -249,6 +252,9 @@ bool stm32g0_probe(target *t)
|
||||
priv_storage->irreversible_enabled = false;
|
||||
t->target_storage = (void*)priv_storage;
|
||||
|
||||
/* OTP Flash area */
|
||||
stm32g0_add_flash(t, FLASH_OTP_START, FLASH_OTP_SIZE, FLASH_OTP_BLOCKSIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -311,6 +317,7 @@ static void stm32g0_flash_lock(target *t)
|
||||
|
||||
/*
|
||||
* Flash erasure function.
|
||||
* OTP case: this function clears any previous error and returns.
|
||||
*/
|
||||
static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
|
||||
size_t len)
|
||||
@ -328,11 +335,6 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
|
||||
if (len == (size_t)0U)
|
||||
goto exit_cleanup;
|
||||
|
||||
nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U;
|
||||
if (t->idcode == STM32G0B_C) // Dual-bank devices
|
||||
bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize;
|
||||
page_nb = (uint16_t)((addr - f->start) / f->blocksize);
|
||||
|
||||
/* Wait for Flash ready */
|
||||
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY_MASK) {
|
||||
if (target_check_error(t))
|
||||
@ -342,6 +344,14 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
|
||||
/* Clear any previous programming error */
|
||||
target_mem_write32(t, FLASH_SR, target_mem_read32(t, FLASH_SR));
|
||||
|
||||
if (addr >= (target_addr)FLASH_OTP_START)
|
||||
goto exit_cleanup;
|
||||
|
||||
nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U;
|
||||
if (t->idcode == STM32G0B_C) // Dual-bank devices
|
||||
bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize;
|
||||
page_nb = (uint16_t)((addr - f->start) / f->blocksize);
|
||||
|
||||
stm32g0_flash_unlock(t);
|
||||
|
||||
do {
|
||||
@ -392,12 +402,20 @@ exit_cleanup:
|
||||
* The SR is supposed to be ready and free of any error.
|
||||
* After a successful programming, the EMPTY bit is cleared to allow rebooting
|
||||
* in Main Flash memory without power cycle.
|
||||
* OTP area is programmed as the "program" area. It can be programmed 8-bytes
|
||||
* by 8-bytes.
|
||||
*/
|
||||
static int stm32g0_flash_write(struct target_flash *f, target_addr dest,
|
||||
const void *src, size_t len)
|
||||
{
|
||||
target *t = f->t;
|
||||
int ret = 0;
|
||||
struct stm32g0_priv_s *ps = (struct stm32g0_priv_s*)t->target_storage;
|
||||
|
||||
if ((dest >= (target_addr)FLASH_OTP_START) && !ps->irreversible_enabled) {
|
||||
tc_printf(t, "Irreversible operations disabled\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
stm32g0_flash_unlock(t);
|
||||
|
||||
|
@ -671,8 +671,12 @@ static const uint8_t g4_i2offset[11] = {
|
||||
0x20, 0x24, 0x28, 0x2c, 0x30, 0x70, 0x44, 0x48, 0x4c, 0x50, 0x74
|
||||
};
|
||||
|
||||
static const uint8_t wl_i2offset[7] = {
|
||||
0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38
|
||||
};
|
||||
|
||||
static bool stm32l4_option_write(
|
||||
target *t,const uint32_t *values, int len, const uint8_t *i2offset)
|
||||
target *t,const uint32_t *values, int len, const uint8_t *i2offset, uint32_t fpec_base)
|
||||
{
|
||||
tc_printf(t, "Device will lose connection. Rescan!\n");
|
||||
stm32l4_flash_unlock(t);
|
||||
@ -682,7 +686,7 @@ static bool stm32l4_option_write(
|
||||
if(target_check_error(t))
|
||||
return true;
|
||||
for (int i = 0; i < len; i++)
|
||||
target_mem_write32(t, L4_FPEC_BASE + i2offset[i], values[i]);
|
||||
target_mem_write32(t, fpec_base + i2offset[i], values[i]);
|
||||
stm32l4_flash_write32(t, FLASH_CR, FLASH_CR_OPTSTRT);
|
||||
while (stm32l4_flash_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
||||
if(target_check_error(t))
|
||||
@ -717,10 +721,6 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
|
||||
tc_printf(t, "STM32L5 options not implemented!\n");
|
||||
return false;
|
||||
}
|
||||
if (t->idcode == ID_STM32WLXX) {
|
||||
tc_printf(t, "STM32WLxx options not implemented!\n");
|
||||
return false;
|
||||
}
|
||||
if (t->idcode == ID_STM32WBXX) {
|
||||
tc_printf(t, "STM32WBxx options not implemented!\n");
|
||||
return false;
|
||||
@ -733,12 +733,17 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFF00FFFF, 0xFF00FFFF, 0xFF00FF00
|
||||
};
|
||||
|
||||
static const uint32_t wl_values[11] = {
|
||||
0x3FEFF0AA, 0xFFFFFFFF, 0xFFFFFF00, 0xFF80FFFF, 0xFF80FFFF, 0xFFFFFFFF,
|
||||
0xFFFFFF00
|
||||
};
|
||||
|
||||
uint32_t val;
|
||||
uint32_t values[11] = { 0xFFEFF8AA, 0xFFFFFFFF, 0, 0x000000ff,
|
||||
0x000000ff, 0xffffffff, 0, 0x000000ff, 0x000000ff };
|
||||
int len;
|
||||
bool res = false;
|
||||
|
||||
uint32_t fpec_base = L4_FPEC_BASE;
|
||||
const uint8_t *i2offset = l4_i2offset;
|
||||
if (t->idcode == ID_STM32L43) {/* L43x */
|
||||
len = 5;
|
||||
@ -753,24 +758,30 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
|
||||
len = 6;
|
||||
for (int i = 0; i < len; i++)
|
||||
values[i] = g4_values[i];
|
||||
} else if (t->idcode == ID_STM32WLXX) {/* WLxx */
|
||||
len = 7;
|
||||
i2offset = wl_i2offset;
|
||||
fpec_base = WL_FPEC_BASE;
|
||||
for (int i = 0; i < len; i++)
|
||||
values[i] = wl_values[i];
|
||||
} else {
|
||||
len = 9;
|
||||
}
|
||||
if ((argc == 2) && !strcmp(argv[1], "erase")) {
|
||||
res = stm32l4_option_write(t, values, len, i2offset);
|
||||
res = stm32l4_option_write(t, values, len, i2offset, fpec_base);
|
||||
} else if ((argc > 2) && !strcmp(argv[1], "write")) {
|
||||
int i;
|
||||
for (i = 2; i < argc; i++)
|
||||
values[i - 2] = strtoul(argv[i], NULL, 0);
|
||||
for (i = i - 2; i < len; i++) {
|
||||
uint32_t addr = L4_FPEC_BASE + i2offset[i];
|
||||
uint32_t addr = fpec_base + i2offset[i];
|
||||
values[i] = target_mem_read32(t, addr);
|
||||
}
|
||||
if ((values[0] & 0xff) == 0xCC) {
|
||||
values[0]++;
|
||||
tc_printf(t, "Changing Level 2 request to Level 1!");
|
||||
}
|
||||
res = stm32l4_option_write(t, values, len, i2offset);
|
||||
res = stm32l4_option_write(t, values, len, i2offset, fpec_base);
|
||||
} else {
|
||||
tc_printf(t, "usage: monitor option erase\n");
|
||||
tc_printf(t, "usage: monitor option write <value> ...\n");
|
||||
@ -780,8 +791,8 @@ static bool stm32l4_cmd_option(target *t, int argc, char *argv[])
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < len; i ++) {
|
||||
uint32_t addr = L4_FPEC_BASE + i2offset[i];
|
||||
val = target_mem_read32(t, L4_FPEC_BASE + i2offset[i]);
|
||||
uint32_t addr = fpec_base + i2offset[i];
|
||||
val = target_mem_read32(t, fpec_base + i2offset[i]);
|
||||
tc_printf(t, "0x%08X: 0x%08X\n", addr, val);
|
||||
}
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user