getting further. IR/DR shifting definitely works, TCLK handling probably broken

This commit is contained in:
Triss 2021-09-28 19:52:33 +02:00
parent 9ca6ae61c0
commit 377733b191
6 changed files with 49 additions and 29 deletions

View File

@ -33,6 +33,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/pio_sbw.c ${CMAKE_CURRENT_SOURCE_DIR}/src/pio_sbw.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tap.c ${CMAKE_CURRENT_SOURCE_DIR}/src/tap.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430dbg.c
) )
# Example include # Example include

View File

@ -1,8 +1,3 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h> #include <stdio.h>
@ -12,6 +7,7 @@
#include "pio_sbw.h" #include "pio_sbw.h"
#include "tap.h" #include "tap.h"
#include "msp430dbg.h"
void printbuf(const uint8_t* buf, size_t size) { void printbuf(const uint8_t* buf, size_t size) {
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
@ -26,11 +22,11 @@ int main() {
stdio_init_all(); stdio_init_all();
sbw_preinit(); /*sbw_preinit();
printf("%s\n", "preinited"); printf("%s\n", "preinited");
bool s = sbw_init(); bool s = sbw_init();
printf("%s\n", s ? "inited" : "failure"); printf("%s\n", s ? "inited" : "failure");*/
/*uint8_t tdi = 0x0f, tdo = 0; /*uint8_t tdi = 0x0f, tdo = 0;
sbw_sequence(8, true, &tdi, &tdo); sbw_sequence(8, true, &tdi, &tdo);
@ -53,12 +49,15 @@ int main() {
sbw_tclk_burst(16); sbw_tclk_burst(16);
printf("done.\n");*/ printf("done.\n");*/
sbw_tap_reset(); // sbw_tap_reset();
sbw_check_fuse(); // sbw_check_fuse();
//
// uint8_t id = sbw_tap_shift_ir(0xff/*IR_BYPASS*/);
//
// printf("JTAG ID=%02x\n", id);
uint8_t id = sbw_tap_shift_ir(0xff/*IR_BYPASS*/); uint32_t initv = msp430_device_get(200e3);
printf("init -> %08lx\n", initv);
printf("JTAG ID=%02x\n", id);
return 0; return 0;
} }

View File

@ -1,8 +1,3 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hardware/clocks.h> #include <hardware/clocks.h>
#include <hardware/dma.h> #include <hardware/dma.h>
@ -88,7 +83,12 @@ bool sbw_init(void) {
return false; return false;
} }
sbw_pio_init(PINOUT_SBW_PIO, sbw_piosm, sbw_offset, 200e3, // need to start at 50 kHz: fuse check needs TMS cycles with a low phase
// of at least 5us. 50 kHz is below the required time (the actual maximum
// frequency would be around 80 kHz), but the exact frequency doesn't
// matter much as we'll switch to a higher one once the check has been
// completed
sbw_pio_init(PINOUT_SBW_PIO, sbw_piosm, sbw_offset, 50e3,
PINOUT_SBW_TCK, PINOUT_SBW_TDIO); PINOUT_SBW_TCK, PINOUT_SBW_TDIO);
last_tdi = last_tms = 0xff; last_tdi = last_tms = 0xff;
@ -133,6 +133,7 @@ static uint8_t bitswap(uint8_t in) {
bool sbw_get_last_tms(void) { return last_tms; } bool sbw_get_last_tms(void) { return last_tms; }
bool sbw_get_last_tdi(void) { return last_tdi; } bool sbw_get_last_tdi(void) { return last_tdi; }
bool sbw_get_last_tclk(void) { return last_tclk; }
void sbw_sequence(uint32_t ncyc, bool tms, const uint8_t* tdi, uint8_t* tdo) { void sbw_sequence(uint32_t ncyc, bool tms, const uint8_t* tdi, uint8_t* tdo) {
if (ncyc == 0) return; if (ncyc == 0) return;

View File

@ -26,6 +26,7 @@ void sbw_set_freq(bool tclk, float freq);
bool sbw_get_last_tms(void); bool sbw_get_last_tms(void);
bool sbw_get_last_tdi(void); bool sbw_get_last_tdi(void);
bool sbw_get_last_tclk(void);
void sbw_sequence(uint32_t ncyc, bool tms, const uint8_t* tdi, uint8_t* tdo); void sbw_sequence(uint32_t ncyc, bool tms, const uint8_t* tdi, uint8_t* tdo);
void sbw_tms_sequence(uint32_t ncyc, bool tdi, const uint8_t* tms); void sbw_tms_sequence(uint32_t ncyc, bool tdi, const uint8_t* tms);

View File

@ -1,4 +1,6 @@
#include <stdio.h>
#include "pio_sbw.h" #include "pio_sbw.h"
#include "tap.h" #include "tap.h"
@ -33,17 +35,25 @@ static uint8_t bitswap(uint8_t in) {
return (lut[in&0xf] << 4) | lut[in>>4]; return (lut[in&0xf] << 4) | lut[in>>4];
} }
static inline uint16_t bitswap16(uint16_t in) { static inline uint16_t bitswap16(uint16_t in) {
//printf("bitswap in=%04x\n", in);
return ((uint16_t)bitswap(in & 0xff) << 8) | bitswap(in >> 8); return ((uint16_t)bitswap(in & 0xff) << 8) | bitswap(in >> 8);
} }
// IR in = OK
// IR out = OK
// DR out = OK
// DR in = BAD!
uint16_t sbw_tap_shift_dr(uint16_t newdr) { uint16_t sbw_tap_shift_dr(uint16_t newdr) {
// DR content is MSB-first instead of LSB-first (IR is the latter) // DR content is MSB-first instead of LSB-first (IR is the latter)
// except the PIO already does bitswaps, so we need to do it for the IR instead // except the PIO already does bitswaps, so we need to do it for the IR instead
newdr = /*bitswap16(*/newdr/*)*/; newdr = bitswap16(newdr);
// 100: run-test/idle -> select-dr-scan -> capture-dr -> shift-dr // 100: run-test/idle -> select-dr-scan -> capture-dr -> shift-dr
const uint8_t tms_seq = 0x01; const uint8_t tms_seqa = 0x01;
sbw_tms_sequence(3, true, &tms_seq); const uint8_t tms_seqb = 0x01 >> 1;
sbw_tms_sequence(1, sbw_get_last_tclk(), &tms_seqa);
sbw_tms_sequence(2, true, &tms_seqb);
// 15 data bits with TMS=0 // 15 data bits with TMS=0
// 1 data bit with TMS=1 (to exit1-dr) // 1 data bit with TMS=1 (to exit1-dr)
@ -55,18 +65,22 @@ uint16_t sbw_tap_shift_dr(uint16_t newdr) {
// TMS=1 (to update-dr) // TMS=1 (to update-dr)
// TMS=0 (to run-test/idle) // TMS=0 (to run-test/idle)
const uint8_t tms_seq_2 = 0x01; const uint8_t tms_seq_2a = 0x01;
sbw_tms_sequence(2, true, &tms_seq_2); const uint8_t tms_seq_2b = 0x01 >> 1;
sbw_tms_sequence(1, true, &tms_seq_2a);
sbw_tms_sequence(1, sbw_get_last_tclk(), &tms_seq_2b);
return /*bitswap16(*/res/*)*/; return bitswap16(res);
} }
uint8_t sbw_tap_shift_ir(uint8_t newir) { uint8_t sbw_tap_shift_ir(uint8_t newir) {
newir = bitswap(newir); newir = /*bitswap(*/newir/*)*/;
// 1100: run-test/idle -> select-dr-scan -> select-ir-scan -> capture-ir -> shift-ir // 1100: run-test/idle -> select-dr-scan -> select-ir-scan -> capture-ir -> shift-ir
const uint8_t tms_seq = 0x03; const uint8_t tms_seqa = 0x03;
sbw_tms_sequence(4, true, &tms_seq); const uint8_t tms_seqb = 0x03 >> 1;
sbw_tms_sequence(1, sbw_get_last_tclk(), &tms_seqa);
sbw_tms_sequence(3, true, &tms_seqb);
// 7 data bits with TMS=0 // 7 data bits with TMS=0
// 1 data bit with TMS=1 (to exit1-ir) // 1 data bit with TMS=1 (to exit1-ir)
@ -77,8 +91,10 @@ uint8_t sbw_tap_shift_ir(uint8_t newir) {
// TMS=1 (to update-ir) // TMS=1 (to update-ir)
// TMS=0 (to run-test/idle) // TMS=0 (to run-test/idle)
const uint8_t tms_seq_2 = 0x01; const uint8_t tms_seq_2a = 0x01;
sbw_tms_sequence(2, true, &tms_seq_2); const uint8_t tms_seq_2b = 0x01 >> 1;
sbw_tms_sequence(1, true, &tms_seq_2a);
sbw_tms_sequence(1, sbw_get_last_tclk(), &tms_seq_2b);
return bitswap(res); return bitswap(res);
} }

View File

@ -2,6 +2,8 @@
#ifndef SBW_TAP_H_ #ifndef SBW_TAP_H_
#define SBW_TAP_H_ #define SBW_TAP_H_
#include <stdint.h>
// move to run-test/idle. typically this is done by sending a single TMS=0 // move to run-test/idle. typically this is done by sending a single TMS=0
// cycle, but the MSP430 has an extra JTAG fuse check that needs to be done // cycle, but the MSP430 has an extra JTAG fuse check that needs to be done
void sbw_tap_reset(void); void sbw_tap_reset(void);