fixes so that it runs ,but it doesn't seem to work with my test target (msp432 devboard)
This commit is contained in:
parent
15d73015e0
commit
93cc1dd13c
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <hardware/gpio.h>
|
||||
#include <pico/time.h>
|
||||
|
@ -17,8 +18,16 @@ inline static void jscan_delay_half_clk(void) { sleep_us(25); }
|
|||
inline static void jscan_pin_mode(uint8_t pin, int mode) {
|
||||
gpio_set_dir(pin, mode == 1);
|
||||
if (mode == 0) gpio_pull_up(pin);
|
||||
else gpio_disable_pulls(pin);
|
||||
}
|
||||
inline static bool jscan_pin_get(uint8_t pin) {
|
||||
bool r = gpio_get(pin);
|
||||
//printf("get pin %d -> %c\n", pin, r?'1':'0');
|
||||
return r;
|
||||
}
|
||||
inline static void jscan_pin_set(uint8_t pin, bool v) {
|
||||
//printf("set pin %d = %c\n", pin, v?'1':'0');
|
||||
gpio_put(pin, v);
|
||||
}
|
||||
inline static bool jscan_pin_get(uint8_t pin) { return gpio_get(pin); }
|
||||
inline static void jscan_pin_set(uint8_t pin, bool v) { gpio_put(pin, v); }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@ def dmctl_do(args: Any) -> int:
|
|||
def get_device_info(conn, args): return devcmds.get_device_info(conn)
|
||||
def get_mode_info(conn, args): return devcmds.get_mode_info(conn, args.mode)
|
||||
def set_mode(conn, args): return devcmds.set_mode(conn, args.mode)
|
||||
def bootloader(conn, args): return devcmds.set_mode(conn, 0)
|
||||
|
||||
def uart_hw_flowctl(conn, args):
|
||||
if args.get: return devcmds.uart_hw_flowctl_get(conn)
|
||||
|
@ -38,7 +39,7 @@ def dmctl_do(args: Any) -> int:
|
|||
return 1
|
||||
return devcmds.tempsensor_set(conn, tsen)
|
||||
def jtag_scan(conn, args):
|
||||
return devcmds.jtag_scan(args.start, args.end)
|
||||
return devcmds.jtag_scan(conn, args.type, args.start, args.end)
|
||||
def sump_ovclk(conn, args):
|
||||
if args.get: return devcmds.sump_overclock_get(conn)
|
||||
oven = args.set
|
||||
|
@ -57,6 +58,7 @@ def dmctl_do(args: Any) -> int:
|
|||
'get-device-info': get_device_info,
|
||||
'get-mode-info': get_mode_info,
|
||||
'set-mode': set_mode,
|
||||
'bootloader': bootloader,
|
||||
|
||||
'uart-cts-rts': uart_hw_flowctl,
|
||||
'tempsensor': tempsensor,
|
||||
|
@ -138,6 +140,8 @@ def main() -> int:
|
|||
setmode = subcmds.add_parser("set-mode", help="Set the device mode")
|
||||
setmode.add_argument('mode', type=int, help="Mode to switch to, required.")
|
||||
|
||||
bootloader = subcmds.add_parser("bootloader", help="Set the device in bootloader mode")
|
||||
|
||||
# mode 1 commands
|
||||
usbhwfctl = subcmds.add_parser("uart-cts-rts", help="Get, enable/disable"+\
|
||||
" UART hardware flow control")
|
||||
|
@ -168,9 +172,11 @@ def main() -> int:
|
|||
"short for --set true")
|
||||
|
||||
jtagscan = subcmds.add_parser("jtag-scan", help="JTAG pinout scanner")
|
||||
jtagscan.add_argument("start-pin", type=int, help="Number of the start "+\
|
||||
jtagscan.add_argument("type", type=str, help="Pinout type to check for.",
|
||||
choices=['jtag', 'swd']) # TODO: SBW etc
|
||||
jtagscan.add_argument("start", type=int, help="Number of the start "+\
|
||||
"of the pin range to scan (inclusive)")
|
||||
jtagscan.add_argument("end-pin", type=int, help="Number of the end of "+\
|
||||
jtagscan.add_argument("end", type=int, help="Number of the end of "+\
|
||||
"the pin range to scan (inclusive)")
|
||||
|
||||
sumpla = subcmds.add_parser("sump-overclock",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from typing import *
|
||||
|
@ -107,7 +109,7 @@ def tempsensor_get(dev: DmjDevice) -> int:
|
|||
return 1
|
||||
|
||||
|
||||
def tempsensor_set(dev, v: int) -> int:
|
||||
def tempsensor_set(dev: DmjDevice, v: int) -> int:
|
||||
try:
|
||||
old, new = dev.m1_tempsensor_i2cemul_set(v)
|
||||
olds = "disabled" if old is None else ("0x%02x" % old)
|
||||
|
@ -122,31 +124,62 @@ def tempsensor_set(dev, v: int) -> int:
|
|||
# ---
|
||||
|
||||
|
||||
def jtag_scan(dev: DmjDevice, start_pin: int, end_pin: int) -> int:
|
||||
SCAN_IDLE = 0x00
|
||||
SCAN_BUSY = 0x01
|
||||
SCAN_FAIL = 0x03
|
||||
SCAN_SUCCESS = 0x04
|
||||
def jtag_scan(dev: DmjDevice, typ: str, start_pin: int, end_pin: int) -> int:
|
||||
SCAN_IDLE = 0x7f
|
||||
SCAN_DONE_F = 0x80
|
||||
|
||||
types = { 0x00: 'jtag', 0x01: 'swd', 0x02: 'sbw' }
|
||||
typei = { 'jtag': 0x00, 'swd': 0x01, 'sbw': 0x02 }
|
||||
|
||||
try:
|
||||
assert typ in typei
|
||||
|
||||
stat = dev.m3_jtagscan_get_status()
|
||||
|
||||
if stat == SCAN_BUSY:
|
||||
print("Another scan already in progress, aborting")
|
||||
if stat < SCAN_IDLE:
|
||||
print("Another %s scan already in progress, aborting" % types.get(stat, "pinout"))
|
||||
return 1
|
||||
|
||||
dev.m3_jtagscan_start(start_pin, end_pin)
|
||||
minstart, maxend = dev.m3_jtagscan_pinrange()
|
||||
if start_pin < minstart:
|
||||
print("Start pin must be at least %d, but is %d" % (minstart, start_pin))
|
||||
return 1
|
||||
if end_pin > maxend:
|
||||
print("End pin must be at most %d, but is %d" % (maxend, end_pin))
|
||||
return 1
|
||||
if start_pin > end_pin:
|
||||
print("WARN: start pin %d greater than end pin %d, swapping the order..." % (start_pin, end_pin))
|
||||
end_pin, start_pin = start_pin, end_pin
|
||||
|
||||
print("Starting %s scan..." % typ.upper())
|
||||
dev.m3_jtagscan_start(typei[typ], start_pin, end_pin)
|
||||
|
||||
stat = typei[typ]
|
||||
while stat < SCAN_IDLE: # TODO: timeout?
|
||||
if stat != typei[typ]:
|
||||
print("Wut?!! device should be in state %d (%s) but is in %d (%s)" % (typei[typ].upper(), typ, stat, types.get(stat, '???').upper()))
|
||||
|
||||
stat = SCAN_BUSY
|
||||
while stat == SCAN_BUSY: # TODO: timeout?
|
||||
stat = dev.m3_jtagscan_get_status()
|
||||
time.sleep(0.1)
|
||||
sys.stdout.write('.')
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write('\n')
|
||||
|
||||
if (stat & SCAN_DONE_F) != 0:
|
||||
nmatches = stat & (SCAN_DONE_F - 1)
|
||||
print("JTAG scan finished (%d matches)%s" % \
|
||||
(nmatches, ':' if nmatches else ''))
|
||||
|
||||
matches = None
|
||||
if typ == 'jtag':
|
||||
matches = dev.m3_jtagscan_get_result_jtag(nmatches)
|
||||
elif typ == 'swd':
|
||||
matches = dev.m3_jtagscan_get_result_swd(nmatches)
|
||||
else:
|
||||
assert False, "wut"
|
||||
|
||||
for i in range(nmatches): print("%02d\t%s" % (i, str(matches[i])))
|
||||
|
||||
if stat == SCAN_SUCCESS:
|
||||
result = dev.m3_jtagscan_get_result()
|
||||
print("JTAG scan result: %s" % ', '.join("%s=%d" % kvp for kvp in result.items()))
|
||||
return 0
|
||||
elif stat == SCAN_FAIL:
|
||||
print("JTAG scan failure: %s" % dev.m3_jtagscan_get_Error())
|
||||
return 0
|
||||
else:
|
||||
print("Huh, device replied weird status %d?" % stat)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
import array
|
||||
import struct
|
||||
|
||||
|
@ -15,13 +18,67 @@ STAT_BADARG = 0x04
|
|||
STAT_ILLSTATE = 0x05
|
||||
|
||||
|
||||
class JtagMatch(NamedTuple):
|
||||
tck: int
|
||||
tms: int
|
||||
tdi: int
|
||||
tdo: int
|
||||
ntrst: int
|
||||
irlen: int
|
||||
ntoggle: int
|
||||
short_warn: int
|
||||
|
||||
def from_bytes(b: bytes) -> JtagMatch:
|
||||
assert len(b) == 8
|
||||
return JtagMatch(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7])
|
||||
|
||||
def list_from_bytes(b: bytes) -> List[JtagMatch]:
|
||||
nmatches = len(b) // 8
|
||||
assert nmatches * 8 == len(b)
|
||||
|
||||
r = [None]*nmatches
|
||||
for i in range(nmatches): r[i] = JtagMatch.from_bytes(b[(i*8):((i+1)*8)])
|
||||
return r
|
||||
|
||||
def __str__(self):
|
||||
return "TCK=%d TMS=%d TDI=%d TDO=%d nTRST=%d %s=%d%s" % \
|
||||
(self.tck, self.tms, self.tdi, self.tdo, self.ntrst,
|
||||
"IRLEN" if irlen > 0 else "#toggle", self.irlen if self.irlen > 0 else self.toggle,
|
||||
(" (W: may be short-circuit: %d)" % self.short_warn) if self.short_warn else '')
|
||||
|
||||
|
||||
class SwdMatch(NamedTuple):
|
||||
swclk: int
|
||||
swdio: int
|
||||
manuf: int
|
||||
part: int
|
||||
|
||||
def from_bytes(b: bytes) -> SwdMatch:
|
||||
assert len(b) == 6
|
||||
|
||||
clk, dio, m, p = struct.unpack('<BBHH', b)
|
||||
return SwdMatch(clk, dio, m, p)
|
||||
|
||||
def list_from_bytes(b: bytes) -> List[SwdMatch]:
|
||||
nmatches = len(b) // 6
|
||||
assert nmatches * 6 == len(b)
|
||||
|
||||
r = [None]*nmatches
|
||||
for i in range(nmatches): r[i] = SwdMatch.from_bytes(b[(i*6):((i+1)*6)])
|
||||
return r
|
||||
|
||||
def __str__(self):
|
||||
return "SWCLK=%d SWDIO=%d manufacturer=%03x partno=%04x" % \
|
||||
(self.swclk, self.swdio, self.manuf, self.part)
|
||||
|
||||
|
||||
def check_statpl(stat, pl, defmsg, minl=None, maxl=None):
|
||||
statmsgs = {
|
||||
STAT_OK: "ok",
|
||||
STAT_ILLCMD: "Illegal/invalid/unknown command",
|
||||
STAT_BADMODE: "Bad mode for this command",
|
||||
STAT_NOSUCHMODE: "No such mode exists or is available",
|
||||
STAT_BADARG: "Bad argument"
|
||||
STAT_BADARG: "Bad argument",
|
||||
STAT_ILLSTATE: "Wrong state for command"
|
||||
}
|
||||
|
||||
|
@ -225,29 +282,39 @@ class DmjDevice:
|
|||
|
||||
return pl[0]
|
||||
|
||||
def m3_jtagscan_get_result(self) -> Dict[str, int]:
|
||||
pinassign = ['TCK', 'TMS', 'TDI', 'TDO', 'TRST']
|
||||
|
||||
def m3_jtagscan_get_result_jtag(self, nmatches: int) -> List[JtagMatch]:
|
||||
self.write(b'\x34')
|
||||
stat, pl = self.read_resp()
|
||||
check_statpl(stat, pl, "m3: jtag scan result", 5, 5)
|
||||
check_statpl(stat, pl, "m3: jtag scan result", 8*nmatches, 8*nmatches)
|
||||
|
||||
return { pinassign[i]: pl[i] for i in range(len(pl)) }
|
||||
return JtagMatch.list_from_bytes(pl)
|
||||
|
||||
def m3_jtagscan_get_error(self) -> str:
|
||||
def m3_jtagscan_get_result_swd(self, nmatches: int) -> List[SwdMatch]:
|
||||
self.write(b'\x34')
|
||||
stat, pl = self.read_resp()
|
||||
check_statpl(stat, pl, "m3: jtag scan error", 1)
|
||||
check_statpl(stat, pl, "m3: swd scan result", 6*nmatches, 6*nmatches)
|
||||
|
||||
return pl.rstrip(b'\0').decode('utf-8')
|
||||
return SwdMatch.list_from_bytes(pl)
|
||||
|
||||
def m3_jtagscan_start(self, min_pin: int, max_pin: int):
|
||||
cmd = bytearray(b'\x35\xff\x00')
|
||||
cmd[1], cmd[2] = min_pin, max_pin
|
||||
def m3_jtagscan_start(self, typ: int, min_pin: int, max_pin: int):
|
||||
cmd = bytearray(b'\x35\xff\xff\x00')
|
||||
cmd[1] = typ
|
||||
cmd[2], cmd[3] = min_pin, max_pin
|
||||
self.write(cmd)
|
||||
stat, pl = self.read_resp()
|
||||
check_statpl(stat, pl, "m3: jtag scan start", 0, 0)
|
||||
|
||||
def m3_jtagscan_pinrange(self) -> Tuple[int, int]:
|
||||
self.write(b'\x36')
|
||||
stat, pl = self.read_resp()
|
||||
check_statpl(stat, pl, "m3: jtag scan get pin range", 2, 2)
|
||||
return tuple(pl)
|
||||
|
||||
def m3_jtagscan_force_stop(self):
|
||||
self.write(b'\x37')
|
||||
stat, pl = self.read_resp()
|
||||
check_statpl(stat, pl, "m3: jtag scan force stop", 0, 0)
|
||||
|
||||
# mode 4 commands
|
||||
|
||||
def m4_sump_overclock_get(self) -> int:
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "mode.h"
|
||||
#include "thread.h"
|
||||
#include "usbstdio.h"
|
||||
#include "vnd_cfg.h"
|
||||
|
||||
#include "m_jscan/bsp-feature.h"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// vim: set et:
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thread.h"
|
||||
|
@ -114,8 +115,8 @@ static const char PATTERN[PATTERN_MATCH_LEN] = "01100111010011011010000101110010
|
|||
#define PATTERN_CMP_LEN 32
|
||||
static const uint32_t PATTERN = 0x7bd50cec; // 01111011110101010000110011101100*/
|
||||
|
||||
#define TAP_SHIFTIR 0x3ec
|
||||
#define TAP_SHIFTIR_LEN 10
|
||||
#define TAP_SHIFTIR /*0x3ec*//*0x0df*/"1111101100"
|
||||
/*#define TAP_SHIFTIR_LEN 10*/
|
||||
|
||||
static void init_pins(uint8_t tck, uint8_t tms, uint8_t tdi, uint8_t ntrst) {
|
||||
for (int i = startpin; i <= endpin; ++i) {
|
||||
|
@ -131,11 +132,15 @@ static void init_pins(uint8_t tck, uint8_t tms, uint8_t tdi, uint8_t ntrst) {
|
|||
}
|
||||
}
|
||||
|
||||
static void tap_state(uint32_t state, size_t tslen, uint8_t tck, uint8_t tms) {
|
||||
static void tap_state(const char* /*uint32_t*/ state, /*size_t tslen,*/ uint8_t tck, uint8_t tms) {
|
||||
size_t tslen=strlen(state);
|
||||
for (size_t i = 0; i < tslen; ++i) {
|
||||
jscan_delay_half_clk();
|
||||
jscan_delay_half_clk();
|
||||
jscan_pin_set(tck, 0);
|
||||
jscan_pin_set(tms, (state >> i) & 1);
|
||||
jscan_pin_set(tms, state[i] - '0');
|
||||
//printf("tapstate %c\n", state[i]);
|
||||
//jscan_pin_set(tms, (state >> (/*tslen-1 -*/ i)) & 1);
|
||||
jscan_delay_half_clk();
|
||||
jscan_pin_set(tck, 1);
|
||||
}
|
||||
|
@ -146,7 +151,9 @@ static void pulse_tdi(int tck, int tdi, int s_tdi) {
|
|||
jscan_delay_half_clk();
|
||||
jscan_pin_set(tck, 0);
|
||||
}
|
||||
jscan_delay_half_clk();
|
||||
jscan_pin_set(tdi, s_tdi);
|
||||
//printf("set tdi %d\n", s_tdi);
|
||||
if (tck != 0xff) {
|
||||
jscan_delay_half_clk();
|
||||
jscan_pin_set(tck, 1);
|
||||
|
@ -155,7 +162,7 @@ static void pulse_tdi(int tck, int tdi, int s_tdi) {
|
|||
|
||||
static size_t check_data(/*uint64_t*/const char* pattern, size_t iterations, uint8_t tck, uint8_t tdi, uint8_t tdo, size_t* reg_len) {
|
||||
size_t w = 0;
|
||||
//size_t plen = PATTERN_CMP_LEN;//strlen(pattern);
|
||||
size_t plen = /*PATTERN_CMP_LEN;*/strlen(pattern);
|
||||
char tdo_read, tdo_prev;
|
||||
size_t nr_toggle = 0;
|
||||
//uint64_t rcv = 0;
|
||||
|
@ -167,25 +174,26 @@ static size_t check_data(/*uint64_t*/const char* pattern, size_t iterations, uin
|
|||
pulse_tdi(tck, tdi, /*(pattern >> w) & 1*/pattern[w] - '0');
|
||||
|
||||
++w;
|
||||
if (w == PATTERN_CMP_LEN) w = 0;
|
||||
if (!pattern[w]/*w == PATTERN_CMP_LEN*/) w = 0;
|
||||
|
||||
tdo_read = '0' + (jscan_pin_get(tdo) ? 1 : 0);
|
||||
//printf("get tdo %c\n", tdo_read);
|
||||
|
||||
if (tdo_read != tdo_prev) ++nr_toggle;
|
||||
tdo_prev = tdo_read;
|
||||
|
||||
if (i < PATTERN_CMP_LEN) rcv[i] = tdo_read;
|
||||
if (i < plen/*PATTERN_CMP_LEN*/) rcv[i] = tdo_read;
|
||||
else {
|
||||
memmove(rcv, rcv + 1, PATTERN_CMP_LEN - 1);
|
||||
rcv[PATTERN_CMP_LEN - 1] = tdo_read;
|
||||
memmove(rcv, rcv + 1, plen/*PATTERN_CMP_LEN*/ - 1);
|
||||
rcv[plen/*PATTERN_CMP_LEN*/ - 1] = tdo_read;
|
||||
}
|
||||
//rcv = (rcv >> 1) | ((uint64_t)tdo_read << (PATTERN_MATCH_LEN-1))//(rcv << 1) | tdo_read;
|
||||
|
||||
if (i >= PATTERN_CMP_LEN - 1) {
|
||||
if (i >= plen/*PATTERN_CMP_LEN*/ - 1) {
|
||||
//if (pattern == ((rcv >> (PATTERN_MATCH_LEN - PATTERN_CMP_LEN)) & (1uLL << PATTERN_CMP_LEN) - 1))
|
||||
if (!memcmp(pattern, rcv, PATTERN_CMP_LEN))
|
||||
if (!memcmp(pattern, rcv, plen/*PATTERN_CMP_LEN*/))
|
||||
{
|
||||
*reg_len = i + 1 - PATTERN_CMP_LEN;
|
||||
*reg_len = i + 1 - plen/*PATTERN_CMP_LEN*/;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -216,9 +224,11 @@ static void scan_jtag(void) {
|
|||
if (tdi == tdo) continue;
|
||||
|
||||
init_pins(tck, tms, tdi, ntrst);
|
||||
tap_state(TAP_SHIFTIR, TAP_SHIFTIR_LEN, tck, tms);
|
||||
tap_state(TAP_SHIFTIR/*, TAP_SHIFTIR_LEN*/, tck, tms);
|
||||
size_t reg_len;
|
||||
size_t ret = check_data(PATTERN, 2*PATTERN_MATCH_LEN, tck, tdi, tdo, ®_len);
|
||||
printf("tck=%hhu tms=%hhu tdi=%hhu tdo=%hhu ntrst=%hhu , ret=%zu rlen=%zu\n",
|
||||
tck, tms, tdi, tdo, ntrst, ret, reg_len);
|
||||
if (ret == 0) {
|
||||
YIELD_AND_CHECK_IF_STOPPED();
|
||||
continue;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "mode.h"
|
||||
#include "thread.h"
|
||||
#include "usbstdio.h"
|
||||
#include "vnd_cfg.h"
|
||||
|
||||
#include "m_sump/bsp-feature.h"
|
||||
|
|
Loading…
Reference in New Issue