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.

LAUNCHXL-CC26X2R1: SDK3.20 to SDK 5.10 Migration PIN Snag

Part Number: LAUNCHXL-CC26X2R1
Other Parts Discussed in Thread: SYSCONFIG

Hi Folks,

I am in the process of migrating two SDK3.20 projects to SDK5.10 and reviewing overall design and reliability. I have completed hardware bring up for one project, but have encountered a SPI interface problem in the other.

Overview

The SPI display operates correctly on the SDK3.20 binaries and debug but does not work on the SDK 5.10 verion of the same project. The problem most likely has to do with the transition from Pre-SysConfig to SysConfig, but after modifying the SysConfig the problem persists. I identified the source of the bug but am not really sure what changes are necessary.

Progress to Date

I compared the SPI configuration generated by SysConfig (SDK5.10/ti_drivers_config.c) against the original modified board file (SDK3.20/CC26X2R1_LAUNCHXL.c). I made changes to SysConfig to mirror the SDK5.10 SPI Config to match the SDK3.20 SPI Config.

SDK 3.20
CC26X2R1_LAUNCHXL.c 
SDK 5.10
SysConfig/ti_drivers_config.c
=============================== GPIO ===============================
GPIO_PinConfig gpioPinConfigs[] = {
DISPLAY_RESET | GPIO_DO_NOT_CONFIG,
POWER_ENABLE | GPIO_DO_NOT_CONFIG,
DISPLAY_BUSY | GPIO_DO_NOT_CONFIG,
...
//DISPLAY_SPI1_MOSI | GPIO_DO_NOT_CONFIG,
//DISPLAY_SPI1_CLK | GPIO_DO_NOT_CONFIG,
//DISPLAY_SPI1_CSN | GPIO_DO_NOT_CONFIG,
...
};
GPIO_PinConfig gpioPinConfigs[] = {
/* DISPLAY_RESET */
GPIOCC26XX_DIO_21 | GPIO_CFG_OUT_OD_NOPULL | GPIO_CFG_OUT_LOW,
/* DISPLAY_BUSY */
GPIOCC26XX_DIO_15 | GPIO_CFG_OUT_OD_PD | GPIO_CFG_OUT_LOW,
/* POWER_ENABLE */
GPIOCC26XX_DIO_07 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW,
};

=============================== PIN ===============================

const PIN_Config BoardGpioInitTable[] = {

...

POWER_ENABLE | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MIN,

...

DISPLAY_RESET | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
DISPLAY_SPI1_MOSI | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
DISPLAY_SPI1_CLK | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
DISPLAY_SPI1_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
DISPLAY_BUSY | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,

...

PIN_TERMINATE
};

const PIN_Config BoardGpioInitTable[CONFIG_PIN_COUNT + 1] = {
/* Parent Signal: DISPLAY_RESET GPIO Pin, (DIO21) */
CONFIG_PIN_6 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
/* Parent Signal: DISPLAY_BUSY GPIO Pin, (DIO15) */
CONFIG_PIN_7 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
/* Parent Signal: POWER_ENABLE GPIO Pin, (DIO7) */
CONFIG_PIN_4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MIN,
...
/* Parent Signal: SPI_EPD_DISPLAY SCLK, (DIO19) */
CONFIG_PIN_9 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
/* Parent Signal: SPI_EPD_DISPLAY MISO, (DIO0) */
CONFIG_PIN_10 | PIN_INPUT_EN | PIN_NOPULL | PIN_IRQ_DIS,
/* Parent Signal: SPI_EPD_DISPLAY MOSI, (DIO20) */
CONFIG_PIN_11 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
/* Parent Signal: SPI_EPD_DISPLAY SS, (DIO18) */
CONFIG_PIN_12 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MIN,
...

PIN_TERMINATE
};

=============================== SPI (U)DMA ===============================

const SPICC26X2DMA_HWAttrs spiCC26X2DMAHWAttrs[CC26X2R1_LAUNCHXL_SPICOUNT] = {

...

{
.baseAddr = SSI1_BASE,
.intNum = INT_SSI1_COMB,
.intPriority = ~0,
.swiPriority = 0,
.powerMngrId = PowerCC26XX_PERIPH_SSI1,
.defaultTxBufValue = 0xFF,
.rxChannelBitMask = 1<<UDMA_CHAN_SSI1_RX,
.txChannelBitMask = 1<<UDMA_CHAN_SSI1_TX,
.mosiPin = DISPLAY_SPI1_MOSI,
.misoPin = DISPLAY_SPI1_MISO,
.clkPin = DISPLAY_SPI1_CLK,
.csnPin = DISPLAY_SPI1_CSN,
.minDmaTransferSize = 10
},

...

};

const SPICC26X2DMA_HWAttrs spiCC26X2DMAHWAttrs[CONFIG_SPI_COUNT] = {

...

{
.baseAddr = SSI1_BASE,
.intNum = INT_SSI1_COMB,
.intPriority = (~0),
.swiPriority = 0,
.powerMngrId = PowerCC26XX_PERIPH_SSI1,
.defaultTxBufValue = ~0,
.rxChannelBitMask = 1<<UDMA_CHAN_SSI1_RX,
.txChannelBitMask = 1<<UDMA_CHAN_SSI1_TX,
.minDmaTransferSize = 10,
.mosiPin = IOID_20,
.misoPin = IOID_0,
.clkPin = IOID_19,
.csnPin = IOID_18
},

...

};

This appears to eliminate the SysConfig as the root of the problem since the configurations appear consistent.

