getting further. IR/DR shifting definitely works, TCLK handling probably broken
This commit is contained in:
parent
9ca6ae61c0
commit
377733b191
|
@ -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
|
||||||
|
|
23
src/main.c
23
src/main.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
38
src/tap.c
38
src/tap.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue