fixes so that it runs ,but it doesn't seem to work with my test target (msp432 devboard)

This commit is contained in:
Triss 2021-08-01 05:22:33 +02:00
parent 15d73015e0
commit 93cc1dd13c
7 changed files with 174 additions and 47 deletions

View File

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <hardware/gpio.h> #include <hardware/gpio.h>
#include <pico/time.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) { inline static void jscan_pin_mode(uint8_t pin, int mode) {
gpio_set_dir(pin, mode == 1); gpio_set_dir(pin, mode == 1);
if (mode == 0) gpio_pull_up(pin); 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 #endif

View File

@ -15,6 +15,7 @@ def dmctl_do(args: Any) -> int:
def get_device_info(conn, args): return devcmds.get_device_info(conn) 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 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 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): def uart_hw_flowctl(conn, args):
if args.get: return devcmds.uart_hw_flowctl_get(conn) if args.get: return devcmds.uart_hw_flowctl_get(conn)
@ -38,7 +39,7 @@ def dmctl_do(args: Any) -> int:
return 1 return 1
return devcmds.tempsensor_set(conn, tsen) return devcmds.tempsensor_set(conn, tsen)
def jtag_scan(conn, args): 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): def sump_ovclk(conn, args):
if args.get: return devcmds.sump_overclock_get(conn) if args.get: return devcmds.sump_overclock_get(conn)
oven = args.set oven = args.set
@ -57,6 +58,7 @@ def dmctl_do(args: Any) -> int:
'get-device-info': get_device_info, 'get-device-info': get_device_info,
'get-mode-info': get_mode_info, 'get-mode-info': get_mode_info,
'set-mode': set_mode, 'set-mode': set_mode,
'bootloader': bootloader,
'uart-cts-rts': uart_hw_flowctl, 'uart-cts-rts': uart_hw_flowctl,
'tempsensor': tempsensor, 'tempsensor': tempsensor,
@ -138,6 +140,8 @@ def main() -> int:
setmode = subcmds.add_parser("set-mode", help="Set the device mode") setmode = subcmds.add_parser("set-mode", help="Set the device mode")
setmode.add_argument('mode', type=int, help="Mode to switch to, required.") 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 # mode 1 commands
usbhwfctl = subcmds.add_parser("uart-cts-rts", help="Get, enable/disable"+\ usbhwfctl = subcmds.add_parser("uart-cts-rts", help="Get, enable/disable"+\
" UART hardware flow control") " UART hardware flow control")
@ -168,9 +172,11 @@ def main() -> int:
"short for --set true") "short for --set true")
jtagscan = subcmds.add_parser("jtag-scan", help="JTAG pinout scanner") 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)") "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)") "the pin range to scan (inclusive)")
sumpla = subcmds.add_parser("sump-overclock", sumpla = subcmds.add_parser("sump-overclock",

View File

@ -1,4 +1,6 @@
import sys
import time
import traceback import traceback
from typing import * from typing import *
@ -107,7 +109,7 @@ def tempsensor_get(dev: DmjDevice) -> int:
return 1 return 1
def tempsensor_set(dev, v: int) -> int: def tempsensor_set(dev: DmjDevice, v: int) -> int:
try: try:
old, new = dev.m1_tempsensor_i2cemul_set(v) old, new = dev.m1_tempsensor_i2cemul_set(v)
olds = "disabled" if old is None else ("0x%02x" % old) 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: def jtag_scan(dev: DmjDevice, typ: str, start_pin: int, end_pin: int) -> int:
SCAN_IDLE = 0x00 SCAN_IDLE = 0x7f
SCAN_BUSY = 0x01 SCAN_DONE_F = 0x80
SCAN_FAIL = 0x03
SCAN_SUCCESS = 0x04 types = { 0x00: 'jtag', 0x01: 'swd', 0x02: 'sbw' }
typei = { 'jtag': 0x00, 'swd': 0x01, 'sbw': 0x02 }
try: try:
assert typ in typei
stat = dev.m3_jtagscan_get_status() stat = dev.m3_jtagscan_get_status()
if stat == SCAN_BUSY: if stat < SCAN_IDLE:
print("Another scan already in progress, aborting") print("Another %s scan already in progress, aborting" % types.get(stat, "pinout"))
return 1 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() 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 return 0
else: else:
print("Huh, device replied weird status %d?" % stat) print("Huh, device replied weird status %d?" % stat)

View File

@ -1,4 +1,7 @@
from __future__ import annotations
import array import array
import struct import struct
@ -15,13 +18,67 @@ STAT_BADARG = 0x04
STAT_ILLSTATE = 0x05 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): def check_statpl(stat, pl, defmsg, minl=None, maxl=None):
statmsgs = { statmsgs = {
STAT_OK: "ok", STAT_OK: "ok",
STAT_ILLCMD: "Illegal/invalid/unknown command", STAT_ILLCMD: "Illegal/invalid/unknown command",
STAT_BADMODE: "Bad mode for this command", STAT_BADMODE: "Bad mode for this command",
STAT_NOSUCHMODE: "No such mode exists or is available", STAT_NOSUCHMODE: "No such mode exists or is available",
STAT_BADARG: "Bad argument" STAT_BADARG: "Bad argument",
STAT_ILLSTATE: "Wrong state for command" STAT_ILLSTATE: "Wrong state for command"
} }
@ -225,29 +282,39 @@ class DmjDevice:
return pl[0] return pl[0]
def m3_jtagscan_get_result(self) -> Dict[str, int]: def m3_jtagscan_get_result_jtag(self, nmatches: int) -> List[JtagMatch]:
pinassign = ['TCK', 'TMS', 'TDI', 'TDO', 'TRST']
self.write(b'\x34') self.write(b'\x34')
stat, pl = self.read_resp() 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') self.write(b'\x34')
stat, pl = self.read_resp() 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): def m3_jtagscan_start(self, typ: int, min_pin: int, max_pin: int):
cmd = bytearray(b'\x35\xff\x00') cmd = bytearray(b'\x35\xff\xff\x00')
cmd[1], cmd[2] = min_pin, max_pin cmd[1] = typ
cmd[2], cmd[3] = min_pin, max_pin
self.write(cmd) self.write(cmd)
stat, pl = self.read_resp() stat, pl = self.read_resp()
check_statpl(stat, pl, "m3: jtag scan start", 0, 0) 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 # mode 4 commands
def m4_sump_overclock_get(self) -> int: def m4_sump_overclock_get(self) -> int:

