This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

  • Answer Suggested

CC3200 using SWD / SWV / SWO / ITM

I am trying to get printf statements to work without using an external UART. I am following the instruction in the ARM manuals best I can and have defined and included the following:

//###################################################

#include <stdio.h>
#include "source/datatypes.h"


#define ITM_Port8(n) (*((volatile UINT8 *)(0xE0000000+4*n)))
#define ITM_Port16(n) (*((volatile UINT16 *)(0xE0000000+4*n)))
#define ITM_Port32(n) (*((volatile UINT32 *)(0xE0000000+4*n)))
#define DEMCR (*((volatile UINT32 *)(0xE000EDFC)))
#define TRCENA 0x01000000

struct __FILE { int handle; };
FILE __stdout;

/*************************************************************************
* Function Name: fputc()
**************************************************************************
* Summary: Overrides the fputc() library function to output to ITM port 0.
*
* Parameters: the character to be displayed
* a file handling structure (for stdout)
*
* Return: the input character.
*
*************************************************************************/
int fputc(int ch, FILE *f)
{
if (DEMCR & TRCENA) {
     while (ITM_Port32(0) == 0);
         ITM_Port8(0) = ch;
}
return ch;
}

//#####################################################

In my normal code I have include a nu,mber of

printf("At point #1/2/3/4");

 statements.

Under the debugger I can follow the code and the gets to 

_CODE_ACCESS int printf(const char *_format, ...)

routine which gets to my fputc()

