Showing posts with label isystem.connect. Show all posts
Showing posts with label isystem.connect. Show all posts

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



Sunday, April 8, 2012

LCD Type On Cheap STM32 Camera Board From eBay

I bought a camera board with 2.8 inch TFT LCD and STM32 on eBay for 50 bucks some time ago. The primary project was put aside after I lost my initial excitement and motivation. After almost a year I was organizing libraries from ST for STM32 for some other purposes. I came across GUI library and remembered that I have the board laying around and decided to test the GUI library.


STM32 camera board (SWD debugging; I rewired the uSD  soon after I bought it)
Circle on functional LCD at the end (original FW displayed the picture from camera)
LCD connection - it is a 37pin connector

Soon I discovered that there are no usable markings for the LCD. I got the schematic from the seller and the demo project sources which were zipped in password protected archive. Nothing found with Google had any LCD type information. I had no way to determine how to set up the communication with the LCD. I didn't decide to query the seller for the password due to his lag in replying - I waited a week to get the mentioned files when I bought the board.
I assumed that the design is based on a evaluation board from ST. There are drives in ST libraries for the LCDs that ST uses on their boards.
Luckily I still have the original firmware (binary file only) to see how the LCD is used. I have programmed it and set up my debugger (winIDEA - I use iSystem emulator) to break on access to registers for the port to which LCD was connected. Fortunately only one port is used for LCD (PORTB). After each RUN the application stopped on each IO port signal change and I could read the signals values.

Watchpoint breakpoints setup in winIDEA
Port registers display in winIDEA

To automate the process of running, waiting to stop and reading the value I wrote a Python script. It uses the exposed API called "isystem.connect" for controlling/interfacing the winIDEA.
Obtained values exposed the LCD initialization sequence from the ST library for SPFD5408.

Ptyhon script:
import isystem.connect as ic
from isystem.connect import IConnectDebug as ICDebug

    
def toHEX8(val):
  return '0x{0:02X}'.format(val)

def toDEC(val):
  return '{0: 3d}'.format(val)

class LCDInterafceValues:
  def __init__(self):
    self.data = 0
  def setNewValues(self, pinsValues):
    self.data = pinsValues
  def isnCS(self):
    return (self.data & (1<<12)) != 0
  def isRS(self):
    return (self.data & (1<<13)) != 0
  def isnWR(self):
    return (self.data & (1<<14)) != 0
  def isnRD(self):
    return (self.data & (1<<15)) != 0
  def getnCS(self):
    if (self.data & (1<<12)) != 0: return 1
    else: return 0
  def getRS(self):
    if (self.data & (1<<13)) != 0: return 1
    else: return 0
  def getnWR(self):
    if (self.data & (1<<14)) != 0: return 1
    else: return 0
  def getnRD(self):
    if (self.data & (1<<15)) != 0: return 1
    else: return 0
  def getData(self):
    return self.data & 0xFF
  def printHeader(self):
    print "CS  RS  RD  WR  data"
  def printLevels(self):
    if self.isnCS(): print "#  ",
    else: print "|  ",
      
    if self.isRS(): print "#  ",
    else: print "|  ",
  
    if self.isnRD(): print "#  ",
    else: print "|  ",
  
    if self.isnWR(): print "#  ",
    else: print "|  ",
      
    print toHEX8(self.getData()),
    print toDEC(self.getData())
    
cmgr = ic.ConnectionMgr()       # Create a connection manager
cmgr.connectMRU()               # Connect to the last used instance of winIDEA

debug = ic.CDebugFacade(cmgr)   # Create a debug object for the connected winIDEA 
debug.reset()                   # Reset CPU

pv = LCDInterafceValues()       # Create a value parser helper
pv.printHeader()

# Watchpoints have already been set in dialogs in winIDEA
# Just run until a watchpoint is hit, then read the IO levels  
while True:
  debug.run()                   # Run the CPU
  debug.waitUntilStopped()      # Do nothing while the CPU is running
  
  # Evaluate expression. Any C expression with firmware variables would be valid here.
  # '@' prefix tells winIDEA to evaluate (read from memory) a peripheral register.
  PortBPins = debug.evaluate(ICDebug.fMonitor , "@GPIOB_IDR").getInt()
  pv.setNewValues(PortBPins);   # Give the IO port value to helper
  pv.printLevels()              # Display values
 
 
Console output ( '#' means signal is HIGH and '|' that is LOW):
CS  RS  RD  WR  data
#   #   #   #   0x12  18
#   #   #   #   0x12  18
#   #   #   #   0x12  18
#   #   #   #   0x12  18
#   #   #   #   0x12  18
#   |   #   #   0x12  18
|   |   #   #   0x12  18
|   |   #   |   0x12  18
|   |   #   #   0x00   0
|   |   #   |   0x00   0
|   |   #   #   0xE3  227
#   |   #   #   0xE3  227
#   |   #   #   0xE3  227
#   #   #   #   0xE3  227
|   #   #   #   0xE3  227
|   #   #   |   0xE3  227
|   #   #   #   0x30  48
|   #   #   |   0x30  48
|   #   #   #   0x08   8
#   #   #   #   0x08   8
#   #   #   #   0x08   8
#   |   #   #   0x08   8
|   |   #   #   0x08   8
|   |   #   |   0x08   8
|   |   #   #   0x00   0
|   |   #   |   0x00   0
|   |   #   #   0xE7  231
#   |   #   #   0xE7  231
#   |   #   #   0xE7  231
#   #   #   #   0xE7  231
|   #   #   #   0xE7  231
|   #   #   |   0xE7  231
|   #   #   #   0x00   0
|   #   #   |   0x00   0
|   #   #   #   0x12  18
#   #   #   #   0x12  18
#   #   #   #   0x12  18
#   |   #   #   0x12  18
|   |   #   #   0x12  18
|   |   #   |   0x12  18
|   |   #   #   0x00   0
|   |   #   |   0x00   0
|   |   #   #   0xEF  239
#   |   #   #   0xEF  239
#   |   #   #   0xEF  239
#   #   #   #   0xEF  239
|   #   #   #   0xEF  239
|   #   #   |   0xEF  239
|   #   #   #   0x12  18
|   #   #   |   0x12  18
|   #   #   #   0x31  49
#   #   #   #   0x31  49
#   #   #   #   0x31  49