Skip to content

Commit 15eb261

Browse files
committed
WIP. CMSIS-DAP driver.
1 parent 928fb4b commit 15eb261

File tree

1 file changed

+89
-23
lines changed

1 file changed

+89
-23
lines changed

cmsis_dap.py

+89-23
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,31 @@ def find(sn=None):
5252
#------------------------------------------------------------------------------
5353
# cmsis-dap protocol constants
5454

55-
DAP_CMD_INFO = 0x00
55+
# CMSIS-DAP General Commands
56+
CMD_DAP_INFO = 0x00
57+
CMD_DAP_LED = 0x01
58+
CMD_DAP_CONNECT = 0x02
59+
CMD_DAP_DISCONNECT = 0x03
60+
CMD_DAP_WRITE_ABORT = 0x08
61+
CMD_DAP_DELAY = 0x09
62+
CMD_DAP_RESET_TARGET = 0x0A
5663

5764
# DAP_CMD_INFO
58-
DAP_CMD_INFO_VID = 0x01 # Get the Vendor ID (string).
59-
DAP_CMD_INFO_PID = 0x02 # Get the Product ID (string).
60-
DAP_CMD_INFO_SN = 0x03 # Get the Serial Number (string).
61-
DAP_CMD_INFO_FW_VERSION = 0x04 # Get the CMSIS-DAP Firmware Version (string).
62-
DAP_CMD_INFO_VENDOR_NAME = 0x05 # Get the Target Device Vendor (string).
63-
DAP_CMD_INFO_DEVICE_NAME = 0x06 # Get the Target Device Name (string).
64-
DAP_CMD_INFO_DBG_CAPS = 0xF0 # Get information about the Capabilities (BYTE) of the Debug Unit
65-
DAP_CMD_INFO_TDT_PARMS = 0xF1 # Get the Test Domain Timer parameter information
66-
DAP_CMD_INFO_SWO_TRACE_SIZE = 0xFD # Get the SWO Trace Buffer Size (WORD).
67-
DAP_CMD_INFO_MAX_PKT_COUNT = 0xFE # Get the maximum Packet Count (BYTE).
68-
DAP_CMD_INFO_MAX_PKT_SIZE = 0xFF # Get the maximum Packet Size (SHORT).
65+
INFO_ID_VID = 0x01 # Get the Vendor ID (string)
66+
INFO_ID_PID = 0x02 # Get the Product ID (string)
67+
INFO_ID_SN = 0x03 # Get the Serial Number (string)
68+
INFO_ID_FW_VERSION = 0x04 # Get the CMSIS-DAP Firmware Version (string)
69+
INFO_ID_VENDOR_NAME = 0x05 # Get the Target Device Vendor (string)
70+
INFO_ID_DEVICE_NAME = 0x06 # Get the Target Device Name (string)
71+
INFO_ID_DBG_CAPS = 0xF0 # Get information about the Capabilities (BYTE) of the Debug Unit
72+
INFO_ID_TDT_PARMS = 0xF1 # Get the Test Domain Timer parameter information
73+
INFO_ID_SWO_TRACE_SIZE = 0xFD # Get the SWO Trace Buffer Size (WORD)
74+
INFO_ID_MAX_PKT_COUNT = 0xFE # Get the maximum Packet Count (BYTE)
75+
INFO_ID_MAX_PKT_SIZE = 0xFF # Get the maximum Packet Size (SHORT)
76+
77+
# DAP Status Code
78+
DAP_OK = 0
79+
DAP_ERROR = 0xFF
6980

7081
#------------------------------------------------------------------------------
7182
# map register names to cmsis-dap register numbers
@@ -82,6 +93,12 @@ def find(sn=None):
8293
# 20 ?
8394
}
8495

96+
def dump_buf(x):
97+
s = []
98+
for c in x:
99+
s.append('%02x' % c)
100+
print(' '.join(s))
101+
85102
#------------------------------------------------------------------------------
86103

