mirror of https://github.com/ARMmbed/mbed-os.git
229 lines
7.1 KiB
Python
229 lines
7.1 KiB
Python
"""
|
|
mbed CMSIS-DAP debugger
|
|
Copyright (c) 2006-2013 ARM Limited
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
"""
|
|
|
|
from cmsis_dap_core import dapTransferBlock, dapWriteAbort, dapSWJPins, dapConnect, dapDisconnect, dapTransfer, dapSWJSequence, dapSWDConfigure, dapSWJClock, dapTransferConfigure, dapInfo
|
|
from transport import Transport
|
|
import logging
|
|
from time import sleep
|
|
|
|
# !! This value are A[2:3] and not A[3:2]
|
|
DP_REG = {'IDCODE' : 0x00,
|
|
'ABORT' : 0x00,
|
|
'CTRL_STAT': 0x04,
|
|
'SELECT': 0x08
|
|
}
|
|
AP_REG = {'CSW' : 0x00,
|
|
'TAR' : 0x04,
|
|
'DRW' : 0x0C
|
|
}
|
|
|
|
IDCODE = 0 << 2
|
|
AP_ACC = 1 << 0
|
|
DP_ACC = 0 << 0
|
|
READ = 1 << 1
|
|
WRITE = 0 << 1
|
|
VALUE_MATCH = 1 << 4
|
|
MATCH_MASK = 1 << 5
|
|
|
|
APBANKSEL = 0x000000f0
|
|
|
|
# AP Control and Status Word definitions
|
|
CSW_SIZE = 0x00000007
|
|
CSW_SIZE8 = 0x00000000
|
|
CSW_SIZE16 = 0x00000001
|
|
CSW_SIZE32 = 0x00000002
|
|
CSW_ADDRINC = 0x00000030
|
|
CSW_NADDRINC = 0x00000000
|
|
CSW_SADDRINC = 0x00000010
|
|
CSW_PADDRINC = 0x00000020
|
|
CSW_DBGSTAT = 0x00000040
|
|
CSW_TINPROG = 0x00000080
|
|
CSW_HPROT = 0x02000000
|
|
CSW_MSTRTYPE = 0x20000000
|
|
CSW_MSTRCORE = 0x00000000
|
|
CSW_MSTRDBG = 0x20000000
|
|
CSW_RESERVED = 0x01000000
|
|
|
|
CSW_VALUE = (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC)
|
|
|
|
TRANSFER_SIZE = {8: CSW_SIZE8,
|
|
16: CSW_SIZE16,
|
|
32: CSW_SIZE32
|
|
}
|
|
|
|
|
|
def JTAG2SWD(interface):
|
|
data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
|
|
dapSWJSequence(interface, data)
|
|
|
|
data = [0x9e, 0xe7]
|
|
dapSWJSequence(interface, data)
|
|
|
|
data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
|
|
dapSWJSequence(interface, data)
|
|
|
|
data = [0x00]
|
|
dapSWJSequence(interface, data)
|
|
|
|
class CMSIS_DAP(Transport):
|
|
"""
|
|
This class implements the CMSIS-DAP protocol
|
|
"""
|
|
def __init__(self, interface):
|
|
self.interface = interface
|
|
self.packet_max_count = 0
|
|
self.packet_max_size = 0
|
|
self.csw = -1
|
|
self.dp_select = -1
|
|
return
|
|
|
|
def init(self):
|
|
# init dap IO
|
|
dapConnect(self.interface)
|
|
# set clock freq at 1000000Hz
|
|
dapSWJClock(self.interface)
|
|
# configure transfer
|
|
dapTransferConfigure(self.interface)
|
|
# configure swd protocol
|
|
dapSWDConfigure(self.interface)
|
|
# switch from jtag to swd
|
|
JTAG2SWD(self.interface)
|
|
# read ID code
|
|
logging.info('IDCODE: 0x%X', self.readDP(DP_REG['IDCODE']))
|
|
# clear abort err
|
|
dapWriteAbort(self.interface, 0x1e);
|
|
return
|
|
|
|
def uninit(self):
|
|
dapDisconnect(self.interface)
|
|
return
|
|
|
|
def info(self, request):
|
|
resp = None
|
|
try:
|
|
resp = dapInfo(self.interface, request)
|
|
except KeyError:
|
|
logging.error('request %s not supported', request)
|
|
return resp
|
|
|
|
def writeMem(self, addr, data, transfer_size = 32):
|
|
self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size])
|
|
|
|
if transfer_size == 8:
|
|
data = data << ((addr & 0x03) << 3)
|
|
elif transfer_size == 16:
|
|
data = data << ((addr & 0x02) << 3)
|
|
|
|
dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'],
|
|
WRITE | AP_ACC | AP_REG['DRW']],
|
|
[addr, data])
|
|
|
|
def readMem(self, addr, transfer_size = 32):
|
|
self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size])
|
|
|
|
resp = dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'],
|
|
READ | AP_ACC | AP_REG['DRW']],
|
|
[addr])
|
|
|
|
res = (resp[0] << 0) | \
|
|
(resp[1] << 8) | \
|
|
(resp[2] << 16) | \
|
|
(resp[3] << 24)
|
|
|
|
if transfer_size == 8:
|
|
res = (res >> ((addr & 0x03) << 3) & 0xff)
|
|
elif transfer_size == 16:
|
|
res = (res >> ((addr & 0x02) << 3) & 0xffff)
|
|
|
|
return res
|
|
|
|
# write aligned word ("data" are words)
|
|
def writeBlock32(self, addr, data):
|
|
# put address in TAR
|
|
self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)
|
|
self.writeAP(AP_REG['TAR'], addr)
|
|
dapTransferBlock(self.interface, len(data), WRITE | AP_ACC | AP_REG['DRW'], data)
|
|
return
|
|
|
|
# read aligned word (the size is in words)
|
|
def readBlock32(self, addr, size):
|
|
# put address in TAR
|
|
self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)
|
|
self.writeAP(AP_REG['TAR'], addr)
|
|
data = []
|
|
resp = dapTransferBlock(self.interface, size, READ | AP_ACC | AP_REG['DRW'])
|
|
for i in range(len(resp)/4):
|
|
data.append( (resp[i*4 + 0] << 0) | \
|
|
(resp[i*4 + 1] << 8) | \
|
|
(resp[i*4 + 2] << 16) | \
|
|
(resp[i*4 + 3] << 24))
|
|
return data
|
|
|
|
|
|
def readDP(self, addr):
|
|
resp = dapTransfer(self.interface, 1, [READ | DP_ACC | (addr & 0x0c)])
|
|
return (resp[0] << 0) | \
|
|
(resp[1] << 8) | \
|
|
(resp[2] << 16) | \
|
|
(resp[3] << 24)
|
|
|
|
def writeDP(self, addr, data):
|
|
if addr == DP_REG['SELECT']:
|
|
if data == self.dp_select:
|
|
return
|
|
self.dp_select = data
|
|
|
|
dapTransfer(self.interface, 1, [WRITE | DP_ACC | (addr & 0x0c)], [data])
|
|
return True
|
|
|
|
def writeAP(self, addr, data):
|
|
if addr == AP_REG['CSW']:
|
|
if data == self.csw:
|
|
return
|
|
self.csw = data
|
|
|
|
ap_sel = addr & 0xff000000
|
|
bank_sel = addr & APBANKSEL
|
|
|
|
self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel)
|
|
dapTransfer(self.interface, 1, [WRITE | AP_ACC | (addr & 0x0c)], [data])
|
|
return True
|
|
|
|
def readAP(self, addr):
|
|
ap_sel = addr & 0xff000000
|
|
bank_sel = addr & APBANKSEL
|
|
|
|
self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel)
|
|
resp = dapTransfer(self.interface, 1, [READ | AP_ACC | (addr & 0x0c)])
|
|
return (resp[0] << 0) | \
|
|
(resp[1] << 8) | \
|
|
(resp[2] << 16) | \
|
|
(resp[3] << 24)
|
|
|
|
def reset(self):
|
|
dapSWJPins(self.interface, 0, 'nRESET')
|
|
sleep(0.1)
|
|
dapSWJPins(self.interface, 0x80, 'nRESET')
|
|
sleep(0.1)
|
|
|
|
def assertReset(self, asserted):
|
|
if asserted:
|
|
dapSWJPins(self.interface, 0, 'nRESET')
|
|
else:
|
|
dapSWJPins(self.interface, 0x80, 'nRESET')
|
|
|
|
|