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.

CC1312R: SPI and UART TI driver does not configure GPIOs any more since SDK 5.30

Part Number: CC1312R
Other Parts Discussed in Thread: SYSCONFIG

Hi,

When upgrading to SDK 6.10 we noticed that some TI drivers does not configure GPIOs any longer like they used to do. So to make it work our application first has to configure the GPIOs required using GPIO_setConfig before calling the TI driver open function, otherwise it won’t work.

This is true for the following drivers at least

  • /source/ti/drivers/spi/SPICC26X2DMA.c
  • /source/ti/drivers/uart/UARTCC26XX.c
  • /source/ti/drivers/nvs/NVSSPI25X.c    (since it is using the SPI driver)

Other TI drivers in SDK 6.10 does handle GPIO configuration using GPIO_setConfig themselves like I2C, PWM so it seems a bit inconsistent between the different drivers. In earlier SDKs (before SDK 5.30) the SPI and UART driver also took care of the GPIO configuration, so this change was introduced in SDK 5.30.

Is this an intentional change in the TI driver behaviour?

BR,

Johannes Kjällquist

  • Do you see this issue only when porting from a previous SDK or also for the examples in the newest SDK? 

  • I’m not sure exactly what to answer, but this change in TI driver behaviour was introduced in SDK 5.30 when the pin driver was removed. And I see no changes in the TI drivers between SDK 5.30 to 6.10 with regards to GPIO configuration.

    Let me give you an example to make it more clear. The following code is from TI drivers in SDK 5.30.

    The initialization function of driver /source/ti/drivers/i2c/I2CCC26XX.c   calls GPIO_setConfig, thus configuring the pins.

    static int I2CCC26XX_initIO(I2C_Handle handle, void *pinCfg) {
        I2CCC26XX_Object           *object;
        I2CCC26XX_HWAttrsV1 const  *hwAttrs;
    
        /* Get the pointer to the object and hwAttrs */
        object = handle->object;
        hwAttrs = handle->hwAttrs;
    
        /* If the pinCfg pointer is NULL, use hwAttrs pins */
        if (pinCfg == NULL) {
            object->sdaPin = hwAttrs->sdaPin;
            object->sclPin = hwAttrs->sclPin;
        } else {
            object->sdaPin = ((I2CCC26XX_I2CPinCfg *)pinCfg)->pinSDA;
            object->sclPin = ((I2CCC26XX_I2CPinCfg *)pinCfg)->pinSCL;
        }
    
        /* Configure I2C pins SDA and SCL and set their muxes */
        GPIO_setConfig(object->sdaPin, GPIO_CFG_OUT_OD_PU);
        GPIO_setMux(object->sdaPin, hwAttrs->sdaPinMux);
    
        GPIO_setConfig(object->sclPin, GPIO_CFG_OUT_OD_PU);
        GPIO_setMux(object->sclPin, hwAttrs->sclPinMux);
    
        return I2C_STATUS_SUCCESS;
    }
    

    The corresponding function in the TI SPI driver /source/ti/drivers/spi/SPICC26X2DMA.c does not call GPIO_setConfig, only the GPIO_setMux functions, so the pins are not configured. That’s why we need to do it in our application before calling the SPI driver

    static void initIO(SPI_Handle handle)
    {
        SPICC26X2DMA_Object        *object = handle->object;
        SPICC26X2DMA_HWAttrs const *hwAttrs = handle->hwAttrs;
    
        if (object->mode == SPI_SLAVE) {
            GPIO_setMux(hwAttrs->mosiPin, hwAttrs->rxPinMux);
            GPIO_setMux(hwAttrs->misoPin, hwAttrs->txPinMux);
            GPIO_setMux(hwAttrs->clkPin, hwAttrs->clkPinMux);
    
            /* Configure CSN callback for optional RETURN_PARTIAL slave mode */
            if (object->csnPin != GPIO_INVALID_INDEX) {
                GPIO_setMux(object->csnPin, hwAttrs->csnPinMux);
                GPIO_setCallback(object->csnPin, csnCallback);
                GPIO_setUserArg(object->csnPin, handle);
            }
        }
        else {
            GPIO_setMux(hwAttrs->mosiPin, hwAttrs->txPinMux);
            GPIO_setMux(hwAttrs->misoPin, hwAttrs->rxPinMux);
            GPIO_setMux(hwAttrs->clkPin, hwAttrs->clkPinMux);
    
            /* Mux CS unless it is software-controlled */
            if (object->csnPin != GPIO_INVALID_INDEX) {
                GPIO_setMux(object->csnPin, hwAttrs->csnPinMux);
            }
        }
    }
    

  • Hei Johannes,

    Driver specific GPIO configurations are indeed now generated through our Sysconfig tool, since around 5.30. If you load an spi example (spimaster for instance) from the latest SDK, you will see that this pin configuration is done in Board_init() -> GPIO_init(). GPIO_init then takes into account the GPIO configuration table (gpioPinConfigs) that was generated through Sysconfig. (see code snippet).

    /*
     *  ======== gpioPinConfigs ========
     *  Array of Pin configurations
     */
    GPIO_PinConfig gpioPinConfigs[31] = {
        0, /* Pin is not available on this device */
        0, /* Pin is not available on this device */
        0, /* Pin is not available on this device */
        0, /* Pin is not available on this device */
        0, /* Pin is not available on this device */
        GPIO_CFG_NO_DIR, /* DIO_5 */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW, /* CONFIG_GPIO_LED_0 */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW, /* CONFIG_GPIO_LED_1 */
        /* Owned by CONFIG_SPI_SLAVE as MISO */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL, /* CONFIG_GPIO_SPI_SLAVE_MISO */
        /* Owned by CONFIG_SPI_SLAVE as MOSI */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW, /* CONFIG_GPIO_SPI_SLAVE_MOSI */
        /* Owned by CONFIG_SPI_SLAVE as SCLK */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW, /* CONFIG_GPIO_SPI_SLAVE_SCLK */
        GPIO_CFG_NO_DIR, /* DIO_11 */
        /* Owned by CONFIG_UART2_0 as RX */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_DOWN_INTERNAL, /* CONFIG_GPIO_UART2_0_RX */
        /* Owned by CONFIG_UART2_0 as TX */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_HIGH, /* CONFIG_GPIO_UART2_0_TX */
        GPIO_CFG_NO_DIR, /* DIO_14 */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL, /* CONFIG_SPI_MASTER_READY */
        GPIO_CFG_NO_DIR, /* DIO_16 */
        GPIO_CFG_NO_DIR, /* DIO_17 */
        GPIO_CFG_NO_DIR, /* DIO_18 */
        GPIO_CFG_NO_DIR, /* DIO_19 */
        /* Owned by CONFIG_SPI_SLAVE as SS */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_HIGH, /* CONFIG_GPIO_SPI_SLAVE_SS */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL, /* CONFIG_SPI_SLAVE_READY */
        GPIO_CFG_NO_DIR, /* DIO_22 */
        GPIO_CFG_NO_DIR, /* DIO_23 */
        GPIO_CFG_NO_DIR, /* DIO_24 */
        GPIO_CFG_NO_DIR, /* DIO_25 */
        GPIO_CFG_NO_DIR, /* DIO_26 */
        GPIO_CFG_NO_DIR, /* DIO_27 */
        GPIO_CFG_NO_DIR, /* DIO_28 */
        GPIO_CFG_NO_DIR, /* DIO_29 */
        GPIO_CFG_NO_DIR, /* DIO_30 */
    };

  • However, I have checked with the R&D team, and there is a bug with the SPI driver (related to the input buffers) where you would indeed have to use GPIO_setConfig, as a workaround. This will also be fixed in the 6.30 SDK. Thank you again for the report.

  • Hi Arthur,

    Ok, I just found it a bit strange that some drivers do GPIO_config and others don’t. That seems a bit inconsistent.

    In our case we cannot use Sysconfig tool with pre-compiled gpioPinConfigs table since we have to config our GPIOs in runtime dynamically. So depending on external circumstances we will initialize GPIOs for different usage after startup.

    But my understanding is then that TI drivers will from now on (SDK 5.30) not configure the GPIOs any longer. It is done separately through Sysconfig and GPIO_init, and if one does not (or cannot) use Sysconfig you would have to handle the GPIO configuration from the application. Is that correct?

    BR,

    Johannes

  • Hi Johannes,

    You are right. As of today, and depending on the driver, you may have to handle the GPIO configuration by yourself in your Application, when not using Sysconfig. This might change in the future, as we are continuously improving the SDK.