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.

CC2640: Simultaneous control of Multiple Digital IO pin

Part Number: CC2640

Hello,
I am new to the TI MCU world. currently, I am trying to learn to program a Ti MCU (cc2640), I have a cc2640R2 development kit. SO far, I have read through some examples but I could not find an option to write data to multiple Digital I/Os at the same time. All the functions that I have seen are either configuring or reading/writing data to a single pin. Is there a function to write data to multiple digital I/Os?

My particular requirement is, I have an array of 4-bit data. and I want to write the 4-bit data to 4 digital GPIO.

For Example:

byte controlPin[]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001,0b1010,0b1011,0b1100,0b1101,0b1110,0b1111};

for(pinSelect=0; pinSelect<=pinLimit; pinSelect++)
{
GPIO_write(Selected Port Pins); // write data to pin 0 to 3
sleep(time);
}

Is there any function that can perform this "GPIO_write(Selected Port Pins)" operation? I want to write data at the same time to all the selected pins.


For example, if the pinSelect=3 then
controlPin[3] is the value then that means "0b0011" data is to be written to pin 0,1,2,&3 so that pin-1 outputs a value of 0 ........ and pin-3 outputs a value of 1).


If there is a function to perform this kind of operation then, I would appreciate it greatly if someone can direct me to it, otherwise to a tutorial that can perform this operation on the register level. If there is no tutorial of such kind then I would also appreciate it if someone can help me figure out a way to perform this operation.

Thank you for your time and consideration.

