Configuring for Special Purpose

Basic Rules

Besides the general input or output functions, you can also use StarFive's pin multiplexing (PINMUX) technologies to configure a GPIO port for special signaling.

There are 3 types of signals: GPO, GPI and GPEN. Different function may require different types of signals.

The basic rules are shown as follow:
Table 1. Basic PINMUX Rules
Function GPO Signal GPI Signal GPEN Signal
Unidirectional input None Required May require
Unidirectional output Required None May require
Bidirectional input/output Required Required Required
The following list provides more explanation of the signals.
  • GPO Signal - The GPO signal is required for the output function.
  • GPI Signal - The GPI signal is required for the input function.
  • GPEN - The GPEN signal is the output enabling signal.

To complete the PINMUX, you need to configure signal index in the register. For more information on the signal index, see Signal Index Table.

It’s worth noting that not all functions have dedicated GPEN signals. For the input function without a GPEN signal, the index value should be fixed to 1. For the output function without a GPEN signal, the index value should be fixed to 0. In the following programming example, the index of the GPEN signal is denoted as OEN.

If GPO signal is required, regs->dout should be configured.
gpo; //GPO signal index
n = port >> 2;
shift = (port & 0x3) << 3;
modl(regs->dout+n, GPIO_DOUT_MASK<<shift, gpo<<shift);
If GPEN signal is required, regs->doen should be configured.
oen; //GPEN signal index
n = port >> 2;
shift = ((port & 0x3) << 3);
modl(regs->doen+n, GPIO_DOEN_MASK<<shift, oen<<shift);
If GPI signal is required, regs->sig_in should be configured.
gpi; //GPI signal index
n = gpi >> 2;
shift = ((gpi & 0x3) << 3);
modl(regs->sig_in+n, GPIO_SIG_IN_MASK<<shift, (port+2)<<shift);

Configuring a GPIO as UART Signal

The following code block provides an example of configuring GPIO11 as UART0 RX.
GPI signal: GPI_SYS_IOMUX_U0_DW_UART_SIN (index 14)
GPO signal: none
GPEN signal: none

port = 11;
gpi = 14; //GPI signal index
oen = 1; //no GPEN signal, but it’s an input function, fixed to 1

n = gpi >> 2;
shift = ((gpi & 0x3) << 3);
modl(regs->sig_in+n, GPIO_SIG_IN_MASK<<shift, (port+2)<<shift);

n = port >> 2;
shift = ((port & 0x3) << 3);
modl(regs->doen+n, GPIO_DOEN_MASK<<shift, oen<<shift);

Configuring a GPIO as SDIO Signal

The following code block provides an example of configuring GPIO12 as SDIO1 DATA0.
GPI signal: GPI_SYS_IOMUX_U1_DW_SDIO_CDATA_IN_0 (index 45)
GPO signal: GPO_SYS_IOMUX_U1_DW_SDIO_CDATA_OUT_0 (index 58)
GPEN signal: GPEN_SYS_IOMUX_U1_DW_SDIO_CDATA_OUT_EN_0 (index 20)

port = 12;
gpi = 45; //GPI signal index
gpo = 58; //GPO signal index
oen = 20; //GPEN signal index

n = gpi >> 2;
shift = (gpi & 3) << 3;
modl(regs->sig_in+n, GPIO_SIG_IN_MASK<<shift, (gpio+2)<<shift);

n = port >> 2;
shift = (port & 0x3) << 3;
modl(regs->dout+n, GPIO_DOUT_MASK<<shift, gpo<<shift);
modl(regs->doen+n, GPIO_DOEN_MASK<<shift, oen<<shift);