bmp: Implement. Requires firmware from https://github.com/UweBonnes/blackmagic/tree/fixes
This commit is contained in:
parent
e708a7a997
commit
0e7a125256
|
|
@ -133,6 +133,7 @@ set(OPENFPGALOADER_SOURCE
|
|||
src/xilinxMapParser.cpp
|
||||
src/colognechip.cpp
|
||||
src/colognechipCfgParser.cpp
|
||||
src/bmp.cpp
|
||||
)
|
||||
|
||||
set(OPENFPGALOADER_HEADERS
|
||||
|
|
@ -186,6 +187,7 @@ set(OPENFPGALOADER_HEADERS
|
|||
src/xilinxMapParser.hpp
|
||||
src/colognechip.hpp
|
||||
src/colognechipCfgParser.hpp
|
||||
src/bmp.hpp
|
||||
)
|
||||
|
||||
link_directories(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,410 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
* Copyright (c) 2021 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
|
||||
*/
|
||||
|
||||
#include "bmp.hpp"
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
# include<stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bmp_remote.h"
|
||||
|
||||
#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
|
||||
#define DEVICE_BY_ID "/dev/serial/by-id/"
|
||||
|
||||
#define REMOTE_MAX_MSG_SIZE (1024)
|
||||
|
||||
#define FREQ_FIXED -1
|
||||
void Bmp::DEBUG_WARN(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Bmp::DEBUG_WIRE(const char *format, ...)
|
||||
{
|
||||
if (!_verbose)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Bmp::DEBUG_PROBE(const char *format, ...)
|
||||
{
|
||||
if (!_verbose)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static const char hexdigits[] = "0123456789abcdef";
|
||||
|
||||
Bmp::Bmp(std::string dev,
|
||||
const std::string &serial, uint32_t clkHZ, bool verbose)
|
||||
{
|
||||
char name[4096];
|
||||
_verbose = verbose;
|
||||
if (dev.empty()) {
|
||||
DEBUG_PROBE("No device given\n");
|
||||
/* Try to find some BMP if0*/
|
||||
struct dirent *dp;
|
||||
DIR *dir = opendir(DEVICE_BY_ID);
|
||||
if (!dir) {
|
||||
fprintf(stderr,"No serial device found\n");
|
||||
return;
|
||||
}
|
||||
int num_devices = 0;
|
||||
int num_total = 0;
|
||||
while ((dp = readdir(dir)) != NULL) {
|
||||
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
|
||||
(strstr(dp->d_name, "-if00"))) {
|
||||
num_total++;
|
||||
if ((!serial.empty()) && (!strstr(dp->d_name, serial.c_str())))
|
||||
continue;
|
||||
num_devices++;
|
||||
strcpy(name, DEVICE_BY_ID);
|
||||
strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
if ((num_devices == 0) && (num_total == 0)){
|
||||
fprintf(stderr,"No BMP probe found\n");
|
||||
return;
|
||||
} else if (num_devices != 1) {
|
||||
fprintf(stderr,"Available Probes:\n");
|
||||
dir = opendir(DEVICE_BY_ID);
|
||||
if (dir) {
|
||||
while ((dp = readdir(dir)) != NULL) {
|
||||
if ((strstr(dp->d_name, BMP_IDSTRING)) &&
|
||||
(strstr(dp->d_name, "-if00")))
|
||||
fprintf(stderr, "%s\n", dp->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
if (serial.empty())
|
||||
fprintf(stderr, "Select Probe with -s <(Partial) Serial "
|
||||
"Number\n");
|
||||
else
|
||||
fprintf(stderr, "Do no match given serial \"%s\"\n", serial.c_str());
|
||||
} else {
|
||||
fprintf(stderr, "Could not opendir %s: %s\n", name, strerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
strncpy(name, dev.c_str(), sizeof(name) - 1);
|
||||
}
|
||||
fd = open(name, O_RDWR | O_SYNC | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Couldn't open serial port %s\n", name);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Found %s\n", name);
|
||||
if (set_interface_attribs()) {
|
||||
fprintf(stderr, "Can not set line\n");
|
||||
throw std::runtime_error("_buffer malloc failed");
|
||||
}
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int c = snprintf(construct, REMOTE_MAX_MSG_SIZE, "%s", REMOTE_START_STR);
|
||||
platform_buffer_write(construct, c);
|
||||
c = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
|
||||
if ((!c) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
DEBUG_WARN("Remote Start failed, error %s\n",
|
||||
c ? (char *)&(construct[1]) : "unknown");
|
||||
throw std::runtime_error("remote_init failed");
|
||||
}
|
||||
DEBUG_PROBE("Remote is %s\n", &construct[1]);
|
||||
|
||||
/* Get Version to init*/
|
||||
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
|
||||
REMOTE_HL_CHECK_STR);
|
||||
platform_buffer_write(construct, s);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR) ||
|
||||
((construct[1] - '0') < 2)) {
|
||||
fprintf(stderr,
|
||||
"Please update BMP!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
setClkFreq(clkHZ);
|
||||
};
|
||||
|
||||
Bmp::~Bmp()
|
||||
{
|
||||
close(fd);
|
||||
fprintf(stderr, "Close\n");
|
||||
}
|
||||
|
||||
int Bmp::setClkFreq(uint32_t clkHZ)
|
||||
{
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s;
|
||||
s = snprintf(construct, REMOTE_MAX_MSG_SIZE, REMOTE_FREQ_SET_STR,
|
||||
clkHZ);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
fprintf(stderr,"Update Firmware to allow to set max SWJ frequency\n");
|
||||
}
|
||||
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,"%s",
|
||||
REMOTE_FREQ_GET_STR);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR))
|
||||
return FREQ_FIXED;
|
||||
|
||||
uint32_t freq[1];
|
||||
unhexify(freq, &construct[1], 4);
|
||||
fprintf(stderr, "%d Hz\n", freq[0]);
|
||||
return freq[0];
|
||||
}
|
||||
|
||||
int Bmp::writeTMS(uint8_t *tms, int len, bool flush_buffer)
|
||||
{
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s;
|
||||
uint32_t tms_word;
|
||||
int ret = len;
|
||||
while (len) {
|
||||
int chunk = len;
|
||||
if (chunk > 32)
|
||||
chunk = 32;
|
||||
tms_word = *tms++;
|
||||
if (chunk > 8)
|
||||
tms_word |= *tms++ << 8;
|
||||
if (chunk > 16)
|
||||
tms_word |= *tms++ << 16;
|
||||
if (chunk > 24)
|
||||
tms_word |= *tms++ << 24;
|
||||
len -= chunk;
|
||||
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
|
||||
REMOTE_JTAG_TMS_STR, chunk, tms_word);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
DEBUG_WARN("jtagtap_tms_seq failed, error %s\n",
|
||||
s ? (char *)&(construct[1]) : "unknown");
|
||||
throw std::runtime_error("writeTMS failed");
|
||||
}
|
||||
}
|
||||
(void)flush_buffer;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Bmp::writeTDI(uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
|
||||
{
|
||||
int ret = len;
|
||||
|
||||
if(!len || (!tx && !rx))
|
||||
return len;
|
||||
while (len) {
|
||||
int chunk = (len > 2000) ? 2000 : len;
|
||||
len -= chunk;
|
||||
int byte_count = (chunk + 7) >> 3;
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf(
|
||||
construct, REMOTE_MAX_MSG_SIZE,
|
||||
REMOTE_JTAG_IOSEQ_STR,
|
||||
(!len && end) ? REMOTE_IOSEQ_TMS : REMOTE_IOSEQ_NOTMS,
|
||||
(((tx) ? REMOTE_IOSEQ_FLAG_IN : REMOTE_IOSEQ_FLAG_NONE) |
|
||||
((rx) ? REMOTE_IOSEQ_FLAG_OUT : REMOTE_IOSEQ_FLAG_NONE)),
|
||||
chunk);
|
||||
char *p = construct + s;
|
||||
if (tx) {
|
||||
hexify(p, tx, byte_count);
|
||||
p += 2 * byte_count;
|
||||
}
|
||||
*p++ = REMOTE_EOM;
|
||||
*p = 0;
|
||||
platform_buffer_write(construct, p - construct);
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
|
||||
if (rx) {
|
||||
unhexify(rx, (const char*)&construct[1], byte_count);
|
||||
rx += byte_count;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
DEBUG_WARN("%s error %d\n",
|
||||
__func__, s);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Bmp::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len)
|
||||
{
|
||||
char construct[REMOTE_MAX_MSG_SIZE];
|
||||
int s = snprintf(
|
||||
construct, REMOTE_MAX_MSG_SIZE, REMOTE_JTAG_JTCK_STR,
|
||||
(tms) ? 1 : 0, (tdi) ? 1 : 0, clk_len);
|
||||
platform_buffer_write(construct, s);
|
||||
|
||||
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||
DEBUG_WARN("toggleClk, error %s\n",
|
||||
s ? (char *)&(construct[1]) : "unknown");
|
||||
throw std::runtime_error("toggleClk");
|
||||
}
|
||||
return clk_len;
|
||||
}
|
||||
|
||||
int Bmp::set_interface_attribs(void)
|
||||
{
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof tty);
|
||||
if (tcgetattr (fd, &tty) != 0) {
|
||||
fprintf(stderr, "error %d from tcgetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
|
||||
// disable IGNBRK for mismatched speed tests; otherwise receive break
|
||||
// as \000 chars
|
||||
tty.c_iflag &= ~IGNBRK; // disable break processing
|
||||
tty.c_lflag = 0; // no signaling chars, no echo,
|
||||
// no canonical processing
|
||||
tty.c_oflag = 0; // no remapping, no delays
|
||||
tty.c_cc[VMIN] = 0; // read doesn't block
|
||||
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
|
||||
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||
// enable reading
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
#if defined(CRTSCTS)
|
||||
tty.c_cflag &= ~CRTSCTS;
|
||||
#endif
|
||||
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
|
||||
fprintf(stderr, "error %d from tcsetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Bmp::platform_buffer_write(const char *data, int size)
|
||||
{
|
||||
int s;
|
||||
|
||||
DEBUG_WIRE("%s\n", data);
|
||||
s = write(fd, data, size);
|
||||
if (s < 0) {
|
||||
fprintf(stdout, "Failed to write\n");
|
||||
throw std::runtime_error("bmp write failed");
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int Bmp::platform_buffer_read(char *data, int maxsize)
|
||||
{
|
||||
char *c;
|
||||
int s;
|
||||
int ret;
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
|
||||
c = data;
|
||||
tv.tv_sec = 0;
|
||||
|
||||
tv.tv_sec = 500 * 1000 ;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/* Look for start of response */
|
||||
do {
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
|
||||
ret = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
DEBUG_WARN("Failed on select\n");
|
||||
return(-3);
|
||||
}
|
||||
if(ret == 0) {
|
||||
DEBUG_WARN("Timeout on read RESP\n");
|
||||
return(-4);
|
||||
}
|
||||
|
||||
s = read(fd, c, 1);
|
||||
}
|
||||
while ((s > 0) && (*c != REMOTE_RESP));
|
||||
/* Now collect the response */
|
||||
do {
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
ret = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
DEBUG_WARN("Failed on select\n");
|
||||
exit(-4);
|
||||
}
|
||||
if(ret == 0) {
|
||||
DEBUG_WARN("Timeout on read\n");
|
||||
return(-5);
|
||||
}
|
||||
s = read(fd, c, 1);
|
||||
if (*c==REMOTE_EOM) {
|
||||
*c = 0;
|
||||
DEBUG_WIRE(" %s\n",data);
|
||||
return (c - data);
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
}while ((s >= 0) && ((c - data) < maxsize));
|
||||
DEBUG_WARN("Failed to read\n");
|
||||
return(-6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *Bmp::hexify(char *hex, const void *buf, size_t size)
|
||||
{
|
||||
char *tmp = hex;
|
||||
const uint8_t *b = (const uint8_t *)buf;
|
||||
|
||||
while (size--) {
|
||||
*tmp++ = hexdigits[*b >> 4];
|
||||
*tmp++ = hexdigits[*b++ & 0xF];
|
||||
}
|
||||
*tmp++ = 0;
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
uint8_t unhex_digit(char hex)
|
||||
{
|
||||
uint8_t tmp = hex - '0';
|
||||
if(tmp > 9)
|
||||
tmp -= 'A' - '0' - 10;
|
||||
if(tmp > 16)
|
||||
tmp -= 'a' - 'A';
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *Bmp::unhexify(void *buf, const char *hex, size_t size)
|
||||
{
|
||||
uint8_t *b = (uint8_t *)buf;
|
||||
while (size--) {
|
||||
*b = unhex_digit(*hex++) << 4;
|
||||
*b++ |= unhex_digit(*hex++);
|
||||
}
|
||||
return (char *)buf;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
* Copyright (C) 2021 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de
|
||||
*/
|
||||
|
||||
#ifndef SRC_BMP_HPP_
|
||||
#define SRC_BMP_HPP_
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "jtagInterface.hpp"
|
||||
|
||||
/*!
|
||||
* \file Bmp.hpp
|
||||
* \class Bmp
|
||||
* \brief concrete class between jtag implementation and blackmagic debug probe remote protocoll
|
||||
* \author Uwe Bonnes
|
||||
*/
|
||||
|
||||
class Bmp : public JtagInterface {
|
||||
public:
|
||||
Bmp(std::string dev,
|
||||
const std::string &serial, uint32_t clkHZ, bool verbose);
|
||||
~Bmp(void);
|
||||
int setClkFreq(uint32_t clkHZ) override;
|
||||
|
||||
/* TMS */
|
||||
int writeTMS(uint8_t *tms, int len, bool flush_buffer) override;
|
||||
/* TDI */
|
||||
int writeTDI(uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
|
||||
/* clk */
|
||||
int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override;
|
||||
int get_buffer_size() override { return 0;}
|
||||
bool isFull() override {return false;}
|
||||
int flush() override { return 0;};
|
||||
private:
|
||||
bool _verbose; /**< display more message */
|
||||
int fd;
|
||||
int set_interface_attribs(void);
|
||||
int platform_buffer_write(const char *data, int size);
|
||||
int platform_buffer_read(char *data, int maxsize);
|
||||
char *unhexify(void *buf, const char *hex, size_t size);
|
||||
char *hexify(char *hex, const void *buf, size_t size);
|
||||
void DEBUG_WARN(const char *format, ...);
|
||||
void DEBUG_WIRE(const char *format, ...);
|
||||
void DEBUG_PROBE(const char *format, ...);
|
||||
};
|
||||
#endif // SRC_BMP_HPP_
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* This file is part of the Black Magic Debug project.
|
||||
*
|
||||
* Copyright (C) 2019 Black Sphere Technologies Ltd.
|
||||
* Written by Dave Marples <dave@marples.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _REMOTE_
|
||||
#define _REMOTE_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Commands to remote end, and responses
|
||||
* =====================================
|
||||
*
|
||||
* All commands as sent as ASCII and begin with !, ending with #.
|
||||
* Parameters are hex digits and format is per command.
|
||||
*
|
||||
* !<CMD><PARAM>#
|
||||
* <CMD> - 2 digit ASCII value
|
||||
* <PARAM> - x digits (according to command) ASCII value
|
||||
*
|
||||
* So, for example;
|
||||
*
|
||||
* SI - swdptap_seq_in_parity
|
||||
* tt - Ticks
|
||||
* e.g. SI21 : Request input with parity, 33 ticks
|
||||
* resp: K<PARAM> - hex value returned.
|
||||
* resp: F<PARAM> - hex value returned, bad parity.
|
||||
* X<err> - error occured
|
||||
*
|
||||
* The whole protocol is defined in this header file. Parameters have
|
||||
* to be marshalled in remote.c, swdptap.c and jtagtap.c, so be
|
||||
* careful to ensure the parameter handling matches the protocol
|
||||
* definition when anything is changed.
|
||||
*/
|
||||
|
||||
/* Protocol error messages */
|
||||
#define REMOTE_ERROR_UNRECOGNISED 1
|
||||
#define REMOTE_ERROR_WRONGLEN 2
|
||||
|
||||
/* Start and end of message identifiers */
|
||||
#define REMOTE_SOM '!'
|
||||
#define REMOTE_EOM '#'
|
||||
#define REMOTE_RESP '&'
|
||||
|
||||
/* Generic protocol elements */
|
||||
#define REMOTE_START 'A'
|
||||
#define REMOTE_TDITDO_TMS 'D'
|
||||
#define REMOTE_TDITDO_NOTMS 'd'
|
||||
#define REMOTE_IOSEQ_TMS 'Q'
|
||||
#define REMOTE_IOSEQ_NOTMS 'q'
|
||||
#define REMOTE_IN_PAR 'I'
|
||||
#define REMOTE_JTAG_SHIFT_IR 'I'
|
||||
#define REMOTE_JTAG_SHIFT_DR 'i'
|
||||
#define REMOTE_JTAG_JTCK 'C'
|
||||
#define REMOTE_FREQ_SET 'F'
|
||||
#define REMOTE_FREQ_GET 'f'
|
||||
#define REMOTE_IN 'i'
|
||||
#define REMOTE_NEXT 'N'
|
||||
#define REMOTE_OUT_PAR 'O'
|
||||
#define REMOTE_OUT 'o'
|
||||
#define REMOTE_PWR_SET 'P'
|
||||
#define REMOTE_PWR_GET 'p'
|
||||
#define REMOTE_RESET 'R'
|
||||
#define REMOTE_INIT 'S'
|
||||
#define REMOTE_TMS 'T'
|
||||
#define REMOTE_VOLTAGE 'V'
|
||||
#define REMOTE_SRST_SET 'Z'
|
||||
#define REMOTE_SRST_GET 'z'
|
||||
#define REMOTE_ADD_JTAG_DEV 'J'
|
||||
|
||||
#define REMOTE_IOSEQ_FLAG_NONE 0
|
||||
#define REMOTE_IOSEQ_FLAG_IN 1
|
||||
#define REMOTE_IOSEQ_FLAG_OUT 2
|
||||
|
||||
#/* Protocol response options */
|
||||
#define REMOTE_RESP_OK 'K'
|
||||
#define REMOTE_RESP_PARERR 'P'
|
||||
#define REMOTE_RESP_ERR 'E'
|
||||
#define REMOTE_RESP_NOTSUP 'N'
|
||||
|
||||
/* High level protocol elements */
|
||||
#define REMOTE_HL_CHECK 'C'
|
||||
#define REMOTE_HL_PACKET 'H'
|
||||
#define REMOTE_DP_READ 'd'
|
||||
#define REMOTE_LOW_ACCESS 'L'
|
||||
#define REMOTE_AP_READ 'a'
|
||||
#define REMOTE_AP_WRITE 'A'
|
||||
#define REMOTE_AP_MEM_READ 'M'
|
||||
#define REMOTE_MEM_READ 'h'
|
||||
#define REMOTE_MEM_WRITE_SIZED 'H'
|
||||
#define REMOTE_AP_MEM_WRITE_SIZED 'm'
|
||||
|
||||
|
||||
/* Generic protocol elements */
|
||||
#define REMOTE_GEN_PACKET 'G'
|
||||
|
||||
#define REMOTE_START_STR (const char []){ '+', REMOTE_EOM, REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_START, REMOTE_EOM, 0 }
|
||||
#define REMOTE_VOLTAGE_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_VOLTAGE, REMOTE_EOM, 0 }
|
||||
#define REMOTE_SRST_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_SET, '%', 'c', REMOTE_EOM, 0 }
|
||||
#define REMOTE_SRST_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_GET, REMOTE_EOM, 0 }
|
||||
#define REMOTE_FREQ_SET_STR (const char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_FREQ_SET, '%', '0', '8', 'x', REMOTE_EOM, 0 }
|
||||
#define REMOTE_FREQ_GET_STR (const char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_FREQ_GET, REMOTE_EOM, 0 }
|
||||
#define REMOTE_PWR_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_SET, '%', 'c', REMOTE_EOM, 0 }
|
||||
#define REMOTE_PWR_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_GET, REMOTE_EOM, 0 }
|
||||
|
||||
/* SWDP protocol elements */
|
||||
#define REMOTE_SWDP_PACKET 'S'
|
||||
#define REMOTE_SWDP_INIT_STR (char []){ REMOTE_SOM, REMOTE_SWDP_PACKET, REMOTE_INIT, REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_SWDP_IN_PAR_STR (char []){ REMOTE_SOM, REMOTE_SWDP_PACKET, REMOTE_IN_PAR, \
|
||||
'%','0','2','x',REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_SWDP_IN_STR (char []){ REMOTE_SOM, REMOTE_SWDP_PACKET, REMOTE_IN, \
|
||||
'%','0','2','x',REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_SWDP_OUT_STR (char []){ REMOTE_SOM, REMOTE_SWDP_PACKET, REMOTE_OUT, \
|
||||
'%','0','2','x','%','x',REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_SWDP_OUT_PAR_STR (char []){ REMOTE_SOM, REMOTE_SWDP_PACKET, REMOTE_OUT_PAR, \
|
||||
'%','0','2','x','%','x',REMOTE_EOM, 0 }
|
||||
|
||||
/* JTAG protocol elements */
|
||||
#define REMOTE_JTAG_PACKET 'J'
|
||||
|
||||
#define REMOTE_JTAG_INIT_STR (char []){ '+',REMOTE_EOM, REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_INIT, REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_JTAG_RESET_STR (char []){ '+',REMOTE_EOM, REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_RESET, REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_JTAG_TMS_STR (const char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_TMS, \
|
||||
'%','0','2','x','%','x',REMOTE_EOM, 0 }
|
||||
|
||||
#define REMOTE_JTAG_IOSEQ_STR (const char []) {REMOTE_SOM, REMOTE_JTAG_PACKET,'%', 'c', '%', 'd', '%','0','4','x', 0}
|
||||
#define REMOTE_JTAG_JTCK_STR (const char []) {REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_JTAG_JTCK,'%', 'd', '%','0','8','x', REMOTE_EOM, 0}
|
||||
|
||||
#define REMOTE_JTAG_NEXT (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_NEXT, \
|
||||
'%','c','%','c',REMOTE_EOM, 0 }
|
||||
/* HL protocol elements */
|
||||
#define HEX '%', '0', '2', 'x'
|
||||
#define HEX_U32(x) '%', '0', '8', 'x'
|
||||
#define CHR(x) '%', 'c'
|
||||
|
||||
#define REMOTE_JTAG_SHIFT_IR_STR (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, \
|
||||
REMOTE_JTAG_SHIFT_IR, '%','0','2', 'x', HEX_U32(ir),REMOTE_EOM, 0 }
|
||||
|
||||
/* Flags (nibble), index(byte), ticks(16 bits) */
|
||||
#define REMOTE_JTAG_SHIFT_DR_STR (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, \
|
||||
REMOTE_JTAG_SHIFT_DR, '%', 'd', '%','0','2', 'x', '%', '0', '4', 'x', 0 }
|
||||
|
||||
#define REMOTE_JTAG_ADD_DEV_STR (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET,\
|
||||
REMOTE_ADD_JTAG_DEV, \
|
||||
'%','0','2','x', /* index */ \
|
||||
'%','0','2','x', /* dr_prescan */ \
|
||||
'%','0','2','x', /* dr_postscan */ \
|
||||
'%','0','2','x', /* ir_len */ \
|
||||
'%','0','2','x', /* ir_prescan */ \
|
||||
'%','0','2','x', /* ir_postscan */ \
|
||||
HEX_U32(current_ir), /* current_ir */ \
|
||||
REMOTE_EOM, 0}
|
||||
|
||||
#define REMOTE_HL_CHECK_STR (const char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_HL_CHECK, REMOTE_EOM, 0 }
|
||||
#define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \
|
||||
'%','0', '2', 'x', 'f', 'f', '%', '0', '4', 'x', REMOTE_EOM, 0 }
|
||||
#define REMOTE_LOW_ACCESS_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_LOW_ACCESS, \
|
||||
'%','0', '2', 'x', '%','0', '2', 'x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_READ, \
|
||||
'%','0', '2', 'x', '%','0','2','x', '%', '0', '4', 'x', REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_WRITE_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_WRITE, \
|
||||
'%','0', '2', 'x', '%','0','2','x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_READ, \
|
||||
'%','0', '2', 'x', '%','0','2','x',HEX_U32(csw), HEX_U32(address), HEX_U32(count), \
|
||||
REMOTE_EOM, 0 }
|
||||
#define REMOTE_AP_MEM_WRITE_SIZED_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_WRITE_SIZED, \
|
||||
'%','0', '2', 'x', '%', '0', '2', 'x', HEX_U32(csw), '%', '0', '2', 'x', HEX_U32(address), HEX_U32(count), 0}
|
||||
#define REMOTE_MEM_WRITE_SIZED_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_MEM_WRITE_SIZED, \
|
||||
'%','0', '2', 'x', '%','0','2','x', HEX_U32(address), HEX_U32(count), 0}
|
||||
|
||||
uint64_t remotehston(uint32_t limit, char *s);
|
||||
void remotePacketProcess(uint8_t i, char *packet);
|
||||
|
||||
#endif
|
||||
|
|
@ -27,6 +27,7 @@ enum communication_type {
|
|||
MODE_LIBGPIOD_BITBANG, /*! Bitbang gpio pins */
|
||||
MODE_JETSONNANO_BITBANG, /*! Bitbang gpio pins */
|
||||
MODE_REMOTEBITBANG, /*! Remote Bitbang mode */
|
||||
MODE_BMP, /*! BMP remote protocoll*/
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
@ -118,6 +119,7 @@ static std::map <std::string, cable_t> cable_list = {
|
|||
{"usb-blaster", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6001 )},
|
||||
{"usb-blasterII", CABLE_DEF(MODE_USBBLASTER, 0x09Fb, 0x6810 )},
|
||||
{"xvc-client", CABLE_DEF(MODE_XVC_CLIENT, 0x0000, 0x0000 )},
|
||||
{"bmp", CABLE_DEF(MODE_DFU() )},
|
||||
#ifdef ENABLE_LIBGPIOD
|
||||
{"libgpiod", CABLE_DEF(MODE_LIBGPIOD_BITBANG, 0, 0x0000 )},
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#ifdef ENABLE_XVC
|
||||
#include "xvc_client.hpp"
|
||||
#endif
|
||||
#include "bmp.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -151,6 +152,9 @@ void Jtag::init_internal(const cable_t &cable, const string &dev, const string &
|
|||
_jtag = new RemoteBitbang_client(ip_adr, port, _verbose);
|
||||
break;
|
||||
#endif
|
||||
case MODE_BMP:
|
||||
_jtag = new Bmp(dev, serial, clkHZ, _verbose);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Jtag: unknown cable type" << std::endl;
|
||||
throw std::exception();
|
||||
|
|
|
|||
Loading…
Reference in New Issue