General Purpose IO (GPIO) FAQ for C2000

From Texas Instruments Wiki
Jump to: navigation, search

Introduction

This page lists a number of frequently asked questions with regards to the general purpose I/O module on C28x devices.

Electrical Specifications

Electrical specifications can change between devices, peripheral types and device families. Always refer to the data manual and errata for a particular device for Electrical Specifications.

Frequently Asked Questions

Documentation

Q: Where are the GPIO registers documented?

Refer to the System Control and Interrupts Reference Guide for your device. All reference guides for each device family are listed in this document: TMS320x28xx, 28xxx DSP Peripherals Reference Guide (SPRU566)

Q: Where are the electrical specifications of the GPIO pins documented ?

Electrical Specifications are documented in the data manual for the particular device. For GPIO these include:
  • Rise time
  • Fall time
  • Maximum toggle speed
  • Input timing: for signal qualification
  • GPIO as a wake-up signal timing

Code Questions

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

Consider the following code.
//
// Toggle GPIO18
//
   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

Consider the following code:
//
// Toggle GPIO18
//
 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?

        GpioDataRegs.GPBTOGGLE.all = 0x0002;
You can 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).

Q: Where is the 1 wait-state for back-to-back writes documented?

This is 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. It applies to all peripheral frame 1 registers.

Reset State

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: What is the status of the GPIO after reset?

As with all C2000 devices, the muxed GPIO pins default to GPIO inputs (hi-impedance) at reset. This condition is not explicitly stated in text in the documentation, but is immediately obvious by looking at the default state of the GPxMUXy and GPxDIRy registers in the System Control User's Guide.
Note: For GPIO pins which are MUXed with the JTAG functions (for example, on F2802x devices), the TRSTn pin controls whether the pins default to GPIO or JTAG at reset.
Note: Even though all GPIO are set to be high impedance on reset, several have internal pull-ups which are also enabled at reset. See the Pull-up/Pull-down section below.

Pull-up/Pull-down

Q: What is the value of the pull-up and pull-down resistors?

The internal pull-ups/downs are active circuits, not passive resistors. There is no Ohms rating. Rather, there are current ratings given in the data manual. You can roughly think of these ratings as the amount of current needed to overpower the pull-up/down and cause the pin to change logic level.

Q: Can the pull-up and pull-down resistors be disabled via software?

  • On 281x: No.
  • On other devices: Yes for GPIO pins. Refer to the GPIO configuration registers in the System Control and Interrupts guide for your particular devices.

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.

Qualification

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.