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.

[FAQ] C2000 GPIO FAQ

This post addresses commonly asked questions regarding the GPIO on F28x devices.  Some information may have changed over time.  Always refer to the latest Technical Reference Manual and datasheet for a particular device. 

Q: Can I read the state of the pin (DAT register) even if the MUX is configured for peripheral usage?

  • 281x: No. On this device, the GPIODAT register reflects the state of the GPIODAT output latch.
  • On other devices: Yes. reading the GPIODAT register actually reflects the value on the pin.

Q: Back-to-back DAT register writes do not work as expected

  • This is also described in the application note Programming TMS320x28xx Peripherals in C/C++ (SPRAA85).
  • Consider the following example. Running the code, the Green LED (A17) toggles as expected, but the red one (A16) stays permanently off. Setting a breakpoint and stepping through the code it works fine.
  for(;;)
  {
         /* Make LED Green */
         GpioDataRegs.GPADAT.bit.GPIO16 = 1; //RED_LED_OFF;
         GpioDataRegs.GPADAT.bit.GPIO17 = 0; //GREEN_LED_ON;
         delay_loop();
         /* Make LED Red */
         GpioDataRegs.GPADAT.bit.GPIO16 = 0; //RED_LED_ON;
         GpioDataRegs.GPADAT.bit.GPIO17 = 1; //GREEN_LED_OFF;
         delay_loop();
   }

The above code will perform a read-modify-write of the DAT registers. The DAT register reflects the state of the pin itself (except on 281x devices). There is, however, some delay between a write to the DAT register and when the resulting value will be seen on the pin and then reflected back to the DAT. In this case the "GREEN_LED_ON" reads GPIO16 as low and writes that value back. Thus the RED LED never changes state.

One solution is to use CLEAR/SET registers for this example. Another is to place NOP's or other instructions between the read-modify-write instructions.

Note: on 281x the DAT register reflects the output latch and not the state of the pin. In this case the above code will work.

Q: Toggling of the GPIO seems slower than it should be - Part 1

  GpioDataRegs.GPACLEAR.bit.GPIO18 = 1;
  GpioDataRegs.GPASET.bit.GPIO18 = 1;
  GpioDataRegs.GPACLEAR.bit.GPIO18 = 1;
  GpioDataRegs.GPASET.bit.GPIO18 = 1;
  GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;

The attempt is to toggle GPIO18 as fast as possible. The bit method shown performs a read-modify-write. The read portion is wait-stated and since the peripheral frame has "write-followed-by-read pipeline protection" the next read won't occur until the previous write has completed. Using .all to write to the whole register will remove the wait-stated reads and effect of the pipeline protection. This is also described in the application note: Programming TMS320x28xx Peripherals in C/C++ (SPRAA85)

Q: Toggling of the GPIO seems slower than it should be - Part 2

for(;;)
{
       GpioDataRegs.GPADAT.bit.GPIO18 = 1;
       GpioDataRegs.GPADAT.bit.GPIO18 = 0;
}

The above code has similar issues to that discussed before. This method uses a read-modify-write. Since the read portion is wait-stated and since the peripheral frame has "write-followed-by-read protection, the next read doesn't occur until the previous one completes. Another issue is the for loop will introduce a branch which takes 4 cycles. So even if this code were changed to use the GPBTOGGLE register, you would see a overhead from the branch.

Q: How can I toggle a GPIO pin as fast as possible in C?

The fastest way is to perform back-to-back writes to the TOGGLE registers:
If this is done in a for() loop, then the loop will introduce a branch instruction which takes 4 cycles at the start of each loop. On floating-point devices you can do something similar with a repeat block instruction (RPTB) instead of a branch which will eliminate the branch overhead. In addition, back-to-back writes to this peripheral frame will introduce a wait-state. That is one toggle will take a cycle, but back to back toggles will add an additional cycle between the writes.

for(;;)
{
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       GpioDataRegs.GPBTOGGLE.all = 0x0002;
       repeat...etc
 }

Q: How long will this C instruction to toggle a GPIO pin take?

Take a look at the disassembly generated in the Code Composer Studio window. In general there will be an instruction to set the data page pointer an AND instruction to write to the GPBTOGGLE register. On their own, each of these instructions take one SYSCLKOUT cycle.

If another write is made to the GPBTOGGLE register then the data page does not have to be set for the second write. Consecutive (back-to-back) writes, however, to GPIO registers experience a 1-cycle pipeline hit (1-cycle delay).

Note: Wait-states are documented in the device specific data manual in the table that describes the wait-states for the various spaces in the device's memory map area. This may not apply to the device you are using.  Always check the documentation.

Q: 2833x/2823x: The GPIOB MUX1 register is set correctly to 0x00000000 after reset, but when loading code it is set to 0XFFFFFFC0?

The GEL file TI supplies is probably setting up the GPIO for XINTF functionality on file load. This allows Code Composer to load debug code directly into the XINTF. Look in the 'on file preload' function and remove the enable XINTF call to stop this behavior.

Q: Are the pull-ups on pins that can be used as ePWM outputs enabled or disabled on reset?

  • On F281x devices if a GPIO pin has a pull-up then it is enabled at reset and there is no way to disable them in software.
  • On F280x, F2802x, F2803x, F2805x, F2806x, F2823x, F2833x and C2834x devices, it is best to refer to the documentation (see below). However, some general guidelines exist:
    • If a GPIO pin is commonly used as an ePWM (GPIO-00 for instance), the pull-up is disabled at reset. It can then be enabled by software.
    • If a GPIO pin is not often used as an ePWM, then the pull-up is enabled on reset. It can then be disabled by software
  • On newer devices, such as F2807x and F2837x devices, all pins have their internal pull-up resistors disabled at reset. They can be enabled later via software.

The documentation for each GPIO Pullup Disable (GPxPUD) register will give the status of each bit, and therefore each pull-up, at reset. This information can be found in the GPIO section of the System Control and Interrupts Guide (or TRM in some devices) for your specific device.

Q: Is it possible to use the qualification function of the GPIO when the input is dedicated to a peripheral?

  • The qualification circuitry is active regardless of the setting of the GPIO mux. So, yes, you can use the qualification for the peripheral function.

Q: I am looking for timing information for the qualification logic.

  • Please see the data manual for your device. This will be listed with the other GPIO timing parameters.