above, goes through the routine and returns. No character can be seen in the debugger output window. I have tried configuring the probe in both JTAG and SWD mode (and moved the SOP jumper to [001] for 2 wire SWD.

In JTAG mode the process, no errors and also no printf() output.

In SWD mode is come with errors accessing the device.

What am I missing, can anybody help please??

For CC3200 related support functions, including debug enhanced "startup.c" as well as a range of embedded friendly support code, search Github for CC3200 support.
  • Hi,

    Did you get anywhere with this? I too was trying to get ITM data through SWO. I was using SWD debug, configured all Coresight trace components and enabled alteranative function on pad. I measured no change with scope on SWO pin when writing to ITM stimulus registers.

  • In reply to Primoz Alic1:

    Hi Primoz,

    Nope, have not yet solved the problem. After doing some research I believe the problem lies in that the TPIU and ITM must be initialized prior to the printf statements. Have found some examples for other processors/dev board and started modifying these, but not working yet. Have posted the current initialization code below.

    Other problems I have found (and hopefully solved) include the following lines in the cc3200.gel file:

    // GEL_MapAddStr(0x20000000, 0, 0x00040000, "R|W", 0); /* SRAM */
    GEL_MapAddStr(0x20000000, 0, 0x00030000, "R|W", 0); /* AMM: SRAM - 192k Pre Release Silicon*/

    ....

    GEL_MapAddStr(0xE0000000, 0, 0x00001000, "R|W", 0); /* AMM: ITM */
    GEL_MapAddStr(0xE0001000, 0, 0x00001000, "R|W", 0); /* AMM: DWT */
    GEL_MapAddStr(0xE0002000, 0, 0x00001000, "R|W", 0); /* AMM: FPB */
    GEL_MapAddStr(0xE000E000, 0, 0x00001000, "R|W", 0); /* AMM: CSB & DCB */
    // GEL_MapAddStr(0xE000E000, 0, 0x00001000, "R|W", 0); /* NVIC */
    GEL_MapAddStr(0xE0040000, 0, 0x00001000, "R|W", 0); /* AMM: TPIU */
    GEL_MapAddStr(0xE00FF000, 0, 0x00001000, "R", 0); /* AMM: ROM */

    The above lines make access to the memory mapped ITM, TPIU, FPB and related memory mapped peripherals available (I think)

    Lastly, I also got the CC3200 configured to Stellaris ICDI debug probe configured to SWD and changed the jumper to SOP0.

    Any TI engineer (or anyone else) that can help to identify what we are missing to make printf / ITM / timestamps working via the debug interface, it will be of HUGE value..

    Andre 

    PS: The register definition below is a looong list that I did not copy/paste here, it is a WIP that I am happy to happy to share if of value....

    //####################################################################

    void Debug_Init(void) {
    //TPIU Initialize
    CS_REG_WRITE(TPIU_ACPR, 0, 0x00000001); //Async Clock Prescaler Register
    CS_REG_WRITE(TPIU_SPPR, 0, TPIU_SPPR_SWOMAN); // Selected Pin Protocol Register = en. Manchester
    CS_REG_WRITE(TPIU_FFCR, 0, 0x00000000); //Formatter and Flush Control Register= bypass formatter
    // ITM initialize
    CS_REG_WRITE(ITM_LOCKACCS, 0, 0xC5ACCE55); //unlock access to ITM registers
    CS_REG_WRITE(ITM_TCR, 0, 0x00010009); //trace ID = 1, ITM and DTW enabled
    CS_REG_WRITE(ITM_TPR, 0, 0xF); //Trace Privilege =en. all tracing ports
    CS_REG_WRITE(ITM_TER, 0, 0xFFFFFFFF); //Trace Enable = all stimulus ports
    // DWT initalize
    CS_REG_WRITE(DWT_CTRL, 0, 0x00001005); // TODO: CHECK !!!
    }

    //###########################################################################

    #include <stdio.h>
    #include "coresight.h"
    //#include "source/datatypes.h"

    void delay(unsigned num_loops) {
    unsigned i;
    for (i=0; i<num_loops; i++);
    }

    void port_wait(ITM_port_t port) {
    delay(10);
    /* Wait while fifo ready */
    while (*port == 0);
    }

    /* Send a null terminated string to the port */
    void ITM_put_string(ITM_port_t port, const char* data) {
    unsigned datapos = 0;
    unsigned portpos = 0;
    unsigned portdata = 0;

    while('\0' != data[datapos]) {
    port_wait(port);
    /* Clear portdata */
    portdata = 0;
    /* Get the next 4 bytes of data */
    for (portpos=0; portpos<4; ++portpos) {
    portdata |= data[datapos] << (8*portpos);
    if ('\0' != data[datapos]) {
    ++datapos;
    }
    }
    /* Write the next 4 bytes of data */
    *port = portdata;
    }
    }

    /* Send a 32 bit value to the port */
    void ITM_put_32(ITM_port_t port, unsigned data) {
    port_wait(port);
    *port = data;
    }

    /* Send a 16 bit value to the port */
    void ITM_put_16(ITM_port_t port, unsigned short data) {
    /* Cast port for 16-bit data */
    volatile unsigned short* myport = (volatile unsigned short*)port;
    port_wait(port);
    *myport = data;
    }

    /* Send a 8 bit value to the port */
    void ITM_put_08(ITM_port_t port, unsigned char data) {
    /* Cast port for 8-bit data */
    volatile unsigned char* myport = (volatile unsigned char*)port;
    port_wait(port);
    *myport = data;
    }

    //################################################################

    For CC3200 related support functions, including debug enhanced "startup.c" as well as a range of embedded friendly support code, search Github for CC3200 support.
  • In reply to Andre Maree:

    In the example codes that I have seen, the standard procedure seems to be:

    #include "uart_if.h"

    InitTerm();

    then use the Report("Whatever you want to say") instead of the printf("Whatever you want to say") function that you are used to.

    Still, I'm not quite sure what it is that you're trying to do.

    Jackson

  • In reply to Andre Maree:

    8bit writes to ITM stimulus registers are good enough for me since I'm doing it in putchar(). 

    I'm counting on debugger to configure Coresight trace components (ITM, DWT and TPIU) as I've used it before on various targets. That only leaves SoC specific configuration which is port/pad/pin configuration.

    I'd like a confirmation that SWO actually works on CC3200.

    Until then I'm using one of debug pins not used in SWD mode as UART Tx.

  • In reply to Jackson Keating:

    @Jackson

    We'd like to get debug (trace) information out of CC3200 through SWO (Single Wire Output) debug pin. This is possible with standard CortexM core debug modules: ITM, DWT and TPIU. Debug IDEs usually know how to extract various debug data from SWO stream. TPIU (Trace Port Interface Unit) is in charge of formatting the trace data from DWT and ITM and outputting it to pins. DWT (Data Watchpoint and Trace) can provide limited amount of data trace. It is usually used for OS task profiling. ITM (Instrumentation Trace Macrocell) outputs instrumented debug info, e.g. printf().

    Read more about these in Coresight Components TRM.

  • In reply to Primoz Alic1:

    Hi Andre,

    I see you want to use the printf() function without the UART. Did you tried "semihosted" feature provided by IDE(s).

    On IAR here is how you can make this work.

    1. On project->options->General Options->Library Configuration make sure you have chosen "Semihosted"

    2. Once you are connect to the device. Go to view->Terminal I/O. Here is how the window look like

    Regarding SWO/SWV I will get back to you

    Thanks and Regards,

    Praveen

    ---------------------------------------------------------------------------------------------------------
    Please click the Verify Answer button on this post if it answers your question.
    ---------------------------------------------------------------------------------------------------------

  • In reply to Praveen Kumar N:

    HI Praveen, thanks for the response.

    Firstly, I am using CCS6 so the configuration options available are far fewer. Have configured semihosting, a single option in CCS and printf works "sometimes" but not reliably.

    What I would like to achieve is to use ITM to stream information of the tasks running via the SWD port.

    I would also like to be able to create a very memory & CPU efficient macro to display a 3 or 4 digit/character alphanumeric identifier, something like "AM07" or "FC03", at various places within the threads to track program flow, with absolute minimal impact on the execution timing of the application.

    For CC3200 related support functions, including debug enhanced "startup.c" as well as a range of embedded friendly support code, search Github for CC3200 support.
  • In reply to Praveen Kumar N:

    Which is the SWO pin and how to initialize it?

    I'm expecting SWO data on JTAG_TDO pin as it is usual with other devices.

    My initialization:

    PinModeSet(PIN_17, PIN_MODE_1); //swo
    PinConfigSet(PIN_17, PIN_STRENGTH_6MA, PIN_TYPE_STD);
    PinDirModeSet(PIN_17, PIN_DIR_MODE_HW);

    PIN17 is still flat on scope...

  • In reply to Primoz Alic1:

    Hi Andre, Primoz,

        On CC3200 the SWO pin doesn't come directly over JTAG_TDO pin, instead requires explicit pin muxing. Following pins support SWO output.

     

    Pin Mode
    45 13
    53 13
    50 13

    Since these are debug pins, these configurations are not exposed by pinmux utility. Use PinModeSet() API to set the pin mode. For eg.

    PinModeSet(PIN_53,PIN_MODE_13);

    These are the ITM configurations I tried

    //
    
    // Enable Trace
    
    //
    
    HWREG(0xE000EDFC) |= (1 << 24);
    
    //
    
    // Enable writ to ITM registers
    
    //
    
    HWREG(0xE0000FB0) = 0xC5ACCE55;
    
    //
    
    // Select UART(NRZ) mode
    
    //
    
    HWREG(0xE00400F0) = 0x00000002;
    
    //
    
    // Set the baud rate
    
    //
    
    HWREG(0xE0040010) = 80000000/BAUD_RATE - 1;
    
    //
    
    // Configure FIFO
    
    //
    
    HWREG(0xE0040304) = 0x100;
    
    //
    
    // Enable ITM
    
    //
    
    HWREG(0xE0000E80) = 0x10001;
    
    //
    
    // Enable stimulus port
    
    //
    
    HWREG(0xE0000E00) = 1;
    

     

     Let me know if this helps.

    Thansk and Regards,

    Praveen

    ---------------------------------------------------------------------------------------------------------
    Please click the Verify Answer button on this post if it answers your question.
    ---------------------------------------------------------------------------------------------------------

  • In reply to Praveen Kumar N:

    Thanks Praveen for the details.

    Am I then correct in saying that there is no way to get the SWO output via the existing FTDI based JTAG/SWD connection?

    From what I can read I agree with Primoz that the norm seems to be via pin 17, TDO, and that would make things much easier.

    In order to understand the debug functionality I have done soem homework and got the following working.

    #1."Console" type output using MAP_UARTCharPut() via second serial on FTDI to a separate terminal window in CCS or using Putty.

    #2 Standard printf  output does come out via the standard CSS console window showing {projname}:CIO. Tried to trace it down to the lowest level but the routines nest about 6 or more levels down, checking for all forms of redirection etc..

    What the printf output would indicate is some level of debug output on the 1st (JTAG/SWD) FTDI serial port.

    Now all we need is the lowest (processor overhead) level of direct register based access to the same serial output, and hopeful be able to get trace and timestamp info via the same existing connection.

    Am I hoping for too much....

    Help much appreciated

    Andre

    For CC3200 related support functions, including debug enhanced "startup.c" as well as a range of embedded friendly support code, search Github for CC3200 support.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.