mbed-os/workspace_tools/debugger/pyOCD/transport/cmsis_dap.py

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')