Friday, July 25, 2014

CC3200 LaunchPad with external debugger and ARM GCC in Eclipse

Hot stuff! I got the board and read most of the the documentation, examples and APIs. It's time for debugging now. Since I don't like bulky SDKs that come for each eval board I tend to extract what I need from them (installing to virtual machine) and use external debugger. Modifications to connect external debugger are depicted below. No HW changes are needed on this one. TI made it all configurable with jumpers. There are 2 changes made:
  • SOP pins are configured to enable SWD (Single Wire Debug).
  • Debug lines are disconnected from on board FTDI debugger. External debugger is connected to freed debug pins via 3 lines SWDIO(TMS), SWDTCK(TCK) and GND. Let's not get into why 3 lines are needed for Single Wire Debug :).
I stopped boot in endless loop after connecting to it. I made simple while(1) empty loop project. Downloaded it to beginning of the RAM (0x20000000) and it worked.
I'm still not sure about clock settings. It doesn't seem that any PLL needs initializing...
[UPDATE]
I did sample project without any PLL code and it worked.

Also I didn't get SWO (Single Wire Output) to generate any output from ITM (Instrumentation Trace Macrocell). I know ITM was configured properly because it worked on some other devices. That only leaves IO configuration which I did with enabling GPIO3CLKEN clock, configuring corresponding GPIO_PAD_CONFIG_24 and set pin as output by setting GPIOA3[0]. Scope didn't show anything on TDO pin when writing ITM stimulus registers. Did anyone manage to get trace output ?
[UPDATE]
I added following code to initialize SWO pin without success:
PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK | PRCM_DSLP_MODE_CLK);
PinModeSet(PIN_17, PIN_MODE_1);
PinConfigSet(PIN_17, PIN_STRENGTH_6MA, PIN_TYPE_STD);
PinDirModeSet(PIN_17, PIN_DIR_MODE_HW);
It works! Apparently TDO is not the pin to get SWO out. Pins 45, 53 and 50 are according to CC3200 forum. Anyway, connecting iTag to 53 and adding code below did the trick.
PinModeSet(PIN_53, PIN_MODE_13);


CC3200-LAUNCHXL + iTAG

[UPDATE]
Created Eclipse C projects for CC3200 libs are available in repository. Short note for building: download CC3200 SDK separately (or extract from CCS installation). Library folders contain RefreshFiles.bat script invoked with CC3200 path to copy needed files to project folder.

While playing with integrated HTTP server I got frustrated with constant terminal to Uniflash tool UART switching. I decided to use UART Tx pin multiplexed with JTAG, which was not used since I'm using SWD.
To utilize it I added FTDI MM232R USB to serial module. I only connected CC3200 Tx to MM232R Rx for printf() tracing. Unconnected pin on LAUNCHPAD debug pinhead (J11) could be used for sending serial data to CC3200.
Code for UART initialization:
#define PRCM_UART_TERM PRCM_UARTA1
#define PIN_TERM_TX PIN_16
#define PIN_TERM_TX_MODE PIN_MODE_2
#define PIN_TERM_RX PIN_17
#define PIN_TERM_RX_MODE PIN_MODE_2
#define UART_TERM UARTA1_BASE
#define PRCM_UART_TERM PRCM_UARTA1

PRCMPeripheralClkEnable(PRCM_UART_TERM, PRCM_RUN_MODE_CLK);
PinTypeUART(PIN_TERM_TX, PIN_TERM_TX_MODE);
UARTConfigSetExpClk(UART_TERM,
                    MAP_PRCMPeripheralClockGet(PRCM_UART_TERM),
                    115200,
                    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

and code for sending single character:
UARTCharPut(UART_TERM, ch);

CC3200-LAUNCHXL + iTAG + MM232R

CC3200-LAUNCHXL to MM232R closeup

Soon after I realized I can capture serial data with iTAG debugger since SWD leaves pins for capturing SWO and iTAG can be configured to dump UART data from that pin to terminal window.
CC3200-LAUNCHXL + iTAG with UART capturing

CC3200-LAUNCHXL + iTAG with UART capturing (iTAG closeup)

CC3200-LAUNCHXL + iTAG with UART capturing (LAUNCHPAD closeup)

Programming SPI flash without Uniflash through debug port

With setup above updating the SPI flash content still requires disconnecting the debug session, switching SOP jumper to 'FLASH' position and resetting the board to program files with TI Uniflash tool.

For development purposes I wrote small monitor application to run on CC3200 and Python script controlling the execution of the monitor through debugger to write files to SPI flash, e.g. write file data to CC3200 RAM and trigger function calling SimpleLink lib to write the data to file. Scripting is supported by winIDEA, IDE used with iTAG debugger and iSYSTEM.Connect API. My intention was to first format the flash and then program all files in specified folder. It turned out that formatting is not supported by library (only Uniflash tool). As workaround first SPI flash must be erased on low (SPI) level, then formatted with Uniflash tool and all data from flash read to be later used as "empty" image. This is done once. SPI access is provided in the script. Later on every update of the files the script erases the flash, programs "empty" image to it and then calls SimpleLink lib to create and write files. See script for more details.

Recording ITM printf() messages on SWO

Tested on pin 53 as mentioned in update above. Don't get confused by the photo below. I'm using white wire for SWO. SWO is configured by debugger to output at 4Mbits/second. CPU speed and SWO prescaler settings in winIDEA must be configured for this. Following equation applies: BAUD = CPUclk/(SWOprcs + 1) -> 80MHz/(19 + 1) = 4MHz.

White wire connected from pin 53 configured as SWO to TDO input on iTag

4M BAUD configured in winIDEA



4 comments:

  1. Replies
    1. You're welcome... It's always good to see own work appreciated!

      Delete
  2. Awesome project!.. Then, is it possible to flash binary to CC3200 without Uniflash?

    ReplyDelete
    Replies
    1. Yes, it is possible to program files to SPI FLASH without Uniflash tool from TI.
      One needs piece of code running on CC (usually called "monitor") which knows how to write to SPI FLASH (through CC API) and software on PC to send file names and data in some agreed way to monitor.
      Now, the easiest way to do this is with debugger since you can use it to write monitor to RAM, run it and then write chunks of data in RAM next to it in a way monitor understands it. Monitor then picks it up and programs FLASH by any means needed.
      But one needs to use a debugger that offers external access to it. I use iSYSTEM debuggers with rich API to control them. It could also be done through GDB. Top level script that I wrote has debugger interface abstracted in few calls which could be replaced for other debugger (or GDB).
      Note that this solution is completely custom and only uses TI's libraries for monitor. Nothing from Uniflash is reused.
      Also, described procedure is the usual way of programming any kind of memories connected to CPU.

      Delete