Spen,
Yes, I could see where you would have liked to have a target
specific method for reading a word from the DCC.
That would have avoided some code duplication.
Note 1:
I don't see any code that lets the the ST-Link interface write
16-bit words atomically. This requires that it one write just
the low byte when resetting the "busy" LSB of the DCC. If you
just try overwriting the whole 16-bit word, the target usually
slips in its next write before the relatively slow JTAG host
zeros out the high byte.
There probably should be a comment about this added to
stm32_stlink_dcc_read()
Note 2:
After further testing, I discovered that DCC commands output at
the top of the 'C' main() would appear to be missed by the host.
Adding a 150ms delay in the target "fixed" this, but I wasn't
pleased.
The real problem is that the DCC busy bit was coming up set, so
the host would misinterpret the zero in the high byte as a
TRACEMSG command, which would be followed by the trace number.
That would get the protocol out of sync.
A better fix is to have the target clear the DDC-link busy bit a
the top of its 'C' main().
Theoretically, this is still a race. Can one assume the target
will get to its 'C' main() before the host reads its DCC?
If not, it would seem that the "correct" approach might be for
the host to also clear the DCC busy bit on target reset.
What would be the best way to do that?
Despite all the above, it now seems to work well in practice.
I'd be very pleased if you'd merge this patch. Thank you.
- brent
P.S. I've attached an optimized version of dcc_stio I call
dccput (as it does not do any input)
Do with it what you will. Mainly, I just hoisted invariants out
of inner loops.
P.P.S. What does hla stand for?
Spencer Oliver wrote:
On 7 January 2013 08:52, Brent Roman <[email protected]> wrote:
Hi,
I was surprised to find that the ST-Link interface does not support DCC
target requests,
even for ARM Cortex-M3 CPUs supported via other JTAG interfaces.
The main reason being that i wanted to standardise routines for both
the std cortex and hla targets (was stlink target).
The term - it was on the list applies here.
The attached patch adds that ST-Link support for DCC target requests.
It is tested only on the STM32L-discovery board, but should work on all
STLINK Cortex-m3 targets.
Only the file stm32_stlink.c is modified.
Your patch will need rebasing as that file is now called hla_target.c
The code was (very obviously) derived from the existing Cortex-M3 support
for DCC.
It should handle tracepoints and the rest, but I have only tested console
output.
I realize that the procedure is to use Git for patch review, however, before
I invest more time and energy, I'd appreciate a quick thumbs up or down on
this.
Until the above happens i am happy to merge this patch, unless you can
find time to do the above that is.
Cheers
Spen
--
Brent Roman MBARI
Software Engineer Tel: (831) 775-1808
425 Clinton Street, Santa Cruz, CA 95062
mailto:[email protected] http://www.mbari.org/~brent
/***************************************************************************
* Copyright (C) 2008 by Dominic Rath *
* [email protected] *
* Copyright (C) 2008 by Spencer Oliver *
* [email protected] *
* revised by: [email protected] 1/6/13 *
* *
* 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. *
***************************************************************************/
#ifndef DCCPUT_H
#define DCCPUT_H
#include "stddef.h"
#include "types.h"
void DCCputU32(const u32 *val, size_t len);
void DCCputU16(const u16 *val, size_t len);
void DCCputByte(const u8 *val, size_t len);
void DCCputs(const char *msg);
void DCCputc(const int msg);
void DCCinit(void);
#endif /* DCCPUT_H */
/***************************************************************************
* Copyright (C) 2008 by Dominic Rath *
* [email protected] *
* Copyright (C) 2008 by Spencer Oliver *
* [email protected] *
* Copyright (C) 2008 by Frederik Kriewtz *
* [email protected] *
* revised by: [email protected] 1/6/13 *
* *
* 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. *
***************************************************************************/
#include "dccput.h"
#define TARGET_REQ_TRACEMSG 0x00
#define TARGET_REQ_DEBUGMSG_ASCII 0x01
#define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8))
#define TARGET_REQ_DEBUGCHAR 0x02
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)
/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel
* DCRDR[7:0] is used by target for status
* DCRDR[15:8] is used by target for write buffer
* DCRDR[23:16] is used for by host for status
* DCRDR[31:24] is used for by host for write buffer */
#define NVIC_DBG_DATA_R (*((volatile u16 *)0xE000EDF8))
#define BUSY 1
static inline void DCCwrite(u32 dcc_data)
{
/* wait for data ready */
while (NVIC_DBG_DATA_R & BUSY);
/* write our data and set write flag - tell host there is data*/
NVIC_DBG_DATA_R = (u16)(((dcc_data & 0xff) << 8) | BUSY);
/* wait for data ready */
while (NVIC_DBG_DATA_R & BUSY);
/* write our data and set write flag - tell host there is data*/
NVIC_DBG_DATA_R = (u16)((dcc_data & 0xff00) | BUSY);
/* wait for data ready */
while (NVIC_DBG_DATA_R & BUSY);
/* write our data and set write flag - tell host there is data*/
NVIC_DBG_DATA_R = (u16)(((dcc_data & 0xff0000) >> 8) | BUSY);
/* wait for data ready */
while (NVIC_DBG_DATA_R & BUSY);
/* write our data and set write flag - tell host there is data*/
NVIC_DBG_DATA_R = (u16)(((dcc_data & 0xff000000) >> 16) | BUSY);
}
void DCCinit(void)
{
NVIC_DBG_DATA_R = 0;
}
#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)
static inline void DCCwrite(u32 dcc_data)
{
u32 dcc_status;
do {
asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status));
} while (dcc_status & 0x2);
asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data));
}
void DCCinit(void) {}
#else
#error unsupported target
#endif
static void DCCwriteBytes(int type, const u8 *umsg, size_t len)
{
size_t extra;
u32 dcc_data;
DCCwrite(((u32)len << 16) | type);
extra = len & 3;
len >>= 2;
while (len) {
dcc_data = (u32)(umsg[0]) | (u32)(umsg[1])<<8
| (u32)(umsg[2])<<16 | (u32)(umsg[3])<<24;
DCCwrite(dcc_data);
umsg += 4;
--len;
}
if (extra) {
umsg+=extra;
dcc_data = 0;
do {
dcc_data <<= 8;
dcc_data |= *--umsg;
} while (--extra);
DCCwrite(dcc_data);
}
}
void DCCtracePoint(u32 number)
{
DCCwrite(TARGET_REQ_TRACEMSG | (number << 8));
}
void DCCputU32(const u32 *val, size_t len)
{
DCCwrite(TARGET_REQ_DEBUGMSG_HEXMSG(4) | (((u32)len & 0xffff) << 16));
while (len)
{
DCCwrite(*val++);
len--;
}
}
void DCCputU16(const u16 *val, size_t len)
{
size_t odd = len & 1;
DCCwrite(TARGET_REQ_DEBUGMSG_HEXMSG(2) | (((u32)len & 0xffff) << 16));
len >>= 1;
while (len)
{
DCCwrite(val[0] | ((u32)val[1] << 16));
val += 2;
--len;
}
if (odd)
DCCwrite(*val);
}
void DCCputByte(const u8 *val, size_t len)
{
DCCwriteBytes(TARGET_REQ_DEBUGMSG_HEXMSG(1), val, len);
}
void DCCputs(const char *msg)
{
size_t len;
for (len = 0; msg[len] && len < 65536; len++);
DCCwriteBytes(TARGET_REQ_DEBUGMSG_ASCII, (const u8 *)msg, len);
}
void DCCputc(const int msg)
{
DCCwrite(TARGET_REQ_DEBUGCHAR | ((u32)(u8)msg) << 16);
}
------------------------------------------------------------------------------
Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS
and more. Get SQL Server skills now (including 2012) with LearnDevNow -
200+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
SALE $99.99 this month only - learn more at:
http://p.sf.net/sfu/learnmore_122512
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel