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.

CCS/PROCESSOR-SDK-AM65X: How to use RTOS GPIO API

Part Number: PROCESSOR-SDK-AM65X


Tool/software: Code Composer Studio

Hello

I want to control the GPIO output on AM65x EVM IDK. I survey the RTOS template application to understand the GPIO API.

I have serveal questions about GPIO API.

1. What is the usage of GPIO_socGetInitCfg() & GPIO_socSetInitCfg()? What happens if we don't call it before calling function like GPIO_write()?

// in main.c
void Board_initGPIO(void)
{
    GPIO_v0_HwAttrs gpio_cfg;

    /* Get the default SPI init configurations */
    GPIO_socGetInitCfg(GPIO_LED0_PORT_NUM, &gpio_cfg);

    /* Modify the default GPIO configurations if necessary */
    GPIO_configIntRouter(GPIO_LED0_PORT_NUM, GPIO_LED0_PIN_NUM, 0, &gpio_cfg);

    /* Set the default GPIO init configurations */
    GPIO_socSetInitCfg(GPIO_LED0_PORT_NUM, &gpio_cfg);
}

2. The argument of most GPIO API only contains index information, no domain information. How these function help us to set a specific gpio pin.
    Furthermore, in app.c it pass a enumerator - USER_LED0 to GPIO_toggle(). Why doesn't it pass the gpio index of target LED?

// in GPIO_board.h
typedef enum GPIO_LED {
    USER_LED0 = 0,
    USER_LED1
}GPIO_LED;

// in app.h
#define TEST_LED_GPIO_INDEX USER_LED0

// in app.c
void gpio_toggle_led_task(UArg arg0, UArg arg1)
{

    appPrint("\n gpio_toggle_led task started");
    while(1) {
        /* Toggle test GPIO connected to LED */
        GPIO_toggle(TEST_LED_GPIO_INDEX);

        /* Delay to set period of pulse */
        Task_sleep(LED_BLINK_DELAY_VALUE);

        /* If end Test is triggered, then exit
         * Note:  The end test can be triggered through commands through uart
         */
        if (g_endTestTriggered)
            break;
    };
    appPrint("\n gpio_toggle_led task ended");
    Task_exit();
}

3. There are some macro like "GPIO_LED0_PORT_NUM" in template. What is the definition of term "Port".
    I couldn't find it (or I miss it) in the AM65x technical reference. Is the "Port" related to "Bank"?

Best regards.