87104
class dap:
@@ -92,8 +109,16 @@ def __init__(self, dev):
92109
self.pid = dev['product_id']
93110
self.sn = dev['serial_number']
94111
self.hid = hid.Device(self.vid, self.pid, self.sn)
95-
self.packet_size = 64 + 1
96-
self.ver = self.get_info_string(DAP_CMD_INFO_FW_VERSION)
112+
self.pkt_size = 64
113+
self.pkt_size = self.get_info_short(INFO_ID_MAX_PKT_SIZE)
114+
self.pkt_count = self.get_info_byte(INFO_ID_MAX_PKT_COUNT)
115+
self.ver = self.get_info_string(INFO_ID_FW_VERSION)
116+
self.caps = self.get_info_byte(INFO_ID_DBG_CAPS)
117+
118+
print('ver %s' % self.ver)
119+
print('caps %d' % self.caps)
120+
print('pkt_count %d' % self.pkt_count)
121+
print('pkt_size %d' % self.pkt_size)
97122

98123
# | close(self)
99124
# | get_feature_report(self, report_id, size)
@@ -109,22 +134,58 @@ def close(self):
109134
"""close the HID"""
110135
self.hid.close()
111136

112-
def cmd_dap_info(self, info):
113-
tx = bytes((0, DAP_CMD_INFO, info))
137+
def xfer(self, tx):
138+
"""tx and rx some bytes to the HID"""
114139
self.hid.write(tx)
115-
rx = self.hid.read(65)
140+
return self.hid.read(self.pkt_size + 1)
141+
142+
def cmd_dap_info(self, id):
143+
rx = self.xfer(bytes((0, CMD_DAP_INFO, id)))
116144
return rx[1:]
117145

118146
def get_info_string(self, info):
119-
x = self.cmd_dap_info(info)
120-
n = x[0]
147+
"""get an information string from the debugger"""
148+
rx = self.cmd_dap_info(info)
149+
n = rx[0]
121150
if n:
122-
return x[1:n].decode("utf-8")
151+
return rx[1:n].decode("utf-8")
152+
return None
153+
154+
def get_info_byte(self, info):
155+
"""get an information byte/u8 from the debugger"""
156+
rx = self.cmd_dap_info(info)
157+
if rx[0] == 1:
158+
return rx[1]
159+
return None
160+
161+
def get_info_short(self, info):
162+
"""get an information short/u16 from the debugger"""
163+
rx = self.cmd_dap_info(info)
164+
if rx[0] == 2:
165+
return rx[1] + (rx[2] << 8)
166+
return None
167+
168+
def get_info_word(self, info):
169+
"""get an information word/u32 from the debugger"""
170+
rx = self.cmd_dap_info(info)
171+
if rx[0] == 4:
172+
return rx[1] + (rx[2] << 8) + (rx[3] << 16) + (rx[4] << 24)
123173
return None
124174

125-
def get_caps_info(self):
126-
x = self.cmd_dap_info(DAP_CMD_INFO_DBG_CAPS)
127-
print(x)
175+
def led_ctrl(self, val):
176+
"""control the debugger leds"""
177+
rx = self.xfer(bytes((0, CMD_DAP_LED, 0, val)))
178+
assert rx[1] == 0
179+
180+
def dap_connect(self, mode):
181+
rx = self.xfer(bytes((0, CMD_DAP_CONNECT, mode)))
182+
assert rx[1] == mode
183+
184+
def dap_disconnect(self):
185+
rx = self.xfer(bytes((0, CMD_DAP_DISCONNECT)))
186+
assert rx[1] == DAP_OK
187+
188+
128189

129190

130191
#def DAP_HostStatus(self):
@@ -133,21 +194,26 @@ def get_caps_info(self):
133194
#def DAP_WriteABORT(self):
134195
#def DAP_Delay(self):
135196
#def DAP_ResetTarget(self):
197+
136198
#def DAP_SWJ_Pins(self):
137199
#def DAP_SWJ_Clock(self):
138200
#def DAP_SWJ_Sequence(self):
201+
139202
#def DAP_SWD_Configure(self):
140203
#def DAP_SWD_Sequence(self):
204+
141205
#def DAP_SWO_Transport(self):
142206
#def DAP_SWO_Mode(self):
143207
#def DAP_SWO_Baudrate(self):
144208
#def DAP_SWO_Control(self):
145209
#def DAP_SWO_Status(self):
146210
#def DAP_SWO_ExtendedStatus(self):
147211
#def DAP_SWO_Data(self):
212+
148213
#def DAP_JTAG_Sequence(self):
149214
#def DAP_JTAG_Configure(self):
150215
#def DAP_JTAG_IDCODE(self):
216+
151217
#def DAP_TransferConfigure(self):
152218
#def DAP_Transfer(self):
153219
#def DAP_TransferBlock(self):

0 commit comments

Comments
 (0)