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.

CC3200 using SWD / SWV / SWO / ITM

Other Parts Discussed in Thread: CC3200, UNIFLASH, MAX3232

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??

  • 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.

  • 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;
    }

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

  • 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

  • 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.

  • @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.

  • 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

  • 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.

  • 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...

  • 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

  • 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

  • Hi Praveen,

    I just tested PIN_53 and it works!

    I only needed to configure pin in my code: PinModeSet(PIN_53, PIN_MODE_13);. I can successfully record @4Mbit/s. Separate printf bursts that is, not constant recording. I didn't go higher as bit time is in the range of raise/fall time as seen on scope.

    Thanks! This answers my questions regarding trace!

  • Hi Andre,

    Not sure if I got your question correctly, but I think you want to get the whole trace info (printfs, timestamps, DWT etc) via the JTAG port itself with minimum processor overhead. Am I right ?

    FTDI based JTAG/SWD doesn't supports this. FTDI on CC3200 LP has two ports; first one is used as JTAG(4 wire) or SWD (2 wire and no SWO ), second one is used as UART port for UART A0.

    To get all the trace info via the JTAG you might require a different emulator like J-Link + IAR supports this.

    Thanks and Regards,

    Praveen

  • Thanks Praveen, but just a (hopefully) last question.

    I have a J-Link adapter and can try to see if I can get it to work, but would need to now which pins should me muxed.

    Based on your info on Pins 45, 50 & 53 above, I check in the TRM but did not see any pin config info referencing SWO and/or SWO.

    To get full SWD/SWO/SWV functionality via the J8-J11 jumper pins, what would the HWREG and/or PinXXXXXX instructions be....

    Thanks

    Andre

    BTW, the CC3200 sofar is AWESOME. my next challenge is to get CoAP and then a rules engine working.

  • Hi Andre,

    You can't bring out SWV on any of J8-J11. Here is how I have connected my J-Link ( SWV on Pin 50)

    JLink LP
    1 P1.1 (VCC)
    7 J9 (SWDIO)
    9 J8 (SWDCK)
    13 P3.10 (SWO)
    20 P2.1 (GND)

    In the code, you need to mux out SWV on Pin 50 by invoking PinModeSet(PIN_50,PIN_MODE_13);

    And this is how I re-implemented my Message function in uart_if.h

    void
    Message(const char *str)
    {

        if(str != NULL)
        {
            while(*str!='\0')
            {
                while(HWREG(0xE0000000) == 0)
                {

                }
                HWREG(0xE0000000) = *str++;
            }
        }

    }

     

    From IAR GUI,

    1. Go to Project->Options->Debugger->Driver select J-Link/J-Trace from the drop down.
    2. Go to J-Link/J-Trace->Connection->Interface choose ‘SWD’
    3. Connect to the target using ‘Download and Debug’ option
    4. Go to J-Link->SWO Trace Window Settings choose the required trace options.
    5. Go to J-Link->SWO Configuration->ITM Stimulus Ports Enable the required ports and redirection to I/O Terminal and/or log file
    6. Under the clock setup set the CPU clock (80 for cc3200).
    7.  Go to J-Link->SWO Trace to open the trace window.
    8. Run the program. Observe the output on View->I/O Terminal and SWO Trace window.

    Also pls note in this case, since you are using the GUI, you should not do the ITM configuration (from my previous post ) inside your code. The GUI will take care of doing this for you base on the option(s) you select.

    Let me know if this helps.

    Thanks and Regards,

    Praveen

  • In SWD mode, I can use JLink to debug cc3200 LP when JLink's 13 pin not connected. Just connect 1, 7, 9, 20 like yours. Thanks.

    I also want to know howto use JLink to program Serial Flash. Should I must use Uniflash tool to program Flash? If this, I must add a UART circuit (like MAX3232)?

  • we have had some luck using the FTDI USB to 'TTL' (3.3v)  cable for uniflash in the CC3200.

    I too would like to program flash from IAR but can't find a bootloader in any of the IAR directories for this chip.

  • Hi Praveen,

    I am afraid I have reached the point where I will have to give this up as impossible, at least for now. I have been able to achieve a lot to get a development environment based on Linux (Ubuntu 14.04) Eclipse CDT (Luna) to the point of a perfect compile, but the last load / run / debug step just avoids me.

    I have tried the JLink EDU/  JLinkServer option, connected all as per your sketch, but cannot get the debug config reliable.

    I have tried the GDBServer / OpenOCD (v8 & v9 beta) with the FTDI drivers combination, but again no luck.

    The catch in EVERYTHING it seems lies in the total lack of proper support for a Linux based CC3200 dev environment. Out of desperation I even looked at commercial compiler options ie EWARM (Win only)  and CodeSourcery (Linux but no CC3200) etc but no luck


    Since we have to make a decision on the road forward with the CC3200 it will be appreciated if we can have some clear feedback on TI plans for proper official support of the Linux / Eclipse / GDB / OpenOCD dev environment.
    Please make my day/week/month with some good news.

    Andre

  • Hi Praveen,

    Based on the silence from TI guess I should assume "no news means no GOOD news" as far as support for a Linux dev environment for the CC3200 is concerned?

    Really really a sad situation.

    Andre

  • It is doable. Will TI provide out of the box solution is another thing. Meanwhile, you can do it yourself: http://searchingforbit.blogspot.si/2014/07/cc3200-launchpad-with-external-debugger.html. Scroll to the part titled "Programming SPI flash without Uniflash through debug port". There is additional info in the comments.