Hi list. I'm new with opencd and have a lote of questions and
problems. Not with software, the problems are with my project. I was
developed a USB adapter to program a lm3s2776 trhow jtag in a board
designed by me.
The USB adapter just make the parallel signals from USB, I do this
with a USB - RS232 converter connected to microcontroller. All signals
are generated good. But I don't know the source of my problems.
When connect the target board and the usb adapter, run openocd (stable
version 0.4) I have this out:
Open On-Chip Debugger 0.4.0 (2011-04-12-08:49)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
parport port = 0x378
85 kHz
jtag_nsrst_delay: 100
jtag_ntrst_delay: 100
srst_only separate srst_gates_jtag srst_open_drain
Info : clock speed 84 kHz
Info : JTAG tap: lm3s2776.cpu tap/device found: 0x3ba00477 (mfg:
0x23b, part: 0xba00, ver: 0x3)
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Block read error address 0xe000ed00, count 0x1
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
Warn : Invalid ACK 0 in JTAG-DP transaction
I try changing the jtag clock (from 500 K to 50 K) and always same the
same output.
The script I'm using is:
openocd.cfg:
source [find parport.cfg]
source [find lm3s2776.cfg]
jtag_khz 85
jtag_nsrst_delay 100
jtag_ntrst_delay 100
reset_config srst_only separate
lm3s2776.cfg:
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME lm3s2776
}
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0xf
-expected-id $_CPUTAPID
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m3 -chain-position $_CHIPNAME.cpu
-variant lm3s
# I'm not shure about -work-area-size
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x2000
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME
parport.cfg:
interface parport
parport_port 0x378
parport_cable USBJTag
The parallelport was modify to work over USB connection. In the
attached file are the modified version of the parport.c. All
configuration of parallel port do nothing.
Some one can helpme?
Thank's a lot.
Sergio
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <jtag/interface.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "bitbang.h"
/*
Prototipos de funciones para establecer el acceso
al adaptador
*/
#define CMD_READ 3
#define READ_DELAY 50
void reset(int handler);
unsigned char readPort(int handler);
static __inline__ void writePort(unsigned char val, int handler);
int initPort(char * porName);
void releasePort(int handler);
void setRTS(unsigned char val, int handler);
void setDTR(unsigned char val, int handler);
/* Fin definiciones propias */
/* parallel port cable description
*/
struct cable {
char* name;
uint8_t TDO_MASK; /* status port bit containing current TDO value */
uint8_t TRST_MASK; /* data port bit for TRST */
uint8_t TMS_MASK; /* data port bit for TMS */
uint8_t TCK_MASK; /* data port bit for TCK */
uint8_t TDI_MASK; /* data port bit for TDI */
uint8_t SRST_MASK; /* data port bit for SRST */
uint8_t OUTPUT_INVERT; /* data port bits that should be inverted */
uint8_t INPUT_INVERT; /* status port that should be inverted */
uint8_t PORT_INIT; /* initialize data port with this value */
uint8_t PORT_EXIT; /* de-initialize data port with this value */
uint8_t LED_MASK; /* data port bit for LED */
};
static struct cable cables[] =
{
/* name tdo trst tms tck tdi srst o_inv i_inv init exit led */
{ "USBJTag", 0x80, 0x08, 0x20, 0x40, 0x10, 0x80, 0x80, 0x00, 0x00, 0x00, 0x04 }
};
/* configuration */
static char* parport_cable = NULL;
static uint16_t parport_port;
static bool parport_exit = 0;
static uint32_t parport_toggling_time_ns = 1000;
static int wait_states;
/* interface variables
*/
static struct cable* cable;
static uint8_t dataport_value = 0x0;
static int serialHandler;
static unsigned long dataport;
static unsigned long statusport;
static int parport_read(void)
{
int data = 0;
data = readPort(serialHandler);
if ((data ^ cable->INPUT_INVERT) & cable->TDO_MASK)
return 1;
else
return 0;
}
static __inline__ void parport_write_data(void)
{
uint8_t output;
output = dataport_value ^ cable->OUTPUT_INVERT;
writePort(output, serialHandler);
}
static void parport_write(int tck, int tms, int tdi)
{
int i = wait_states + 1;
if (tck)
dataport_value |= cable->TCK_MASK;
else
dataport_value &= ~cable->TCK_MASK;
if (tms)
dataport_value |= cable->TMS_MASK;
else
dataport_value &= ~cable->TMS_MASK;
if (tdi)
dataport_value |= cable->TDI_MASK;
else
dataport_value &= ~cable->TDI_MASK;
while (i-- > 0)
parport_write_data();
}
/* (1) assert or (0) deassert reset lines */
static void parport_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
if (trst == 0)
dataport_value |= cable->TRST_MASK;
else if (trst == 1)
dataport_value &= ~cable->TRST_MASK;
if (srst == 0)
dataport_value |= cable->SRST_MASK;
else if (srst == 1)
dataport_value &= ~cable->SRST_MASK;
parport_write_data();
}
/* turn LED on parport adapter on (1) or off (0) */
static void parport_led(int on)
{
if (on)
dataport_value |= cable->LED_MASK;
else
dataport_value &= ~cable->LED_MASK;
parport_write_data();
}
static int parport_speed(int speed)
{
wait_states = speed;
return ERROR_OK;
}
static int parport_khz(int khz, int* jtag_speed)
{
if (khz == 0) {
LOG_DEBUG("RCLK not supported");
return ERROR_FAIL;
}
*jtag_speed = 499999 / (khz * parport_toggling_time_ns);
return ERROR_OK;
}
static int parport_speed_div(int speed, int* khz)
{
uint32_t denominator = (speed + 1) * parport_toggling_time_ns;
*khz = (499999 + denominator) / denominator;
return ERROR_OK;
}
static struct bitbang_interface parport_bitbang = {
.read = &parport_read,
.write = &parport_write,
.reset = &parport_reset,
.blink = &parport_led,
};
static int parport_init(void)
{
struct cable *cur_cable;
cur_cable = cables;
if ((parport_cable == NULL) || (parport_cable[0] == 0))
{
parport_cable = "USBJTag";
LOG_WARNING("No parport cable specified, using default 'USBJTag'");
}
while (cur_cable->name)
{
if (strcmp(cur_cable->name, parport_cable) == 0)
{
cable = cur_cable;
break;
}
cur_cable++;
}
if (!cable)
{
LOG_ERROR("No matching cable found for %s", parport_cable);
return ERROR_JTAG_INIT_FAILED;
}
dataport_value = cable->PORT_INIT;
serialHandler = initPort("/dev/ttyUSB0");
reset(serialHandler);
usleep(1000);
parport_reset(0, 0);
parport_write(0, 0, 0);
parport_led(1);
bitbang_interface = &parport_bitbang;
wait_states = jtag_get_speed();
return ERROR_OK;
}
static int parport_quit(void)
{
parport_led(0);
if (parport_exit)
{
dataport_value = cable->PORT_EXIT;
parport_write_data();
}
if (parport_cable)
{
free(parport_cable);
parport_cable = NULL;
}
releasePort(serialHandler);
return ERROR_OK;
}
COMMAND_HANDLER(parport_handle_parport_port_command)
{
if (CMD_ARGC == 1)
{
/* only if the port wasn't overwritten by cmdline */
if (parport_port == 0)
{
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port);
}
else
{
LOG_ERROR("The parport port was already configured!");
return ERROR_FAIL;
}
}
command_print(CMD_CTX, "parport port = 0x%" PRIx16 "", parport_port);
return ERROR_OK;
}
COMMAND_HANDLER(parport_handle_parport_cable_command)
{
if (CMD_ARGC == 0)
return ERROR_OK;
/* only if the cable name wasn't overwritten by cmdline */
if (parport_cable == 0)
{
/* REVISIT first verify that it's listed in cables[] ... */
parport_cable = malloc(strlen(CMD_ARGV[0]) + sizeof(char));
strcpy(parport_cable, CMD_ARGV[0]);
}
/* REVISIT it's probably worth returning the current value ... */
return ERROR_OK;
}
COMMAND_HANDLER(parport_handle_write_on_exit_command)
{
if (CMD_ARGC != 1)
{
command_print(CMD_CTX, "usage: parport_write_on_exit <on | off>");
return ERROR_OK;
}
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], parport_exit);
return ERROR_OK;
}
COMMAND_HANDLER(parport_handle_parport_toggling_time_command)
{
if (CMD_ARGC == 1) {
uint32_t ns;
int retval = parse_u32(CMD_ARGV[0], &ns);
if (ERROR_OK != retval)
return retval;
if (ns == 0) {
LOG_ERROR("0 ns is not a valid parport toggling time");
return ERROR_FAIL;
}
parport_toggling_time_ns = ns;
wait_states = jtag_get_speed();
}
command_print(CMD_CTX, "parport toggling time = %" PRIu32 " ns",
parport_toggling_time_ns);
return ERROR_OK;
}
static const struct command_registration parport_command_handlers[] = {
{
.name = "parport_port",
.handler = parport_handle_parport_port_command,
.mode = COMMAND_CONFIG,
.help = "Display the address of the I/O port (e.g. 0x378) "
"or the number of the '/dev/parport' device used. "
"If a parameter is provided, first change that port.",
.usage = "[port_number]",
},
{
.name = "parport_cable",
.handler = parport_handle_parport_cable_command,
.mode = COMMAND_CONFIG,
.help = "Set the layout of the parallel port cable "
"used to connect to the target.",
/* REVISIT there's no way to list layouts we know ... */
.usage = "[layout]",
},
{
.name = "parport_write_on_exit",
.handler = parport_handle_write_on_exit_command,
.mode = COMMAND_CONFIG,
.help = "Configure the parallel driver to write "
"a known value to the parallel interface on exit.",
.usage = "('on'|'off')",
},
{
.name = "parport_toggling_time",
.handler = parport_handle_parport_toggling_time_command,
.mode = COMMAND_CONFIG,
.help = "Displays or assigns how many nanoseconds it "
"takes for the hardware to toggle TCK.",
.usage = "[nanoseconds]",
},
COMMAND_REGISTRATION_DONE
};
struct jtag_interface parport_interface = {
.name = "parport",
.commands = parport_command_handlers,
.init = parport_init,
.quit = parport_quit,
.khz = parport_khz,
.speed_div = parport_speed_div,
.speed = parport_speed,
.execute_queue = bitbang_execute_queue,
};
/*
*
Implementación de funciones propias
*
*/
void reset(int handler){
setDTR(0, handler);
setRTS(0, handler);
sleep(1);
setDTR(1, handler);
}
unsigned char readPort(int handler){
unsigned char delay;
unsigned char ready;
unsigned char ret=0;
unsigned char cmd;
// Primero enviamos la solicitud de escritura
cmd = CMD_READ;
// enviamos la petición de escritura
write(handler, &cmd, 1);
// esperamos la respuesta
ioctl(handler, FIONREAD, &ready);
delay = 0;
while((!ready) && (delay < READ_DELAY)){
usleep(500);
delay++;
ioctl(handler, FIONREAD, &ready);
}
// levantamos la respuesta
read(handler, &ret, 1);
if(!ready)
LOG_DEBUG("No se recibió ningún valor");
else
LOG_DEBUG("Recibido %02x", ret);
return ret;
}
static __inline__ void writePort(unsigned char val, int handler){
val = val & 0xFC;
write(handler, &val, 1);
}
int initPort(char * porName){
int handler;
// Estructura para la configuración del puerto serie
struct termios options;
handler = open(porName, O_RDWR | O_NOCTTY | O_NDELAY);
if (handler == -1){
//LOG_ERROR("cannot open device. check it exists and that user read and write rights are set. errno=%d", err);
perror("open_port: No se pudo abrir el puerto indicado");
}
else{
// que no espere por valores si al realizar una lectura no hay datos disponibles
fcntl(handler, F_SETFL, FNDELAY);
// comenzamos la configuración
// levantamos la configuración original
tcgetattr(handler, &options);
// establecemos el baudrate de entrada y salida a 115200
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
// habilitamos el receptor
options.c_cflag |= (CLOCAL | CREAD);
// Configuramos 8 bits, sin paridad 1 bit de stop
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Sin control por hardware
options.c_cflag &= ~CRTSCTS;
// ni por software
options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
// Raw mode
options.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
options.c_oflag &= ~OPOST;
// Establecemos los atributos de configuración
tcsetattr(handler, TCSANOW, &options);
reset(handler);
}
return (handler);
}
void releasePort(int handler){
close(handler);
}
void setRTS(unsigned char val, int handler){
int status;
ioctl(handler, TIOCMGET, &status);
if (val) {
status|=TIOCM_RTS;
}
else {
status&=~TIOCM_RTS;
}
ioctl(handler, TIOCMSET, &status);
}
void setDTR(unsigned char val, int handler){
int status;
ioctl(handler, TIOCMGET, &status);
if (val) {
status|=TIOCM_DTR;
}
else {
status&=~TIOCM_DTR;
}
ioctl(handler, TIOCMSET, &status);
}
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development