DCC or debug communication channel is a quick way to get debug output from a program running on a target device to the JTAG host device. Unfortunately I found that the cortex-m3 doesn’t exactly have a DCC.
What it does have however is a general purpose data register (DCRDR) that gets used by the debugger for reading/writing registers, etc, etc, and while there is no specification from ARM as to how to use it to accomplish something like DCC, it is possible and there’s already basic support for it in OpenOCD.
I ran into problems, however, getting all of my characters output. It looks to me as if OpenOCD has a clever way of making the most out of the 32bit DCC register that makes use of all of the bits instead of just the lower 8 which is needed for basic single character DCC output. For cortex-m3/DCRDR, it is necessary to use at least one bit for signalling between the target / host, so the OpenOCD code attempts to read 4 consecutive writes to build up a 32bit value. One day, I may fully understand the 32bit format for the data and want to use it, but I’d like to have the simple single character output as well, so I made the following change to cortex_m3.c in the function cortex_m3_handle_target_request:
cortex_m3_dcc_read(swjdp, &data, &ctrl);
/* check if we have single char data */
if (ctrl & (1 << 1))
{
uint32_t request;
/* during this poll cycle read as much as we can from target */
while (ctrl & (1<<1))
{
request = data;
target_request(target, request);
cortex_m3_dcc_read(swjdp, &data, &ctrl);
}
}
else if (ctrl & (1 << 0))
Then I’m using this code on the stm32:
volatile uint32_t *DCRDR = 0xe000edf8;
void DCC_write_byte(char cbyte)
{
static uint32_t waitCount = 0;
/* wait for host to read & clear value or timeout */
while (((*DCRDR)&0x1)&&(++waitCount<100000))
{
asm("nop");
}
/* only reset the timeout if the value was read,
otherwise next time will immediately timeout (no host connected) */
if (((*DCRDR)&0x1)==0)
waitCount=0;
*DCRDR=(cbyte<<8)|3;
}
And this command to the rebuilt OpenOCD:
/usr/local/bin/openocd -d0 -f /usr/local/share/openocd/scripts/interface/vsllink-swd.cfg -f /usr/local/share/openocd/scripts/target/stm32vl.cfg -c init -c targets -c "target_request debugmsgs charmsg"
I don’t plan on submitting this to OpenOCD at this time since I’m using the version built from a script in the previous post, anxiously awaiting SWD support in a future release.
#1 by Bingo on February 5, 2011 - 6:04 pm
Nice one Tim 🙂
Btw: I Just added a working maple bootloader to the Versaloon thread.
Makes fw update much easier … (Well a little easier)
And now i can begin to work on a full JTAG on the STM8 , as i can disable JTAG in Versaloon , and use the pins for “Target Jtag” , and still erase the full chip or just update fw. By going into bootloader mode , where JTAG isn’t disabled.
/Bingo
#2 by tim on February 8, 2011 - 10:09 pm
I just updated both of my stm32-discovery boards to use the maple bootloader. It’s nice to be able to remove the SWD wires from the ST-Link side of the board. I may have to get one of these stm8 discovery boards, if you manage to get the full JTAG working.
#3 by Spencer Oliver on August 16, 2011 - 5:11 am
If you look in the openocd src archive under contrib/libdcc you will see a pre written lib for simple dcc comms.
Also note that openocd also supports the dcc format used by the codesoucery toolchain – they call it hosted mode.