icdi: add TI icdi interface
This is the new proprietary interface replacing the older FTDI based adapters. It is currently fitted to the ek-lm4f232 and Stellaris LaunchPad. Change-Id: I794ad79e31ff61ec8e9f49530aca9308025c0b60 Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/922 Tested-by: jenkins__archive__
parent
c7a6f065d2
commit
adb8ec32dc
2
README
2
README
|
@ -275,6 +275,8 @@ options may be available there:
|
||||||
|
|
||||||
--enable-stlink Enable building support for the ST-Link JTAG
|
--enable-stlink Enable building support for the ST-Link JTAG
|
||||||
Programmer
|
Programmer
|
||||||
|
--enable-ti-icdi Enable building support for the TI/Stellaris ICDI
|
||||||
|
JTAG Programmer
|
||||||
|
|
||||||
--enable-osbdm Enable building support for the OSBDM (JTAG only)
|
--enable-osbdm Enable building support for the OSBDM (JTAG only)
|
||||||
Programmer
|
Programmer
|
||||||
|
|
18
configure.ac
18
configure.ac
|
@ -477,7 +477,11 @@ AC_ARG_ENABLE([buspirate],
|
||||||
|
|
||||||
AC_ARG_ENABLE([stlink],
|
AC_ARG_ENABLE([stlink],
|
||||||
AS_HELP_STRING([--enable-stlink], [Enable building support for the ST-Link JTAG Programmer]),
|
AS_HELP_STRING([--enable-stlink], [Enable building support for the ST-Link JTAG Programmer]),
|
||||||
[build_hladapter=$enableval], [build_hladapter=no])
|
[build_hladapter_stlink=$enableval], [build_hladapter_stlink=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([ti-icdi],
|
||||||
|
AS_HELP_STRING([--enable-ti-icdi], [Enable building support for the TI ICDI JTAG Programmer]),
|
||||||
|
[build_hladapter_icdi=$enableval], [build_hladapter_icdi=no])
|
||||||
|
|
||||||
AC_ARG_ENABLE([osbdm],
|
AC_ARG_ENABLE([osbdm],
|
||||||
AS_HELP_STRING([--enable-osbdm], [Enable building support for the OSBDM (JTAG only) Programmer]),
|
AS_HELP_STRING([--enable-osbdm], [Enable building support for the OSBDM (JTAG only) Programmer]),
|
||||||
|
@ -790,10 +794,10 @@ else
|
||||||
AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])
|
AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $build_hladapter = yes; then
|
if test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes; then
|
||||||
AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the ST-Link JTAG driver.])
|
AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the High Level JTAG driver.])
|
||||||
else
|
else
|
||||||
AC_DEFINE([BUILD_HLADAPTER], [0], [0 if you don't want the ST-Link JTAG driver.])
|
AC_DEFINE([BUILD_HLADAPTER], [0], [0 if you don't want the High Level JTAG driver.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $build_osbdm = yes; then
|
if test $build_osbdm = yes; then
|
||||||
|
@ -1142,8 +1146,8 @@ fi
|
||||||
|
|
||||||
# Check for libusb1 ported drivers.
|
# Check for libusb1 ported drivers.
|
||||||
build_usb_ng=no
|
build_usb_ng=no
|
||||||
if test $build_jlink = yes -o $build_hladapter = yes -o $build_osbdm = yes -o \
|
if test $build_jlink = yes -o $build_hladapter_stlink = yes -o $build_osbdm = yes -o \
|
||||||
$build_opendous = yes -o $build_ftdi = yes
|
$build_opendous = yes -o $build_ftdi = yes -o $build_hladapter_icdi = yes
|
||||||
then
|
then
|
||||||
build_usb_ng=yes
|
build_usb_ng=yes
|
||||||
fi
|
fi
|
||||||
|
@ -1192,7 +1196,7 @@ AM_CONDITIONAL([ULINK], [test $build_ulink = yes])
|
||||||
AM_CONDITIONAL([ARMJTAGEW], [test $build_armjtagew = yes])
|
AM_CONDITIONAL([ARMJTAGEW], [test $build_armjtagew = yes])
|
||||||
AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes])
|
AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes])
|
||||||
AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes])
|
AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes])
|
||||||
AM_CONDITIONAL([HLADAPTER], [test $build_hladapter = yes])
|
AM_CONDITIONAL([HLADAPTER], [test $build_hladapter_stlink = yes -o $build_hladapter_icdi = yes])
|
||||||
AM_CONDITIONAL([OSBDM], [test $build_osbdm = yes])
|
AM_CONDITIONAL([OSBDM], [test $build_osbdm = yes])
|
||||||
AM_CONDITIONAL([OPENDOUS], [test $build_opendous = yes])
|
AM_CONDITIONAL([OPENDOUS], [test $build_opendous = yes])
|
||||||
AM_CONDITIONAL([SYSFSGPIO], [test $build_sysfsgpio = yes])
|
AM_CONDITIONAL([SYSFSGPIO], [test $build_sysfsgpio = yes])
|
||||||
|
|
|
@ -49,12 +49,15 @@ ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002c", MODE="664", GROUP="plugdev"
|
||||||
# Hitex STM32-PerformanceStick
|
# Hitex STM32-PerformanceStick
|
||||||
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="664", GROUP="plugdev"
|
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="664", GROUP="plugdev"
|
||||||
|
|
||||||
# TI/Luminary Stellaris Evaluation Board (several)
|
# TI/Luminary Stellaris Evaluation Board FTDI (several)
|
||||||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="664", GROUP="plugdev"
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="664", GROUP="plugdev"
|
||||||
|
|
||||||
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
|
# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board
|
||||||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="664", GROUP="plugdev"
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="664", GROUP="plugdev"
|
||||||
|
|
||||||
|
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
|
||||||
|
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="664", GROUP="plugdev"
|
||||||
|
|
||||||
# Xverve Signalyzer Tool (DT-USB-ST)
|
# Xverve Signalyzer Tool (DT-USB-ST)
|
||||||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="664", GROUP="plugdev"
|
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="664", GROUP="plugdev"
|
||||||
|
|
||||||
|
|
|
@ -370,3 +370,30 @@ void bit_copy_discard(struct bit_copy_queue *q)
|
||||||
free(qe);
|
free(qe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int unhexify(char *bin, const char *hex, int count)
|
||||||
|
{
|
||||||
|
int i, tmp;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (sscanf(hex + (2 * i), "%02x", &tmp) != 1)
|
||||||
|
return i;
|
||||||
|
bin[i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hexify(char *hex, const char *bin, int count, int out_maxlen)
|
||||||
|
{
|
||||||
|
int i, cmd_len = 0;
|
||||||
|
|
||||||
|
/* May use a length, or a null-terminated string as input. */
|
||||||
|
if (count == 0)
|
||||||
|
count = strlen(bin);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i]);
|
||||||
|
|
||||||
|
return cmd_len;
|
||||||
|
}
|
||||||
|
|
|
@ -156,4 +156,9 @@ int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset,
|
||||||
void bit_copy_execute(struct bit_copy_queue *q);
|
void bit_copy_execute(struct bit_copy_queue *q);
|
||||||
void bit_copy_discard(struct bit_copy_queue *q);
|
void bit_copy_discard(struct bit_copy_queue *q);
|
||||||
|
|
||||||
|
/* functions to convert to/from hex encoded buffer
|
||||||
|
* used in ti-icdi driver and gdb server */
|
||||||
|
int unhexify(char *bin, const char *hex, int count);
|
||||||
|
int hexify(char *hex, const char *bin, int count, int out_maxlen);
|
||||||
|
|
||||||
#endif /* BINARYBUFFER_H */
|
#endif /* BINARYBUFFER_H */
|
||||||
|
|
|
@ -100,6 +100,7 @@ DRIVERFILES += remote_bitbang.c
|
||||||
endif
|
endif
|
||||||
if HLADAPTER
|
if HLADAPTER
|
||||||
DRIVERFILES += stlink_usb.c
|
DRIVERFILES += stlink_usb.c
|
||||||
|
DRIVERFILES += ti_icdi_usb.c
|
||||||
endif
|
endif
|
||||||
if OSBDM
|
if OSBDM
|
||||||
DRIVERFILES += osbdm.c
|
DRIVERFILES += osbdm.c
|
||||||
|
|
|
@ -0,0 +1,730 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2012 by Spencer Oliver *
|
||||||
|
* spen@spen-soft.co.uk *
|
||||||
|
* *
|
||||||
|
* 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 2 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, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* project specific includes */
|
||||||
|
#include <helper/binarybuffer.h>
|
||||||
|
#include <jtag/interface.h>
|
||||||
|
#include <jtag/hla/hla_layout.h>
|
||||||
|
#include <jtag/hla/hla_transport.h>
|
||||||
|
#include <jtag/hla/hla_interface.h>
|
||||||
|
#include <target/target.h>
|
||||||
|
|
||||||
|
#include <target/cortex_m.h>
|
||||||
|
|
||||||
|
#include <libusb-1.0/libusb.h>
|
||||||
|
|
||||||
|
#define ICDI_WRITE_ENDPOINT 0x02
|
||||||
|
#define ICDI_READ_ENDPOINT 0x83
|
||||||
|
|
||||||
|
#define ICDI_WRITE_TIMEOUT 1000
|
||||||
|
#define ICDI_READ_TIMEOUT 1000
|
||||||
|
#define ICDI_PACKET_SIZE 2048
|
||||||
|
|
||||||
|
#define PACKET_START "$"
|
||||||
|
#define PACKET_END "#"
|
||||||
|
|
||||||
|
struct icdi_usb_handle_s {
|
||||||
|
libusb_context *usb_ctx;
|
||||||
|
libusb_device_handle *usb_dev;
|
||||||
|
|
||||||
|
char *read_buffer;
|
||||||
|
char *write_buffer;
|
||||||
|
int max_packet;
|
||||||
|
int read_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int icdi_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer);
|
||||||
|
static int icdi_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer);
|
||||||
|
|
||||||
|
static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)
|
||||||
|
{
|
||||||
|
int input_index, output_index;
|
||||||
|
|
||||||
|
output_index = 0;
|
||||||
|
|
||||||
|
for (input_index = 0; input_index < len; input_index++) {
|
||||||
|
|
||||||
|
char b = buffer[input_index];
|
||||||
|
|
||||||
|
if (b == '$' || b == '#' || b == '}' || b == '*') {
|
||||||
|
/* These must be escaped. */
|
||||||
|
if (output_index + 2 > out_maxlen)
|
||||||
|
break;
|
||||||
|
out_buf[output_index++] = '}';
|
||||||
|
out_buf[output_index++] = b ^ 0x20;
|
||||||
|
} else {
|
||||||
|
if (output_index + 1 > out_maxlen)
|
||||||
|
break;
|
||||||
|
out_buf[output_index++] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = input_index;
|
||||||
|
return output_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)
|
||||||
|
{
|
||||||
|
int input_index, output_index;
|
||||||
|
int escaped;
|
||||||
|
|
||||||
|
output_index = 0;
|
||||||
|
escaped = 0;
|
||||||
|
|
||||||
|
for (input_index = 0; input_index < len; input_index++) {
|
||||||
|
|
||||||
|
char b = buffer[input_index];
|
||||||
|
|
||||||
|
if (output_index + 1 > out_maxlen)
|
||||||
|
LOG_ERROR("Received too much data from the target.");
|
||||||
|
|
||||||
|
if (escaped) {
|
||||||
|
out_buf[output_index++] = b ^ 0x20;
|
||||||
|
escaped = 0;
|
||||||
|
} else if (b == '}')
|
||||||
|
escaped = 1;
|
||||||
|
else
|
||||||
|
out_buf[output_index++] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (escaped)
|
||||||
|
LOG_ERROR("Unmatched escape character in target response.");
|
||||||
|
|
||||||
|
return output_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_send_packet(void *handle, int len)
|
||||||
|
{
|
||||||
|
unsigned char cksum = 0;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
int result, retry = 0;
|
||||||
|
int transferred = 0;
|
||||||
|
|
||||||
|
assert(handle != NULL);
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
/* check we have a large enough buffer for checksum "#00" */
|
||||||
|
if (len + 3 > h->max_packet) {
|
||||||
|
LOG_ERROR("packet buffer too small");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate checksum - offset start of packet */
|
||||||
|
for (int i = 1; i < len; i++)
|
||||||
|
cksum += h->write_buffer[i];
|
||||||
|
|
||||||
|
len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
|
||||||
|
|
||||||
|
#ifdef _DEBUG_USB_COMMS_
|
||||||
|
char buffer[50];
|
||||||
|
char ch = h->write_buffer[1];
|
||||||
|
if (ch == 'x' || ch == 'X')
|
||||||
|
LOG_DEBUG("writing packet: <binary>");
|
||||||
|
else {
|
||||||
|
memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
|
||||||
|
buffer[len] = 0;
|
||||||
|
LOG_DEBUG("writing packet: %s", buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
result = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len,
|
||||||
|
&transferred, ICDI_WRITE_TIMEOUT);
|
||||||
|
if (result != 0 || transferred != len) {
|
||||||
|
LOG_DEBUG("Error TX Data %d", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check that the client got the message ok, or shall we resend */
|
||||||
|
result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet,
|
||||||
|
&transferred, ICDI_READ_TIMEOUT);
|
||||||
|
if (result != 0 || transferred < 1) {
|
||||||
|
LOG_DEBUG("Error RX Data %d", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG_USB_COMMS_
|
||||||
|
LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (h->read_buffer[0] == '-') {
|
||||||
|
LOG_DEBUG("Resending packet %d", ++retry);
|
||||||
|
} else {
|
||||||
|
if (h->read_buffer[0] != '+')
|
||||||
|
LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retry == 3) {
|
||||||
|
LOG_DEBUG("maximum nack retries attempted");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retry = 0;
|
||||||
|
h->read_count = transferred;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
/* read reply from icdi */
|
||||||
|
result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,
|
||||||
|
h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);
|
||||||
|
|
||||||
|
#ifdef _DEBUG_USB_COMMS_
|
||||||
|
LOG_DEBUG("received data: count %d", transferred);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check for errors but retry for timeout */
|
||||||
|
if (result != 0) {
|
||||||
|
|
||||||
|
if (result == LIBUSB_ERROR_TIMEOUT) {
|
||||||
|
LOG_DEBUG("Error RX timeout %d", result);
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Error RX Data %d", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h->read_count += transferred;
|
||||||
|
|
||||||
|
/* we need to make sure we have a full packet, including checksum */
|
||||||
|
if (h->read_count > 5) {
|
||||||
|
|
||||||
|
/* check that we have received an packet delimiter
|
||||||
|
* we do not validate the checksum
|
||||||
|
* reply should contain $...#AA - so we check for # */
|
||||||
|
if (h->read_buffer[h->read_count - 3] == '#')
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retry++ == 3) {
|
||||||
|
LOG_DEBUG("maximum data retries attempted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_send_cmd(void *handle, const char *cmd)
|
||||||
|
{
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd);
|
||||||
|
return icdi_send_packet(handle, cmd_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_send_remote_cmd(void *handle, const char *data)
|
||||||
|
{
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
|
||||||
|
cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len);
|
||||||
|
|
||||||
|
return icdi_send_packet(handle, cmd_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_get_cmd_result(void *handle)
|
||||||
|
{
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
int offset = 0;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
assert(handle != NULL);
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ch = h->read_buffer[offset++];
|
||||||
|
if (offset > h->read_count)
|
||||||
|
return ERROR_FAIL;
|
||||||
|
} while (ch != '$');
|
||||||
|
|
||||||
|
if (memcmp("OK", h->read_buffer + offset, 2) == 0)
|
||||||
|
return ERROR_OK;
|
||||||
|
|
||||||
|
if (h->read_buffer[offset] == 'E') {
|
||||||
|
/* get error code */
|
||||||
|
char result;
|
||||||
|
if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
|
||||||
|
return ERROR_FAIL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for now we assume everything else is ok */
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_idcode(void *handle, uint32_t *idcode)
|
||||||
|
{
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
return icdi_usb_write_mem32(handle, addr, 1, (uint8_t *)&val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum target_state icdi_usb_state(void *handle)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
uint32_t dhcsr;
|
||||||
|
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
result = icdi_usb_read_mem32(h, DCB_DHCSR, 1, (uint8_t *)&dhcsr);
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return TARGET_UNKNOWN;
|
||||||
|
|
||||||
|
if (dhcsr & S_HALT)
|
||||||
|
return TARGET_HALTED;
|
||||||
|
|
||||||
|
return TARGET_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_version(void *handle)
|
||||||
|
{
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
char version[20];
|
||||||
|
|
||||||
|
/* get info about icdi */
|
||||||
|
int result = icdi_send_remote_cmd(handle, "version");
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (h->read_count < 8) {
|
||||||
|
LOG_ERROR("Invalid Reply Received");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert reply */
|
||||||
|
if (unhexify(version, h->read_buffer + 2, 4) != 4) {
|
||||||
|
LOG_WARNING("unable to get ICDI version");
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* null terminate and print info */
|
||||||
|
version[4] = 0;
|
||||||
|
|
||||||
|
LOG_INFO("ICDI Firmware version: %s", version);
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_query(void *handle)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
result = icdi_send_cmd(handle, "qSupported");
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("query supported failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from this we can get the max packet supported */
|
||||||
|
|
||||||
|
/* query packet buffer size */
|
||||||
|
char *offset = strstr(h->read_buffer, "PacketSize");
|
||||||
|
if (offset) {
|
||||||
|
char *separator;
|
||||||
|
int max_packet;
|
||||||
|
|
||||||
|
max_packet = strtoul(offset + 11, &separator, 16);
|
||||||
|
if (!max_packet)
|
||||||
|
LOG_ERROR("invalid max packet, using defaults");
|
||||||
|
else
|
||||||
|
h->max_packet = max_packet;
|
||||||
|
LOG_DEBUG("max packet supported : %" PRIu32 " bytes", h->max_packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* if required re allocate packet buffer */
|
||||||
|
if (h->max_packet != ICDI_PACKET_SIZE) {
|
||||||
|
h->read_buffer = realloc(h->read_buffer, h->max_packet);
|
||||||
|
h->write_buffer = realloc(h->write_buffer, h->max_packet);
|
||||||
|
if (h->read_buffer == 0 || h->write_buffer == 0) {
|
||||||
|
LOG_ERROR("unable to reallocate memory");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set extended mode */
|
||||||
|
result = icdi_send_cmd(handle, "!");
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("unable to enable extended mode: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_reset(void *handle)
|
||||||
|
{
|
||||||
|
/* we do this in hla_target.c */
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_assert_srst(void *handle, int srst)
|
||||||
|
{
|
||||||
|
/* TODO not supported yet */
|
||||||
|
return ERROR_COMMAND_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_run(void *handle)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* resume target at current address */
|
||||||
|
result = icdi_send_cmd(handle, "c");
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("continue failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_halt(void *handle)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* this query halts the target ?? */
|
||||||
|
result = icdi_send_cmd(handle, "?");
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("halt failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_step(void *handle)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* step target at current address */
|
||||||
|
result = icdi_send_cmd(handle, "s");
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("step failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_read_regs(void *handle)
|
||||||
|
{
|
||||||
|
/* currently unsupported */
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
char cmd[10];
|
||||||
|
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "p%x", num);
|
||||||
|
result = icdi_send_cmd(handle, cmd);
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("register read failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert result */
|
||||||
|
if (unhexify((char *)val, h->read_buffer + 2, 4) != 4) {
|
||||||
|
LOG_ERROR("failed to convert result");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_write_reg(void *handle, int num, uint32_t val)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
char cmd[20];
|
||||||
|
|
||||||
|
int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num);
|
||||||
|
hexify(cmd + cmd_len, (char *)&val, 4, sizeof(cmd));
|
||||||
|
|
||||||
|
result = icdi_send_cmd(handle, cmd);
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("register write failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
char cmd[20];
|
||||||
|
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "x%x,%x", addr, len);
|
||||||
|
result = icdi_send_cmd(handle, cmd);
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("memory read failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unescape input */
|
||||||
|
int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);
|
||||||
|
if (read_len != (int)len) {
|
||||||
|
LOG_ERROR("read more bytes than expected: actual 0x%" PRIx32 " expected 0x%" PRIx32, read_len, len);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%x,%x:", addr, len);
|
||||||
|
|
||||||
|
int out_len;
|
||||||
|
cmd_len += remote_escape_output((char *)buffer, len, h->write_buffer + cmd_len,
|
||||||
|
&out_len, h->max_packet - cmd_len);
|
||||||
|
|
||||||
|
if (out_len < (int)len) {
|
||||||
|
/* for now issue a error as we have no way of allocating a larger buffer */
|
||||||
|
LOG_ERROR("memory buffer too small: requires 0x%" PRIx32 " actual 0x%" PRIx32, out_len, len);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = icdi_send_packet(handle, cmd_len);
|
||||||
|
if (result != ERROR_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
result = icdi_get_cmd_result(handle);
|
||||||
|
if (result != ERROR_OK) {
|
||||||
|
LOG_ERROR("memory write failed: 0x%x", result);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer)
|
||||||
|
{
|
||||||
|
return icdi_usb_read_mem(handle, addr, len, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer)
|
||||||
|
{
|
||||||
|
return icdi_usb_write_mem(handle, addr, len, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer)
|
||||||
|
{
|
||||||
|
return icdi_usb_read_mem(handle, addr, len * 4, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer)
|
||||||
|
{
|
||||||
|
return icdi_usb_write_mem(handle, addr, len * 4, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_close(void *handle)
|
||||||
|
{
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
|
||||||
|
h = (struct icdi_usb_handle_s *)handle;
|
||||||
|
|
||||||
|
if (h->usb_dev)
|
||||||
|
libusb_close(h->usb_dev);
|
||||||
|
|
||||||
|
if (h->usb_ctx)
|
||||||
|
libusb_exit(h->usb_ctx);
|
||||||
|
|
||||||
|
if (h->read_buffer)
|
||||||
|
free(h->read_buffer);
|
||||||
|
|
||||||
|
if (h->write_buffer)
|
||||||
|
free(h->write_buffer);
|
||||||
|
|
||||||
|
free(handle);
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
struct icdi_usb_handle_s *h;
|
||||||
|
|
||||||
|
LOG_DEBUG("icdi_usb_open");
|
||||||
|
|
||||||
|
h = calloc(1, sizeof(struct icdi_usb_handle_s));
|
||||||
|
|
||||||
|
if (h == 0) {
|
||||||
|
LOG_ERROR("unable to allocate memory");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
|
||||||
|
param->vid, param->pid);
|
||||||
|
|
||||||
|
if (libusb_init(&h->usb_ctx) != 0) {
|
||||||
|
LOG_ERROR("libusb init failed");
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid);
|
||||||
|
if (!h->usb_dev) {
|
||||||
|
LOG_ERROR("open failed");
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libusb_claim_interface(h->usb_dev, 2)) {
|
||||||
|
LOG_DEBUG("claim interface failed");
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if mode is supported */
|
||||||
|
retval = ERROR_OK;
|
||||||
|
|
||||||
|
switch (param->transport) {
|
||||||
|
#if 0
|
||||||
|
/* TODO place holder as swd is not currently supported */
|
||||||
|
case HL_TRANSPORT_SWD:
|
||||||
|
#endif
|
||||||
|
case HL_TRANSPORT_JTAG:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
retval = ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
LOG_ERROR("mode (transport) not supported by device");
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate buffer */
|
||||||
|
h->read_buffer = malloc(ICDI_PACKET_SIZE);
|
||||||
|
h->write_buffer = malloc(ICDI_PACKET_SIZE);
|
||||||
|
h->max_packet = ICDI_PACKET_SIZE;
|
||||||
|
|
||||||
|
if (h->read_buffer == 0 || h->write_buffer == 0) {
|
||||||
|
LOG_DEBUG("malloc failed");
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query icdi version etc */
|
||||||
|
retval = icdi_usb_version(h);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
goto error_open;
|
||||||
|
|
||||||
|
/* query icdi support */
|
||||||
|
retval = icdi_usb_query(h);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
goto error_open;
|
||||||
|
|
||||||
|
*fd = h;
|
||||||
|
|
||||||
|
/* set the max target read/write buffer in bytes
|
||||||
|
* as we are using gdb binary packets to transfer memory we have to
|
||||||
|
* reserve half the buffer for any possible escape chars plus
|
||||||
|
* at least 64 bytes for the gdb packet header */
|
||||||
|
param->max_buffer = (((h->max_packet - 64) / 4) * 4) / 2;
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
|
||||||
|
error_open:
|
||||||
|
icdi_usb_close(h);
|
||||||
|
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hl_layout_api_s icdi_usb_layout_api = {
|
||||||
|
.open = icdi_usb_open,
|
||||||
|
.close = icdi_usb_close,
|
||||||
|
.idcode = icdi_usb_idcode,
|
||||||
|
.state = icdi_usb_state,
|
||||||
|
.reset = icdi_usb_reset,
|
||||||
|
.assert_srst = icdi_usb_assert_srst,
|
||||||
|
.run = icdi_usb_run,
|
||||||
|
.halt = icdi_usb_halt,
|
||||||
|
.step = icdi_usb_step,
|
||||||
|
.read_regs = icdi_usb_read_regs,
|
||||||
|
.read_reg = icdi_usb_read_reg,
|
||||||
|
.write_reg = icdi_usb_write_reg,
|
||||||
|
.read_mem8 = icdi_usb_read_mem8,
|
||||||
|
.write_mem8 = icdi_usb_write_mem8,
|
||||||
|
.read_mem32 = icdi_usb_read_mem32,
|
||||||
|
.write_mem32 = icdi_usb_write_mem32,
|
||||||
|
.write_debug_reg = icdi_usb_write_debug_reg
|
||||||
|
};
|
|
@ -71,6 +71,12 @@ static const struct hl_layout hl_layouts[] = {
|
||||||
.close = hl_layout_close,
|
.close = hl_layout_close,
|
||||||
.api = &stlink_usb_layout_api,
|
.api = &stlink_usb_layout_api,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "ti-icdi",
|
||||||
|
.open = hl_layout_open,
|
||||||
|
.close = hl_layout_close,
|
||||||
|
.api = &icdi_usb_layout_api,
|
||||||
|
},
|
||||||
{.name = NULL, /* END OF TABLE */ },
|
{.name = NULL, /* END OF TABLE */ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct hl_interface_param_s;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
extern struct hl_layout_api_s stlink_usb_layout_api;
|
extern struct hl_layout_api_s stlink_usb_layout_api;
|
||||||
|
extern struct hl_layout_api_s icdi_usb_layout_api;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
struct hl_layout_api_s {
|
struct hl_layout_api_s {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#
|
||||||
|
# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits
|
||||||
|
#
|
||||||
|
# http://www.ti.com/tool/ek-lm4f120xl
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: using the bundled ICDI interface is optional!
|
||||||
|
# This interface is not ftdi based as previous boards were
|
||||||
|
#
|
||||||
|
source [find interface/ti-icdi.cfg]
|
||||||
|
|
||||||
|
set WORKAREASIZE 0x8000
|
||||||
|
set CHIPNAME lm4f120h5qr
|
||||||
|
source [find target/stellaris_icdi.cfg]
|
|
@ -4,10 +4,12 @@
|
||||||
# http://www.ti.com/tool/ek-lm4f232
|
# http://www.ti.com/tool/ek-lm4f232
|
||||||
#
|
#
|
||||||
|
|
||||||
# NOTE: using the bundled FT2232 JTAG/SWD/SWO interface is optional!
|
#
|
||||||
# so is using in JTAG mode, as done here.
|
# NOTE: using the bundled ICDI interface is optional!
|
||||||
source [find interface/luminary-icdi.cfg]
|
# This interface is not ftdi based as previous boards were
|
||||||
|
#
|
||||||
|
source [find interface/ti-icdi.cfg]
|
||||||
|
|
||||||
set WORKAREASIZE 0x8000
|
set WORKAREASIZE 0x8000
|
||||||
set CHIPNAME lm4f23x
|
set CHIPNAME lm4f23x
|
||||||
source [find target/stellaris.cfg]
|
source [find target/stellaris_icdi.cfg]
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#
|
||||||
|
# TI Stellaris In-Circuit Debug Interface (ICDI) Board
|
||||||
|
#
|
||||||
|
# This is the propriety ICDI interface used on newer boards such as
|
||||||
|
# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232
|
||||||
|
# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad
|
||||||
|
# http://www.ti.com/tool/ek-lm4f232
|
||||||
|
#
|
||||||
|
|
||||||
|
interface hla
|
||||||
|
hla_layout ti-icdi
|
||||||
|
hla_vid_pid 0x1cbe 0x00fd
|
||||||
|
|
||||||
|
# unused but set to disable warnings
|
||||||
|
adapter_khz 1000
|
|
@ -0,0 +1,34 @@
|
||||||
|
#
|
||||||
|
# lm3s icdi pseudo target
|
||||||
|
#
|
||||||
|
|
||||||
|
if { [info exists CHIPNAME] } {
|
||||||
|
set _CHIPNAME $CHIPNAME
|
||||||
|
} else {
|
||||||
|
set _CHIPNAME lm3s
|
||||||
|
}
|
||||||
|
|
||||||
|
# Work-area is a space in RAM used for flash programming
|
||||||
|
# By default use 16kB
|
||||||
|
if { [info exists WORKAREASIZE] } {
|
||||||
|
set _WORKAREASIZE $WORKAREASIZE
|
||||||
|
} else {
|
||||||
|
set _WORKAREASIZE 0x4000
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# possible value are hla_jtag
|
||||||
|
# currently swd is not supported
|
||||||
|
#
|
||||||
|
transport select hla_jtag
|
||||||
|
|
||||||
|
# do not check id as icdi currently does not support it
|
||||||
|
hla newtap $_CHIPNAME cpu -expected-id 0
|
||||||
|
|
||||||
|
set _TARGETNAME $_CHIPNAME.cpu
|
||||||
|
target create $_TARGETNAME hla_target -chain-position $_TARGETNAME
|
||||||
|
|
||||||
|
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
||||||
|
|
||||||
|
# flash configuration ... autodetects sizes, autoprobed
|
||||||
|
flash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME
|
Loading…
Reference in New Issue