I reviewed the relevant APIs to develop a method to debug the issue.

SPI_open

PIN_open
extern SPI_Handle SPI_open(uint_least8_t index, SPI_Params *params);

/*!
 *  @brief  Function to initialize the #SPI_Params struct to its defaults
 *
 *  @param  params      An pointer to #SPI_Params structure for
 *                      initialization
 *
 *  Defaults values are:
 *  * SPI_Params.transferMode        = #SPI_MODE_BLOCKING
 *  * SPI_Params.transferTimeout     = #SPI_WAIT_FOREVER
 *  * SPI_Params.transferCallbackFxn = NULL
 *  * SPI_Params.mode                = #SPI_MASTER
 *  * SPI_Params.bitRate             = 1000000 (Hz)
 *  * SPI_Params.dataSize            = 8 (bits)
 *  * SPI_Params.frameFormat         = #SPI_POL0_PHA0
 */
extern PIN_Handle PIN_open(PIN_State *state, const PIN_Config pinList[]);


/** @brief  Add pin to pin set for open PIN handle
 *
 *  If the requested pin is unallocated it will be added, else an error code
 *  will be returned.
 *  @param handle   handle retrieved through an earlier call to PIN_open().
 *  @param pinCfg   Pin ID/configuration for pin to add.
 *  @return Error code if unsuccessful, else PIN_SUCCESS
 */

This appears to be the only code that could affect the startup of the display, so I added debugging code to check the state of the PINs and SPI interface based on SPI_open and PIN_open.

#include <ti/drivers/SPI.h>
#include <ti/drivers/PWM.h>
#include "ti_drivers_config.h"

// Display Configuration
#include <ti/display/Display.h>
extern Display_Handle dispHost;

PIN_Handle h_display_pins = NULL;
PIN_State  display_pins_state;
const PIN_Config display_pins_table[] = {
    POWER_ENABLE     | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
    DISPLAY_RESET    | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
    DISPLAY_BUSY     | PIN_INPUT_EN | PIN_PULLDOWN,
    PIN_TERMINATE
};

void EPD_bus_init(void){
  h_display_pins = PIN_open(&display_pins_state, display_pins_table);
  if(h_display_pins != PIN_SUCCESS){
      Display_printf(dispHost, 0, 0, "Display PIN: Initialization Error\n");
  }
  EPD_DelayMs(5);
  pwm_init();
  SPI_init();
  SPI_Params_init(&SPIparams);
  SPIparams.transferMode        = SPI_MODE_BLOCKING;
  SPIparams.bitRate             = 4800000;
  SPIparams.mode                = SPI_MASTER;
  SPIparams.dataSize            = 9;
  SPIparams.frameFormat         = SPI_POL0_PHA0;
  SPIhandle = SPI_open(SPI_EPD_DISPLAY, &SPIparams);
  if(!SPIhandle) {
      Display_printf(dispHost, 0, 0, "Display SPI: Initialization Error\n");
  }
}
SPI_Handle      SPIhandle = NULL;
SPI_Params      SPIparams;

PWM_Handle hPWM = NULL;

When the display initialization code is called, the following messages appear:

Display: Display Init EVT
Display SPI: Initialization Error
Display PIN: Initialization Error

The h_display_pins variable returns after PIN_open:

When I changed the PIN table slightly to use names directly from ti_drivers_config.c as follows:

const PIN_Config display_pins_table[] = {
    CONFIG_PIN_4     | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
    CONFIG_PIN_6     | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
    CONFIG_PIN_7     | PIN_INPUT_EN | PIN_PULLDOWN,
    PIN_TERMINATE
};

the following messages appear:

Display: Display Init EVT
Display PIN: Initialization Error

This change seems strange to me because I would assume correcting the PIN table would improve the result of PIN_open. Instead, I observe that the SPI_open stops truning null. 

Question

  • How can I further investigate this problem?
  • Is there an API violation that makes the SDK3.20 method invalid for the SDK5.10?
  • Hi Folks,

    Minor update - I found a way to test did the problem that should be consistent across SDKs.

    As demonstrated in SDK3.20 where the code works, the configuration of the 7th pin is retrieved before and after applying the included pin-table.

    This results in the following expression states:

    In SDK5.10,


    This same code yields the following state:


    The bit that changes from 0 to 1 in SDK3.20 does not change in SDK5.10. Although I thought I eliminated the SysConfig/ti_drivers_config.c source as the root of the problem, I am not so sure anymore.

    Ideas are welcome Pray 

    Best,

    Ken

  • I was able to solve the problem by replacing all of the following names with the PIN_ID() address.
    POWER_ENABLE  --> PIN_ID(07)
    DISPLAY_RESET --> PIN_ID(21)
    DISPLAY_BUSY  --> PIN_ID(15)

    Problem Solved.

  • Hi Ken,

    I highly appreciate the thorough details and returning with the exact solution to your issue!

    Regards,
    Ryan

  • Thanks Ryan!

    The scientific method prevails! Specify criteria for success, perform initial investigation, identify variables, develop testing system, get results. Also several rinse and repeat cycles. I'm still learning the ropes for embedded development - while less can be more in system design, more is more when it comes to debugging and cooperation. 

    This bug had given me and a colleague the run around for several days. In the end, it really helped to stop, take a break, then look at the APIs more closely.

    I wasn't expecting to have to use PIN_ID since that is a pretty low-level function to get the register address when names for the same address should have been available through SysConfig. I don't see many future changes to the custom display driver, so I think PIN_ID() is a solid workaround solution.

    See ya around!

    Ken