Best Regards

  • Ifthekhar,

    The TI Driver GPIO functions only allow you to control 1 I/O at a time. You can look into the source to see how those drivers are implemented to get see how to do lower-level control.

    You can also refer to PIN_setPortOutputValue(). This function simultaneously writes output buffer values of all allocated pins in a GPIO port.

    Regards,

    Daniel

  • Hello @, I took a different approach to solve the problem and have used the same single GPIO control function. My code builds up properly but When I run it it does not seem to do anything. Can anyone tell me what am I doing wrong?

    Thank you.

    Here is the code:

    #include <unistd.h> // from GPIO
    #include <stdint.h>
    #include <stddef.h> // from GPIO
    #include <stdio.h>
    /* For sleep() */
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>  //from GPIO
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/UART.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
    
        GPIO_init(); // from GPIO
    
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
    
    
        int controlPin[] = {0b0000, 0b0001, 0b0010, 0b0011, 0b0100, 0b0101, 0b0110, 0b0111, 0b1000, 0b1001, 0b1010, 0b1011, 0b1100, 0b1101, 0b1110, 0b1111};
        int pincount = 16;
    
        int Muxpin_0= 25;  // DIO25 of the launchxl-cc2640r2 board
        int Muxpin_1= 26; // DIO26 of the launchxl-cc2640r2 board
        int Muxpin_2= 27; // DIO27 of the launchxl-cc2640r2 board
        int Muxpin_3= 28;  // DIO28 of the launchxl-cc2640r2 board 
    
        /* Configure the MUX control pin */
        GPIO_setConfig(Muxpin_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Muxpin_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Muxpin_2, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Muxpin_3, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
    
    
        while(1) {
            //sleep(1000);
    
            int pin = 0;
    
            for (pin = 0; pin <= pincount; pin++)
              {
                a = controlPin[pin] & 0b1000;
                a = a >> 3;
                b = controlPin[pin] & 0b0100;
                b = b >> 2;
                c = controlPin[pin] & 0b0010;
                c = c >> 1;
                d = controlPin[pin] & 0b0001;
    
                GPIO_write(Muxpin_0, a);
                GPIO_write(Muxpin_1, b);
                GPIO_write(Muxpin_2, c);
                GPIO_write(Muxpin_3, d);
    sleep(1); // one second sleep
    GPIO_write(Muxpin_0, 0); GPIO_write(Muxpin_1, 0); GPIO_write(Muxpin_2, 0); GPIO_write(Muxpin_3, 0); } } }

  • You need to have a gpioPinConfigs table for your GPIOs. the GPIO driver is a wrapper for the Pin Driver, so you need to make sure your CC2640R2_LAUNCHXL.c/.h files are updated with the additional GPIOs you are using. 

    For an example, see this post: https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/538/t/793727

    Regards,

    Daniel

  • Hello @, Thank you very much for your suggestion. I have tried the solution but it looks like I am still doing something wrong. I would appreciate it greatly if you can have a look at it and can suggest me a solution for it.

    Here are my code and other .h and .c files sections that I have edited. I have added the comment "added by IFA" beside the lines where I have made the changes. I have noticed another issue, other than "GPIO25", I was also using "Board_GPIO_LED1". I have noticed that the sleep function is also not working. The LED is always staying turned ON.

    Code:

    #include <unistd.h> // from GPIO
    #include <stdint.h>
    #include <stddef.h> // from GPIO
    #include <stdio.h>
    /* For sleep() */
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>  //from GPIO
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/UART.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
    
        GPIO_init(); // from GPIO
    
    
        /* Configure the MUX control pin */
        GPIO_setConfig(Board_GPIO_DIO25, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
    
    
    
        while(1) {
    
                GPIO_write(Board_GPIO_DIO25, 1);
                GPIO_write(Board_GPIO_LED1, 1);
                sleep(1); // one second sleep
                GPIO_write(Board_GPIO_DIO25, 0);
                GPIO_write(Board_GPIO_LED1, 0);
    
     //   }
    }
    }

    Board.h file edited section:

    #define Board_DIO29_ANALOG      CC2640R2_LAUNCHXL_DIO29_ANALOG
    #define Board_DIO30_ANALOG      CC2640R2_LAUNCHXL_DIO30_ANALOG
    
    #define Board_GPIO_DIO25        CC2640R2_LAUNCHXL_GPIO_DIO25  // added by IFA
    #define Board_GPIO_BUTTON0      CC2640R2_LAUNCHXL_GPIO_S1
    #define Board_GPIO_BUTTON1      CC2640R2_LAUNCHXL_GPIO_S2
    #define Board_GPIO_BTN1         CC2640R2_LAUNCHXL_GPIO_S1
    #define Board_GPIO_BTN2         CC2640R2_LAUNCHXL_GPIO_S2
    #define Board_GPIO_LED0         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_LED1         CC2640R2_LAUNCHXL_GPIO_LED_GREEN
    #define Board_GPIO_LED2         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_RLED         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_GLED         CC2640R2_LAUNCHXL_GPIO_LED_GREEN
    #define Board_GPIO_LED_ON       CC2640R2_LAUNCHXL_GPIO_LED_ON
    #define Board_GPIO_LED_OFF      CC2640R2_LAUNCHXL_GPIO_LED_OFF
    #define Board_GPIO_TMP116_EN    CC2640R2_LAUNCHXL_GPIO_TMP116_EN

    CC2640R2_LAUNCHXL.h file edited section:

    /*!
     *  @def    CC2640R2_LAUNCHXL_GPIOName
     *  @brief  Enum of GPIO names
     */
    typedef enum CC2640R2_LAUNCHXL_GPIOName {
        CC2640R2_LAUNCHXL_GPIO_DIO25 = 25,  // added by IFA
        CC2640R2_LAUNCHXL_GPIO_S1 = 0,
        CC2640R2_LAUNCHXL_GPIO_S2,
        CC2640R2_LAUNCHXL_SPI_MASTER_READY,
        CC2640R2_LAUNCHXL_SPI_SLAVE_READY,
        CC2640R2_LAUNCHXL_GPIO_LED_GREEN,
        CC2640R2_LAUNCHXL_GPIO_LED_RED,
        CC2640R2_LAUNCHXL_GPIO_TMP116_EN,
        CC2640R2_LAUNCHXL_GPIO_SPI_FLASH_CS,
        CC2640R2_LAUNCHXL_SDSPI_CS,
        CC2640R2_LAUNCHXL_GPIO_LCD_CS,
        CC2640R2_LAUNCHXL_GPIO_LCD_POWER,
        CC2640R2_LAUNCHXL_GPIO_LCD_ENABLE,
        CC2640R2_LAUNCHXL_GPIOCOUNT
    } CC2640R2_LAUNCHXL_GPIOName;

    CC2640R2_LAUNCHXL.c file edited sections:

    
    
    /*
     * Array of Pin configurations
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in CC2640R2_LAUNCHXL.h
     * NOTE: Pins not used for interrupts should be placed at the end of the
     *       array. Callback entries can be omitted from callbacks array to
     *       reduce memory usage.
     */
    GPIO_PinConfig gpioPinConfigs[] = {
        /* Input pins */
        GPIOCC26XX_DIO_25 | GPIO_DO_NOT_CONFIG,  /* GPIO 25 */ // added by IFA
        GPIOCC26XX_DIO_13 | GPIO_DO_NOT_CONFIG,  /* Button 0 */
        GPIOCC26XX_DIO_14 | GPIO_DO_NOT_CONFIG,  /* Button 1 */
    
        GPIOCC26XX_DIO_15 | GPIO_DO_NOT_CONFIG,  /* CC2640R2_LAUNCHXL_SPI_MASTER_READY */
        GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,  /* CC2640R2_LAUNCHXL_SPI_SLAVE_READY */
    
        /* Output pins */
    
        GPIOCC26XX_DIO_07 | GPIO_DO_NOT_CONFIG,  /* Green LED */
        GPIOCC26XX_DIO_06 | GPIO_DO_NOT_CONFIG,  /* Red LED */
        GPIOCC26XX_DIO_30 | GPIO_DO_NOT_CONFIG,  /* TMP116_EN */
    
        /* SPI Flash CSN */
        GPIOCC26XX_DIO_20 | GPIO_DO_NOT_CONFIG,
    
        /* SD CS */
        GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,
    
        /* Sharp Display - GPIO configurations will be done in the Display files */
        GPIOCC26XX_DIO_24 | GPIO_DO_NOT_CONFIG, /* SPI chip select */
        GPIOCC26XX_DIO_22 | GPIO_DO_NOT_CONFIG, /* LCD power control */
        GPIOCC26XX_DIO_23 | GPIO_DO_NOT_CONFIG, /*LCD enable */
    
    };

    and 

    /*
     * Array of callback function pointers
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in CC2640R2_LAUNCH.h
     * NOTE: Pins not used for interrupts can be omitted from callbacks array to
     *       reduce memory usage (if placed at end of gpioPinConfigs array).
     */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        NULL,  /* GPIO - 25 */ // added by IFA
        NULL,  /* Button 0 */
        NULL,  /* Button 1 */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_MASTER_READY */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_SLAVE_READY */
    };

     

  • Ifthekhar,

    Did you also modify BoardGpioInitTable[] in the CC2640R2_LAUNCHXL.c file? This is also required as part of the Pin driver.

    Regards,

    Daniel

  • @, It's working now. I did not have to modify BoardGpioInitTable[]. The problem was that in "CC2640R2_LAUNCHXL.h" file's "CC2640R2_LAUNCHXL_GPIOName" structure, I placed the GPIO 25 initialization at the beginning but made it equal to 25, as a result, it chanced numbering structure. I have changed 25 to 0 for the GPIO25 and for GPIO_S1 removed the zero. It solved the problem.

    My experimental code changes the status of GPIO 25,26,27 & 28 every 500ms. Hopefully, my solution will help others to solve similar issues.

    Best Regards,

    Ifthekhar

    Here is the solution for my experimental code.

    Code:

    #include <unistd.h> // from GPIO
    #include <stdint.h>
    #include <stddef.h> // from GPIO
    #include <stdio.h>
    /* For sleep() */
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>  //from GPIO
    #include <ti/drivers/gpio/GPIOCC26XX.h>
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/pin/PINCC26xx.h>
    #include <ti/drivers/Watchdog.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        /* 1 second delay */
        uint32_t time = 500000;
        GPIO_init(); // from GPIO
    
    
        /* Configure the MUX control pin */
        GPIO_setConfig(Board_GPIO_DIO25, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_DIO26, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_DIO27, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_DIO28, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
     //   double time_count = 500;
    
    
        while(1) {
    
                GPIO_write(Board_GPIO_DIO25, 1);
                GPIO_write(Board_GPIO_DIO26, 1);
                GPIO_write(Board_GPIO_DIO27, 1);
                GPIO_write(Board_GPIO_DIO28, 1);
                GPIO_write(Board_GPIO_LED1, 1);
                usleep(time);
                GPIO_write(Board_GPIO_DIO25, 0);
                GPIO_write(Board_GPIO_DIO26, 0);
                GPIO_write(Board_GPIO_DIO27, 0);
                GPIO_write(Board_GPIO_DIO28, 0);
                GPIO_write(Board_GPIO_LED1, 0);
                usleep(time);
      //          Task_sleep(333000/10);
    
    
     //   }
    }
    }
    

    Board.h file edited section:

    #define Board_GPIO_DIO25        CC2640R2_LAUNCHXL_GPIO_DIO25        // Added by IFA GPIO 25
    #define Board_GPIO_DIO26        CC2640R2_LAUNCHXL_GPIO_DIO26        // Added by IFA GPIO 26
    #define Board_GPIO_DIO27        CC2640R2_LAUNCHXL_GPIO_DIO27        // Added by IFA GPIO 27
    #define Board_GPIO_DIO28        CC2640R2_LAUNCHXL_GPIO_DIO28        // Added by IFA GPIO 28
    #define Board_GPIO_BUTTON0      CC2640R2_LAUNCHXL_GPIO_S1
    #define Board_GPIO_BUTTON1      CC2640R2_LAUNCHXL_GPIO_S2
    #define Board_GPIO_BTN1         CC2640R2_LAUNCHXL_GPIO_S1
    #define Board_GPIO_BTN2         CC2640R2_LAUNCHXL_GPIO_S2
    #define Board_GPIO_LED0         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_LED1         CC2640R2_LAUNCHXL_GPIO_LED_GREEN
    #define Board_GPIO_LED2         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_RLED         CC2640R2_LAUNCHXL_GPIO_LED_RED
    #define Board_GPIO_GLED         CC2640R2_LAUNCHXL_GPIO_LED_GREEN
    #define Board_GPIO_LED_ON       CC2640R2_LAUNCHXL_GPIO_LED_ON
    #define Board_GPIO_LED_OFF      CC2640R2_LAUNCHXL_GPIO_LED_OFF
    #define Board_GPIO_TMP116_EN    CC2640R2_LAUNCHXL_GPIO_TMP116_EN

    CC2640R2_LAUNCHXL.h file edited section:

    /*!
     *  @def    CC2640R2_LAUNCHXL_GPIOName
     *  @brief  Enum of GPIO names
     */
    typedef enum CC2640R2_LAUNCHXL_GPIOName {
        CC2640R2_LAUNCHXL_GPIO_DIO25 = 0, // added by IFA  GPIO 25
        CC2640R2_LAUNCHXL_GPIO_DIO26,  // added by IFA
        CC2640R2_LAUNCHXL_GPIO_DIO27,   // added by IFA
        CC2640R2_LAUNCHXL_GPIO_DIO28,   // added by IFA   GPIO 28
        CC2640R2_LAUNCHXL_GPIO_S1,
        CC2640R2_LAUNCHXL_GPIO_S2,
        CC2640R2_LAUNCHXL_SPI_MASTER_READY,
        CC2640R2_LAUNCHXL_SPI_SLAVE_READY,
        CC2640R2_LAUNCHXL_GPIO_LED_GREEN,
        CC2640R2_LAUNCHXL_GPIO_LED_RED,
        CC2640R2_LAUNCHXL_GPIO_TMP116_EN,
        CC2640R2_LAUNCHXL_GPIO_SPI_FLASH_CS,
        CC2640R2_LAUNCHXL_SDSPI_CS,
        CC2640R2_LAUNCHXL_GPIO_LCD_CS,
        CC2640R2_LAUNCHXL_GPIO_LCD_POWER,
        CC2640R2_LAUNCHXL_GPIO_LCD_ENABLE,
        CC2640R2_LAUNCHXL_GPIOCOUNT
    } CC2640R2_LAUNCHXL_GPIOName;

    CC2640R2_LAUNCHXL.c file edited sections:

    /*
     * Array of Pin configurations
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in CC2640R2_LAUNCHXL.h
     * NOTE: Pins not used for interrupts should be placed at the end of the
     *       array. Callback entries can be omitted from callbacks array to
     *       reduce memory usage.
     */
    GPIO_PinConfig gpioPinConfigs[] = {
        GPIOCC26XX_DIO_25 | GPIO_DO_NOT_CONFIG,  // GPIO 25 (added by IFA)
        GPIOCC26XX_DIO_26 | GPIO_DO_NOT_CONFIG,  // GPIO 26 (added by IFA)
        GPIOCC26XX_DIO_27 | GPIO_DO_NOT_CONFIG,  // GPIO 27 (added by IFA)
        GPIOCC26XX_DIO_28 | GPIO_DO_NOT_CONFIG,  // GPIO 28 (added by IFA)
        /* Input pins */
        GPIOCC26XX_DIO_13 | GPIO_DO_NOT_CONFIG,  /* Button 0 */
        GPIOCC26XX_DIO_14 | GPIO_DO_NOT_CONFIG,  /* Button 1 */
    
        GPIOCC26XX_DIO_15 | GPIO_DO_NOT_CONFIG,  /* CC2640R2_LAUNCHXL_SPI_MASTER_READY */
        GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,  /* CC2640R2_LAUNCHXL_SPI_SLAVE_READY */
    
        /* Output pins */
        GPIOCC26XX_DIO_07 | GPIO_DO_NOT_CONFIG,  /* Green LED */
        GPIOCC26XX_DIO_06 | GPIO_DO_NOT_CONFIG,  /* Red LED */
        GPIOCC26XX_DIO_30 | GPIO_DO_NOT_CONFIG,  /* TMP116_EN */
    
        /* SPI Flash CSN */
        GPIOCC26XX_DIO_20 | GPIO_DO_NOT_CONFIG,
    
        /* SD CS */
        GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,
    
        /* Sharp Display - GPIO configurations will be done in the Display files */
        GPIOCC26XX_DIO_24 | GPIO_DO_NOT_CONFIG, /* SPI chip select */
        GPIOCC26XX_DIO_22 | GPIO_DO_NOT_CONFIG, /* LCD power control */
        GPIOCC26XX_DIO_23 | GPIO_DO_NOT_CONFIG, /*LCD enable */
    
    };

    and 

    /*
     * Array of callback function pointers
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in CC2640R2_LAUNCH.h
     * NOTE: Pins not used for interrupts can be omitted from callbacks array to
     *       reduce memory usage (if placed at end of gpioPinConfigs array).
     */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        NULL,   // GPIO 25 Added by IFA
        NULL,   // GPIO 26 Added by IFA
        NULL,   // GPIO 27 Added by IFA
        NULL,   // GPIO 28 Added by IFA
        NULL,  /* Button 0 */
        NULL,  /* Button 1 */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_MASTER_READY */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_SLAVE_READY */
    };

    One last thing, I also have tested the code without putting anything inside the "GPIO_CallbackFxn gpioCallbackFunctions[]" section.

    Like this way:

    /*
     * Array of callback function pointers
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in CC2640R2_LAUNCH.h
     * NOTE: Pins not used for interrupts can be omitted from callbacks array to
     *       reduce memory usage (if placed at end of gpioPinConfigs array).
     */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        NULL,  /* Button 0 */
        NULL,  /* Button 1 */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_MASTER_READY */
        NULL,  /* CC2640R2_LAUNCHXL_SPI_SLAVE_READY */
    };

    It also works just fine. If anyone knows the purpose of putting  "NULL" inside the "GPIO_CallbackFxn gpioCallbackFunctions[]" structure, please let me know.

  • Ifthekhar,

    An explanation for the array GPIO_CallbackFxn gpioCallbackFunctions[] can be found here: https://software-dl.ti.com/simplelink/esd/simplelink_msp432_sdk/1.60.00.12/docs/tidrivers/doxygen/html/_g_p_i_o_8h.html 

    An array of GPIO_CallbackFxn elements that is used to store callback function pointers for GPIO pins configured with interrupts. The indexes for these array elements correspond to the pins defined in the GPIO_pinConfig array. These function pointers can be defined statically by referencing the callback function name in the array element, or dynamically, by setting the array element to NULL and using GPIO_setCallback() at runtime to plug the callback entry. 

    Regards, 

    Daniel

  • Hello Daniel,

    Thank you for your help.

    Best Regards,

    Ifthekhar