From Technologic Systems Manuals

This board uses both CPU and a DIO controller in the FPGA.

The CPU DIO typically has 1-7 functions associated with various pins (I2C, PWM, SPI, etc). See the CPU manual for the complete listing and for information on how to control these DIO. For purposes of identity, all FPGA DIO will be labelled DIO_n (where n is the DIO pin number), and all CPU dio will be labelled MFP_n.


Full details on CPU pins can be found in the CPU manual, along with mode and mapping assignments specific to the CPU. The MFP pins can have multiple functions and not all default to GPIO, so understanding each one you wish to modify is important to your development process. The MFP definition registers are described in the CPU manual starting in Section A1, pages A7 through A12 (note these are appendix pages). This wiki will assume the reader already has a thorough understanding of these settings and is comfortable moving forward using them as a GPIO. NOTE: The default TS boot scripts set some MFP pins up with functions other than the default functionality. It is important to set the MFP you wish to use to the function you desire before using it. Do not assume default functionality is present on all MFP pins. The base address for the MFP alternate function block is at 0xD401E000, each MFP pin has its own address as listed in the table starting on page A-7. Alternate function definitions start in the table on page 58.

The CPU GPIO are divided into four banks, GPIO bank 0 through 3. These banks are controlled by several registers. Full information on these registers is found in the CPU manual starting at page A-832. The most important registers for general GPIO usage are the bit-value register (GPIO_GPLR / GPIO_PLR0-3), the GPIO direction register (GPIO_GPDR / GPIO_PDR0-3), the GPIO Output Set register (GPIO_GPSR / GPIO_GPIO_PSR0-3), and the GPIO Output Clear Register (GPIO_GPCR / GPIO_PCR0-3). The GPIO section in the CPU manual contains a typo in the GPIO control base address. The correct base address is 0xD4019000.

It can be generally assumed MFP # and GPIO bit # are identical for the purposes of this table.

Register Name Address Offset GPIO Start (bit 0) GPIO End (bit 31) Function
GPIO_PLR0 0x0000 0 31 DIO Data (RO)
GPIO_PLR1 0x0004 32 63
GPIO_PLR2 0x0008 64 95
GPIO_PLR3 0x0100 96 122
GPIO_PDR0 0x000c 0 31 DIO Direction
GPIO_PDR1 0x0010 32 63
GPIO_PDR2 0x0014 64 95
GPIO_PDR3 0x010c 96 122
GPIO_PSR0 0x0018 0 31 DIO Set
GPIO_PSR1 0x001c 32 63
GPIO_PSR2 0x0020 64 95
GPIO_PSR3 0x0118 96 122
GPIO_PCR0 0x0024 0 31 DIO Clear
GPIO_PCR1 0x0028 32 63
GPIO_PCR2 0x002c 64 95
GPIO_PCR3 0x0124 96 122

There are also edge-detect registers that work via set and status bits documented in the CPU manual, see section A.36.5 starting at page A-386.


All FPGA DIO are controlled by three distinct register types: Direction, Input Data, and Output Data. To use any DIO pin, the direction register must be set (0 for input, 1 for output), then either the input register may be read, or the output register may be written to. These registers are described in the Syscon memory table.

For example, to write to DIO_0, bit 0 (the LSB) of 0x80004018 (The direction register for DIO_0 through DIO_14) must be set high, then the desired value (high = 1 low = 0) should be written to bit 0 of 0x80004010 (the Output Data register for DIO_0 through DIO_14). Alternatively to read the status of that pin, the Direction Register must be set low, then bit zero of 0x80004020 would reflect the status of that pin.

All 60 of the DIO from the FPGA will default to the DIO mode. These pins coming from the FPGA are all 3.3V tolerant. To manipulate these DIO you can access the #Syscon.

Bit masking: Any bits not expressly mentioned here should be masked out. Direction setting: 0 is input, 1 is output.

For simple operations you can use tshwctl to set the FPGA DIO pins:

# Set DIO 30 as a high output
tshwctl --setdio 30

# Set DIO 30 as a low output
tshwctl --clrdio 30

# Read the input value of DIO 42, 43, 44
# This will set the pin to an input and return the value
tshwctl --getdio 42,43,44