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-F28P55X: Simple Question about Reading GPIO Pin Status on LAUNCHXL F28P55X (Input & Output)

Part Number: LAUNCHXL-F28P55X
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi everyone,

I'm testing the GPIO input function on my LAUNCHXL F28P55X board. I used two functions: GPIO_readPin(uint32_t pin) and GPIO_readPinDataRegister(uint32_t pin).

My English is not very good, so I don't fully understand the difference from the comments in the gpio.h file. Also, my test results are not what I expected.

I have already set up GPIO48 as an input. I also enabled the pull-up resistor (I checked with a multimeter and it has 3.3V).

My first question:
When I want to read the current input state of a GPIO pin (like GPIO48, which is set as an input), which function should I use? GPIO_readPin(uint32_t pin) or GPIO_readPinDataRegister(uint32_t pin)? I want to know if the pin is HIGH or LOW due to an external signal.

My second question:
If a GPIO pin is configured as an output, and I want to confirm its current output state (e.g., if it's currently outputting HIGH or LOW), which function should I use for that?

Thank you for your help! gpio.h

  • Hello,

    "GPIO_ReadPin" returns the actual state of the pin, not the state of the output latch. Also, "GPIO_WritePin(Uint16 gpioNumber, Uint16 outVal)" sets the GPyDAT register bit for the specified pin.

    Overall, first make sure that you configure the pin to digital GPIO and input mode and enable pull-up/down to define state when floating (optinal). Then you can read and write directly through GPADAT.

    Writing a GPIO Status:

    GpioDataRegs.GPASET.bit.GPIOX = 1;
    GpioDataRegs.GPACLEAR.bit.GPIOX = 1;


    Reading a GPIO Status:
    uint16_t inputLevel = GpioDataRegs.GPADAT.bit.GPIOX;

    Best Regards,

    Masoud

  • Thank you for your help before.

    I have a problem. My lab project has a build error on my LAUNCHXL F28P55X board.

    The project is here: \ti\c2000\C2000Ware_5_05_00_00\training\device\f28p55x\system_design\lab_systemdesign

    the picture show error says:
    "../lab_main.c", line 162: error #20: identifier "GpioDataRegs" is undefined

    This means GpioDataRegs can not found by the compiler.

    Can you help me this undefined?

    Thank you very much!

  • Hello,

    This is because you need to include the device header file (f28p55x_device.h) in the example. Also, you'll need to include the "${C2000WARE_ROOT}/device_support/f28p55x/headers/include" in the compiler include options. Since in this example, the library files are being used, you can simply use  "GPIO_writePin(20, 1);" and "status = GPIO_readPin(20);" for write/read.

    Best Regards,

    Masoud

  • uint16_t LED_INX = 0; 

    Sorry

    It is show "Compilation failure".

  • I suggest simply use "GPIO_writePin(20, 1);" and "status = GPIO_readPin(20);" for write/read in this example with no other change.

    Best Regards,

    Masoud

  • Hi Masoud,

    Thank you for your help.
    I know GPIO_writePin(20, 1); and status = GPIO_readPin(20); will work.

    But I want to use GpioDataRegs.GPASET.bit.GPIO20 = 1;
    When I use GpioDataRegs.GPASET.bit.GPIO20 = 1;, assembly code is very small. It means more faster. If I use GPIO_writePin(20, 1);, assembly code is big.
    My project still has error. GpioDataRegs undefined.
    I have put device_support/f28p55x/headers/include in my include options.
    Also, I added #include "f28p55x_device.h"
    Can you help me fix GpioDataRegs undefined?

    Thank your help.

  • Hello Ming,

    The project you mentioned earlier "\ti\c2000\C2000Ware_5_05_00_00\training\device\f28p55x\system_design\lab_systemdesign" is using driver lib while you trying to add bit-field support and that cause compiler issue here.

    Indeed, F28P55x devices support two types of development software, driver library APIs and bit-field structures. Each have their advantages and are implemented to be compatible together within the same user application.

    When combining bit-field and driverlib support, add a pre-defined symbol within the project properties called "_DUAL_HEADERS". This is required to avoid having conflicting definitions (in enums/structs/macros) which share the exact same names in both bit-field and driverlib headers.

    When you trying to add bit-field support on top of a driver lib-based project:

    1. Add the following include directory path to the project:

    device_support\f28p55x\headers\include

    2. Include the following header file in the project main source file:

    device_support\f28p55x\headers\include\f28p55x_device.h


    3. Add or link the f28p55x_globalvariabledefs.c file to the project. Location of file:

    device_support\f28p55x\headers\source


    4. Add or link the f28p55x_Headers_nonBIOS.cmd file to the project. Location of file:

    device_support\f28p55x\headers\cmd

    Let me know if this solves the issue.

    Best Regards,

    Masoud

  • Hello Masoud,

    I copyed the f28p55x_Headers_nonBIOS.cmd and f28p55x_globalvariabledefs.c files to the project.

    Thank you, the problem has been resolved.

    Does this solution also work for the F280039C?

    Thank your help.

  • Happy to know the problem is sorted out. Yes, the same approach works for F28003x.

    Best Regards,

    Masoud

  • Title: Question about GPIO access speed and my custom MyGPIOlib.h (based on GPIO_writePin)

    My Question (A & B):
    (A) When I use different GPIO output styles, which one gives faster assembly execution?
    (B) I read the function "static inline void GPIO_writePin(uint32_t pin, uint32_t outVal)" in gpio.h. I made my own macros in MyGPIOlib.h based on this. Is my usage correct and safe?

    Background / Details:
    (1) Direct register access : Thank you for teaching me how to use GPIO output syntax. The assembly code looks very simple, for example:
    GpioDataRegs.GPASET.bit.GPIO20 = 1;
    // Assembly
        761F01FC MOVW DP, #0x1fc
        1A030010 OR @0x3, #0x0010

    GpioDataRegs.GPACLEAR.bit.GPIO20 = 1;
    // Assembly
    761F01FC MOVW DP, #0x1fc
    1A050010 OR @0x5, #0x0010

    LED_INX = GpioDataRegs.GPADAT.bit.GPIO20 ;
    // Assembly
    761F01FC MOVW DP, #0x1fc
    CC010010 AND AL, @0x1, #0x10
    761F02B4 MOVW DP, #0x2b4
    FFC3 LSR AL, 4
    9620 MOV @0x20, AL

    LED_INX = GpioDataRegs.GPBDAT.bit.GPIO48;
    // Assembly
    761F01FC MOVW DP, #0x1fc
    9209 MOV AL, @0x9
    9001 ANDB AL, #0x1
    761F02B4 MOVW DP, #0x2b4
    9620 MOV @0x20, AL

    (2) GPIO_writePin in driverlib:
    I also studied the function in
    {project}\device\driverlib\gpio.h
    static inline void GPIO_writePin(uint32_t pin, uint32_t outVal)

    I understand that GPIODATA_BASE means the hardware GPIO address.
    So I tried to make my own declarations in MyGPIOlib.h. The usage looks like this:
    GPA20_OUT_HI ;
    // Assembly<pre>
        8F100000 MOVL XAR4, #0x100000
        BDA47F02 VMOV32 *(0:0x7f02), @XAR4</pre>

    GPA21_OUT_LO ;
    // Assembly
    8F200000 MOVL XAR4, #0x200000
    BDA47F04 VMOV32 *(0:0x7f04), @XAR4

    GPA20_OUT_LO ;
    // Assembly
    8F100000 MOVL XAR4, #0x100000
    BDA47F04 VMOV32 *(0:0x7f04), @XAR4

    LED_INX = GPIO20_IN ;
    // Assembly
    28AC0014 MOV @T, #0x0014
    761F02B4 MOVW DP, #0x2b4
    BFA97F00 VMOV32 @ACC, *(0:0x7f00)
    5622 LSRL ACC, T
    9001 ANDB AL, #0x1
    9620 MOV @0x20, AL

    LED_INX = GPIO48_IN ;
    // Assembly
    761F02B4 MOVW DP, #0x2b4
    BFA97F08 VMOV32 @ACC, *(0:0x7f08)
    9101 ANDB AH, #0x1
    9720 MOV @0x20, AH


    I am testing different ways to access GPIO in C2000.

    Below are the key parts of my MyGPIOlib.h for reference:
    // {project}\device\driverlib\gpio.h //
    // {project}\device\driverlib\inc //

    #define MY_GPA_DATA_BASE_ADDRESS GPIODATA_BASE + 0x00 // GPIO0 ~ GPIO31 //
    #define MY_GPB_DATA_BASE_ADDRESS GPIODATA_BASE + 0x08 // GPIO32 ~ GPIO63 //
    #define MY_GPC_DATA_BASE_ADDRESS GPIODATA_BASE + 0x10 // GPIO64 ~ GPIO95 //


    #define GPA_IN_DAT (*((volatile uint32_t *)(MY_GPA_DATA_BASE_ADDRESS + GPIO_GPxDAT_R_INDEX * 2)))
    #define GPB_IN_DAT (*((volatile uint32_t *)(MY_GPB_DATA_BASE_ADDRESS + GPIO_GPxDAT_R_INDEX * 2)))

    #define GPA_OUT_HI (*((volatile uint32_t *)(MY_GPA_DATA_BASE_ADDRESS + GPIO_GPxSET_INDEX * 2)))
    #define GPA_OUT_LO (*((volatile uint32_t *)(MY_GPA_DATA_BASE_ADDRESS + GPIO_GPxCLEAR_INDEX * 2)))
    #define GPA_OUT_BLINK (*((volatile uint32_t *)(MY_GPA_DATA_BASE_ADDRESS + GPIO_GPxTOGGLE_INDEX * 2)))


    #define GPIO20_IN ((GPA_IN_DAT ) >> 20U) & (uint32_t)0x1U
    #define GPIO48_IN ((GPB_IN_DAT ) >> ( 48U - 32U)) & (uint32_t)0x1U
    #define GPA20_OUT_HI GPA_OUT_HI = GPIO_GPADIR_GPIO20
    #define GPA20_OUT_LO GPA_OUT_LO = GPIO_GPADIR_GPIO20
    #define GPA20_OUT_BLINK GPA_OUT_BLINK = GPIO_GPADIR_GPIO20
    #define GPA21_OUT_HI GPA_OUT_HI = GPIO_GPADIR_GPIO21
    #define GPA21_OUT_LO GPA_OUT_LO = GPIO_GPADIR_GPIO21
    #define GPA21_OUT_BLINK GPA_OUT_BLINK = GPIO_GPADIR_GPIO21


    So my two questions are:
    1. Which style of GPIO access is faster in assembly execution?
    2. Is my custom MyGPIOlib.h declaration (based on GPIO_writePin) correct and safe to use?

    My goal: Optimize execution speed. These GPIO operations are for high-speed control (PWM / real-time).

  • Hello Ming,

    1. Which style of GPIO access is faster in assembly execution?

    Fastest write path: writing the SET/CLEAR/TOGGLE registers with a compile-time constant mask (i.e., GpioDataRegs.GPASET.all = (1UL<<20);).
    Your disassembly with MOVW DP + OR @...,#imm is the leanest. Your MyGPIOlib.h style works, but it typically costs extra cycles (MOVL XAR4 + VMOV32) and is slower.

    Your macro path (e.g., GPA20_OUT_HI):

    MOVL XAR4,#0x00100000 ; load 32-bit mask into XAR4
    VMOV32 *(0:0x7f02),@XAR4 ; 32b write to GPASET

    That is at least 2 instructions where the first is a 32-bit literal load (costlier than OR #imm), and the second is a 32-bit peripheral write. In practice this is slower than the direct OR pattern.

    2. Is my custom MyGPIOlib.h declaration (based on GPIO_writePin) correct and safe to use?

    Yes, broadly. It writes to the correct write-only registers and uses volatile. Fix the mask macro name, parentheses. For peak speed, prefer the direct struct/bit-mask style shown above (or static inline wrappers around it).

    Also, please post the new question as a separate E2E thread so everyone can refer to it later.

    Thanks and Regards,

    Masoud 

  • For C2000 GPIO which is 32-bit, for example F280039C and F28P55x:
    Is one page of the Data Page Pointer register (DP) equal to 64 words?
    Because MOVW DP, #0x1fc, and 0x1fc * 0x40 = 0x7F00 = GPIODATA_BASE.

    I want to make sure about the assembly address calculation for GPIO access.
    Please confirm if my understanding is correct.

    Thank you!

  • Yes, on C28x, the Data-Page (DP) pointer selects a 64-word page and the instruction’s 6-bit direct offset selects a word within that page. Formally:

    - Effective data address (word-addressed) = (DP << 6) | (6-bit offset).

    - Therefore MOVW DP, #0x1FC points DP at word address 0x1FC * 0x40 = 0x7F00. Any direct access with offset 0x00…0x3F then hits 0x7F00…0x7F3F.

    So, if your device’s TRM lists GPIODATA_BASE at 0x7F00 (word address), then your calculation lines up: DP = 0x1FC targets that GPIO data register block.

    For portability across F28003x/F28P55x, it’s still best to pull the base address from the device TRM or driverlib headers and let the assembler/compiler form the addressing; but the DP math above is the underlying mechanism.

    Best Regards,

    Masoud