ChingWei

  • Hi ChingWei,

     A GPIO example is provided in <PDK>\packages\ti\drv\gpio\test\led_blink. This example will build & execute on A53 and R5F.

    ChingWei Huang said:
    What is the usage of GPIO_socGetInitCfg() & GPIO_socSetInitCfg()?

    These API functions are provided so the application can change the default driver configuration for a GPIO hardware module. The default configuration is located in <PDK>\packages\ti\drv\gpio\soc\am65xx\GPIO_soc.c, GPIO_v0_hwAttrs. Using these function, the application:

    • reads the default configuration in GPIO_v0_hwAttrs using GPIO_socGetInitCfg().
    • updates the configuration returned by GPIO_socGetInitCfg() by overwriting the returned stucture members as required
    • writes the update configuration back to GPIO_v0_hwAttrs using GPIO_socSetInitCfg().

    ChingWei Huang said:
    What happens if we don't call it before calling function like GPIO_write()?

    The application will use the default driver configuration for a GPIO hardware module.

    ChingWei Huang said:
    The argument of most GPIO API only contains index information, no domain information. 

    The GPIO driver doesn't retain domain-specific information. To use GPIO in a specific domain (e.g. WKUP_GPIO0), the GPIO_socGetInitCfg() & GPIO_socSetInitCfg() API functions should be called to update the base address for the required port (e.g. for WKUP_GPIO0, update base address for port 0). This can be seen in the R5F example mentioned above, see the function Board_initGPIO().

    The index argument for most GPIO API functions is an index into an application-defined table containing the GPIO pin configurations. For example, please see <PDK>\packages\ti\drv\gpio\test\led_blink\am65xx\GPIO_board.c. The index parameter is used to index into the table gpioPinConfigs[]. The contents of GPIO_board.c can be modified to add more GPIOs, or change the configurations of the existing GPIOs.

    ChingWei Huang said:
    How these function help us to set a specific gpio pin?

    A specific pin configuration is contained in the arrays gpioPinConfigs[] and gpioCallbackFunctions[] in GPIO_board.c for a particular application.

    ChingWei Huang said:
    Furthermore, in app.c it pass a enumerator - USER_LED0 to GPIO_toggle(). Why doesn't it pass the gpio index of target LED?

    The index is for gpioPinConfigs[]. The corresponding entry in gpioPinConfigs[] should contain the port & pin numbers associated with the LED.

    ChingWei Huang said:
    There are some macro like "GPIO_LED0_PORT_NUM" in template. What is the definition of term "Port"? I couldn't find it (or I miss it) in the AM65x technical reference. Is the "Port" related to "Bank"?

    A port is a GPIO hardware module, i.e.

    • 2x for MAIN domain, GPIO0 & GPIO1
    • 1x for WKUP domain, WKUP_GPIO0

    There are multiple banks per port & 16 pins per bank, please see the TRM, 12.1.2.1 GPIO Overview.

    Regards,
    Frank

  • Hi Frank

    Thank you for your reply. It helps a lot !

    So, it seems that we have to build a GPIO configuraion to tell API which GPIO we want to use.

    We can't access new GPIO(not include in GPIO configuration) in the run time.

    And If we have built our own GPIO configuraion for application, we don't need to call GPIO_socGetInitCfg() & GPIO_socSetInitCfg() anymore.

    For example, if I want create a AM65x application that would control WKUP_GPIO0, GPIO0, GPIO1.

    I first change GPIO_v0_hwAttrs and GPIO_config in am65xx/GPIO_soc.c.

    /* GPIO Driver hardware attributes */
    GPIO_v0_hwAttrsList GPIO_v0_hwAttrs =
    {
         {
             CSL_WKUP_GPIO0_BASE,
             &GPIO_intCfgs[0][0],
             &GPIO_socConfigIntrPath,
         },
    
        {
            CSL_GPIO0_BASE,
            &GPIO_intCfgs[1][0],
            &GPIO_socConfigIntrPath,
        },
    
        {
            CSL_GPIO1_BASE,
            &GPIO_intCfgs[2][0],
            &GPIO_socConfigIntrPath,
        }
    };
    
    /* GPIO configuration structure */
    CSL_PUBLIC_CONST GPIOConfigList GPIO_config =
    {
         {
            &GPIO_FxnTable_v0,
            NULL,
            &GPIO_v0_hwAttrs[0]
         },
    
        {
            &GPIO_FxnTable_v0,
            NULL,
            &GPIO_v0_hwAttrs[1]
        },
    
        {
            &GPIO_FxnTable_v0,
            NULL,
            &GPIO_v0_hwAttrs[2]
        }
    };

    In this case, port 0 would refer to WKUP_GPIO0, port 1 would refer to GPIO0, port 2 would refer to GPIO1.

    Next, I change gpioPinConfigs in board.c

    #define WKUP_GPIO0_PORT_NUM    (0 << 8)
    #define GPIO0_PORT_NUM    (1 << 8)
    #define GPIO1_PORT_NUM    (2 << 8)
    
    /* GPIO Driver board specific pin configuration structure */
    GPIO_PinConfig gpioPinConfigs[] = {
                                       WKUP_GPIO0_PORT_NUM | WKUP_GPIO15_PIN_NUM | GPIO_CFG_OUTPUT,
                                       WKUP_GPIO0_PORT_NUM | WKUP_GPIO16_PIN_NUM | GPIO_CFG_OUTPUT,
                                       GPIO0_PORT_NUM | GPIO0_12_PIN_NUM | GPIO_CFG_OUTPUT,
                                       GPIO1_PORT_NUM | GPIO1_2_PIN_NUM | GPIO_CFG_OUTPUT,
    };
    
    /* GPIO Driver call back functions */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        NULL,
        NULL,
        NULL,
        NULL,
    };
    
    /* GPIO Driver configuration structure */
    GPIO_v0_Config GPIO_v0_config = {
        gpioPinConfigs,
        gpioCallbackFunctions,
        sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
        sizeof(gpioCallbackFunctions) / sizeof(GPIO_CallbackFxn),
        0,
    };

    In the result,

    GPIO_toggle(0); //this would toggle WKUP_GPIO0:GPIO-15
    GPIO_toggle(1); //this would toggle WKUP_GPIO0:GPIO-16
    GPIO_toggle(2); //this would toggle GPIO0:GPIO-12
    GPIO_toggle(3); //this would toggle GPIO1:GPIO-2

    Is my thinking correct?

    Best regards.
    ChingWei

  • ChingWei,

    I'm checking back on this thread, which looks to have not been fully closed. Were you able to resolve your issue?

    Best regards,

    Dave

  • Hi Dave

    The issue of TI-RTOS GPIO API remains unsolved.

    But we now accomplish GPIO control by writing GPIO register directly instead of using RTOS API.

    I think this issue could be closed for now because we are not using RTOS API.

    I would open a new issue once we need to use RTOS API. Is it OK?

    Best regards.

    ChingWei

  • Thanks ChingWei. Let's do so.

    Best regards,

    Dave