View File

@ -4,6 +4,7 @@
#include "mode.h" #include "mode.h"
#include "thread.h" #include "thread.h"
#include "usbstdio.h"
#include "vnd_cfg.h" #include "vnd_cfg.h"
#include "m_jscan/bsp-feature.h" #include "m_jscan/bsp-feature.h"

View File

@ -1,5 +1,6 @@
// vim: set et: // vim: set et:
#include <stdio.h>
#include <string.h> #include <string.h>
#include "thread.h" #include "thread.h"
@ -114,8 +115,8 @@ static const char PATTERN[PATTERN_MATCH_LEN] = "01100111010011011010000101110010
#define PATTERN_CMP_LEN 32 #define PATTERN_CMP_LEN 32
static const uint32_t PATTERN = 0x7bd50cec; // 01111011110101010000110011101100*/ static const uint32_t PATTERN = 0x7bd50cec; // 01111011110101010000110011101100*/
#define TAP_SHIFTIR 0x3ec #define TAP_SHIFTIR /*0x3ec*//*0x0df*/"1111101100"
#define TAP_SHIFTIR_LEN 10 /*#define TAP_SHIFTIR_LEN 10*/
static void init_pins(uint8_t tck, uint8_t tms, uint8_t tdi, uint8_t ntrst) { static void init_pins(uint8_t tck, uint8_t tms, uint8_t tdi, uint8_t ntrst) {
for (int i = startpin; i <= endpin; ++i) { 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) { for (size_t i = 0; i < tslen; ++i) {
jscan_delay_half_clk();
jscan_delay_half_clk(); jscan_delay_half_clk();
jscan_pin_set(tck, 0); 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_delay_half_clk();
jscan_pin_set(tck, 1); 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_delay_half_clk();
jscan_pin_set(tck, 0); jscan_pin_set(tck, 0);
} }
jscan_delay_half_clk();
jscan_pin_set(tdi, s_tdi); jscan_pin_set(tdi, s_tdi);
//printf("set tdi %d\n", s_tdi);
if (tck != 0xff) { if (tck != 0xff) {
jscan_delay_half_clk(); jscan_delay_half_clk();
jscan_pin_set(tck, 1); 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) { 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 w = 0;
//size_t plen = PATTERN_CMP_LEN;//strlen(pattern); size_t plen = /*PATTERN_CMP_LEN;*/strlen(pattern);
char tdo_read, tdo_prev; char tdo_read, tdo_prev;
size_t nr_toggle = 0; size_t nr_toggle = 0;
//uint64_t rcv = 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'); pulse_tdi(tck, tdi, /*(pattern >> w) & 1*/pattern[w] - '0');
++w; ++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); tdo_read = '0' + (jscan_pin_get(tdo) ? 1 : 0);
//printf("get tdo %c\n", tdo_read);
if (tdo_read != tdo_prev) ++nr_toggle; if (tdo_read != tdo_prev) ++nr_toggle;
tdo_prev = tdo_read; tdo_prev = tdo_read;
if (i < PATTERN_CMP_LEN) rcv[i] = tdo_read; if (i < plen/*PATTERN_CMP_LEN*/) rcv[i] = tdo_read;
else { else {
memmove(rcv, rcv + 1, PATTERN_CMP_LEN - 1); memmove(rcv, rcv + 1, plen/*PATTERN_CMP_LEN*/ - 1);
rcv[PATTERN_CMP_LEN - 1] = tdo_read; rcv[plen/*PATTERN_CMP_LEN*/ - 1] = tdo_read;
} }
//rcv = (rcv >> 1) | ((uint64_t)tdo_read << (PATTERN_MATCH_LEN-1))//(rcv << 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 (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; return 1;
} }
} }
@ -216,9 +224,11 @@ static void scan_jtag(void) {
if (tdi == tdo) continue; if (tdi == tdo) continue;
init_pins(tck, tms, tdi, ntrst); 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 reg_len;
size_t ret = check_data(PATTERN, 2*PATTERN_MATCH_LEN, tck, tdi, tdo, &reg_len); size_t ret = check_data(PATTERN, 2*PATTERN_MATCH_LEN, tck, tdi, tdo, &reg_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) { if (ret == 0) {
YIELD_AND_CHECK_IF_STOPPED(); YIELD_AND_CHECK_IF_STOPPED();
continue; continue;

View File

@ -4,6 +4,7 @@
#include "mode.h" #include "mode.h"
#include "thread.h" #include "thread.h"
#include "usbstdio.h"
#include "vnd_cfg.h" #include "vnd_cfg.h"
#include "m_sump/bsp-feature.h" #include "m_sump/bsp-feature.h"