Section 19.2 GPIO Connections
Table 19.2.1 shows the relationship between the GPIO pins and the header pins for the 40-pin header. Table 19.2.2 shows the relationship for Revision 2.0 of the 26-bit header, and Table 19.2.3 shows the relationship for Revision 1.0 of the 26-pin header. If you have a Raspberry Pi with a 26-pin header, you will need to consult the Raspberry Pi website to determine which Revision you have.
GPFSELm is the \(m^{th}\) GPIO register and FSELn is the \(n^{th}\) GPIO pin. Edge of Raspberry Pi board is to the right.| GPIO | Header | GPIO | |||||
| Register | Bits | Pin | Pin | Pin | Bits | Register | |
| \(3.3\) volts | \(1\) | \(2\) | \(5.0\) volts | ||||
GPFSEL0 |
\(8-6\) | FSEL2 |
\(3\) | \(4\) | \(5.0\) volts | ||
GPFSEL0 |
\(11-9\) | FSEL3 |
\(5\) | \(6\) | ground | ||
GPFSEL0 |
\(14-12\) | FSEL4 |
\(7\) | \(8\) | FSEL14 |
\(14-12\) | GPFSEL1 |
| ground | \(9\) | \(10\) | FSEL15 |
\(17-15\) | GPFSEL1 |
||
GPFSEL1 |
\(23-21\) | FSEL17 |
\(11\) | \(12\) | FSEL18 |
\(26-24\) | GPFSEL1 |
GPFSEL2 |
\(23-21\) | FSEL27 |
\(13\) | \(14\) | ground | ||
GPFSEL2 |
\(8-6\) | FSEL22 |
\(15\) | \(16\) | FSEL23 |
\(11-9\) | GPFSEL2 |
| \(3.3\) volts | \(17\) | \(18\) | FSEL24 |
\(14-12\) | GPFSEL2 |
||
GPFSEL1 |
\(2-0\) | FSEL10 |
\(19\) | \(20\) | ground | ||
GPFSEL0 |
\(29-27\) | FSEL9 |
\(21\) | \(22\) | FSEL25 |
\(17-15\) | GPFSEL2 |
GPFSEL1 |
\(5-3\) | FSEL11 |
\(23\) | \(24\) | FSEL8 |
\(26-24\) | GPFSEL0 |
| ground | \(25\) | \(26\) | FSEL7 |
\(23-21\) | GPFSEL0 |
||
| do not connect | \(27\) | \(28\) | do not connect | ||||
GPFSEL0 |
\(17-15\) | FSEL5 |
\(29\) | \(30\) | ground | ||
GPFSEL0 |
\(20-18\) | FSEL6 |
\(31\) | \(32\) | FSEL12 |
\(8-6\) | GPFSEL1 |
GPFSEL1 |
\(11-9\) | FSEL13 |
\(33\) | \(34\) | ground | ||
GPFSEL1 |
\(29-27\) | FSEL19 |
\(35\) | \(36\) | FSEL16 |
\(20-18\) | GPFSEL1 |
GPFSEL2 |
\(20-18\) | FSEL26 |
\(37\) | \(38\) | FSEL20 |
\(2-0\) | GPFSEL2 |
| ground | \(39\) | \(40\) | FSEL21 |
\(5-3\) | GPFSEL2 |
||
GPFSELm is the \(m^{th}\) GPIO register and FSELn is the \(n^{th}\) GPIO pin. Edge of Raspberry Pi board is to the right.| GPIO | Header | GPIO | |||||
| Register | Bits | Pin | Pin | Pin | Bits | Register | |
| \(3.3\) volts | \(1\) | \(2\) | \(5.0\) volts | ||||
GPFSEL0 |
\(8-6\) | FSEL2 |
\(3\) | \(4\) | \(5.0\) volts | ||
GPFSEL0 |
\(11-9\) | FSEL3 |
\(5\) | \(6\) | ground | ||
GPFSEL0 |
\(14-12\) | FSEL4 |
\(7\) | \(8\) | FSEL14 |
\(14-12\) | GPFSEL1 |
| ground | \(9\) | \(10\) | FSEL15 |
\(17-15\) | GPFSEL1 |
||
GPFSEL1 |
\(23-21\) | FSEL17 |
\(11\) | \(12\) | FSEL18 |
\(26-24\) | GPFSEL1 |
GPFSEL2 |
\(23-21\) | FSEL27 |
\(13\) | \(14\) | ground | ||
GPFSEL2 |
\(8-6\) | FSEL22 |
\(15\) | \(16\) | FSEL23 |
\(11-9\) | GPFSEL2 |
| \(3.3\) volts | \(17\) | \(18\) | FSEL24 |
\(14-12\) | GPFSEL2 |
||
GPFSEL1 |
\(2-0\) | FSEL10 |
\(19\) | \(20\) | ground | ||
GPFSEL0 |
\(29-27\) | FSEL9 |
\(21\) | \(22\) | FSEL25 |
\(17-15\) | GPFSEL2 |
GPFSEL1 |
\(5-3\) | FSEL11 |
\(23\) | \(24\) | FSEL8 |
\(26-24\) | GPFSEL0 |
| ground | \(25\) | \(26\) | FSEL7 |
\(23-21\) | GPFSEL0 |
||
GPFSELm is the \(m^{th}\) GPIO register and FSELn is the \(n^{th}\) GPIO pin. Edge of Raspberry Pi board is to the right.| GPIO | Header | GPIO | |||||
| Register | Bits | Pin | Pin | Pin | Bits | Register | |
| \(3.3\) volts | \(1\) | \(2\) | \(5.0\) volts | ||||
GPFSEL0 |
\(2-0\) | FSEL0 |
\(3\) | \(4\) | \(5.0\) volts | ||
GPFSEL0 |
\(5-3\) | FSEL1 |
\(5\) | \(6\) | ground | ||
GPFSEL0 |
\(14-12\) | FSEL4 |
\(7\) | \(8\) | FSEL14 |
\(14-12\) | GPFSEL1 |
| ground | \(9\) | \(10\) | FSEL15 |
\(17-15\) | GPFSEL1 |
||
GPFSEL1 |
\(23-21\) | FSEL17 |
\(11\) | \(12\) | FSEL18 |
\(26-24\) | GPFSEL1 |
GPFSEL2 |
\(23-21\) | FSEL27 |
\(13\) | \(14\) | ground | ||
GPFSEL2 |
\(8-6\) | FSEL22 |
\(15\) | \(16\) | FSEL23 |
\(11-9\) | GPFSEL2 |
| \(3.3\) volts | \(17\) | \(18\) | FSEL24 |
\(14-12\) | GPFSEL2 |
||
GPFSEL1 |
\(2-0\) | FSEL10 |
\(19\) | \(20\) | ground | ||
GPFSEL0 |
\(29-27\) | FSEL9 |
\(21\) | \(22\) | FSEL25 |
\(17-15\) | GPFSEL2 |
GPFSEL1 |
\(5-3\) | FSEL11 |
\(23\) | \(24\) | FSEL8 |
\(26-24\) | GPFSEL0 |
| ground | \(25\) | \(26\) | FSEL7 |
\(23-21\) | GPFSEL0 |
||
Table 19.2.4 shows which bits in the GPIO function select registers control physical pins on the GPIO header.
GPFLSEL0–GPFLSEL2, 40-pin header.| Bits | ||||||||||
| GPIO Register | \(29-27\) | \(26-24\) | \(23-21\) | \(20-18\) | \(17-15\) | \(14-12\) | \(11-9\) | \(8-6\) | \(5-3\) | \(2-0\) |
GPFLSEL0 |
\(21\) | \(24\) | \(26\) | \(31\) | \(29\) | \(7\) | \(5\) | \(3\) | ||
GPFLSEL1 |
\(35\) | \(12\) | \(11\) | \(36\) | \(10\) | \(8\) | \(33\) | \(32\) | \(23\) | |
GPFLSEL2 |
\(13\) | \(37\) | \(22\) | \(18\) | \(16\) | \(15\) | \(40\) | \(38\) | ||
Table 19.2.5 shows the locations of the three GPIO registers that are used to select the pin functions Table 19.2.4.
| Name | Datasheet Address | GPIO Offset |
GPFSEL0 |
\(\hex{0x7e200000}\) | \(\hex{0x0000}\) |
GPFSEL1 |
\(\hex{0x7e200004}\) | \(\hex{0x0004}\) |
GPFSEL2 |
\(\hex{0x7e200008}\) | \(\hex{0x0008}\) |
Thus if we wish to access pin number 12 on the GPIO header, we need to access bits \(26\)–\(24\) at \(\hex{0x004}\) relative to virtual address in our program that we get from the call to the mmap function.
Using one of the pins in the header connection is a two-step process:
Select the function of the pin. Each connector pin can be selected to be either an input or an output. Most can also be selected for alternate functions, but we will not do so in this book.
Turn the pin on (Set) or off (Clear). There are two separate sets of GPIO registers for either setting a pin function or clearing it.
The first step can be accomplished as shown in Listing 19.2.6.
@ gpioPinFSelect.s
@ Selects a function for a GPIO pin. Assumes that GPIO registers
@ have been mapped to programming memory.
@ Calling sequence:
@ r0 <- address of GPIO in mapped memory
@ r1 <- pin number
@ r2 <- pin function
@ bl gpioPinFSelect
@ 2017-09-30: Bob Plantz
@ Define my Raspberry Pi
.cpu cortex-a53
.fpu neon-fp-armv8
.syntax unified @ modern syntax
@ Constants for assembler
.equ PIN_FIELD,0b111 @ 3 bits
@ The program
.text
.align 2
.global gpioPinFSelect
.type gpioPinFSelect, %function
gpioPinFSelect:
sub sp, sp, 24 @ space for saving regs
@ (keeping 8-byte sp align)
str r4, [sp, 4] @ save r4
str r5, [sp, 8] @ r5
str r6, [sp,12] @ r6
str fp, [sp, 16] @ fp
str lr, [sp, 20] @ lr
add fp, sp, 20 @ set our frame pointer
mov r4, r0 @ save pointer to GPIO
mov r5, r1 @ save pin number
mov r6, r2 @ save function code
@ Compute address of GPFSEL register and pin field
mov r3, 10 @ divisor
udiv r0, r5, r3 @ GPFSEL number
mul r1, r0, r3 @ compute remainder
sub r1, r5, r1 @ for GPFSEL pin
@ Set up the GPIO pin funtion register in programming memory
lsl r0, r0, 2 @ 4 bytes in a register
add r0, r4, r0 @ GPFSELn address
ldr r2, [r0] @ get entire register
mov r3, r1 @ need to multiply pin
add r1, r1, r3, lsl 1 @ position by 3
mov r3, PIN_FIELD @ gpio pin field
lsl r3, r3, r1 @ shift to pin position
bic r2, r2, r3 @ clear pin field
lsl r6, r6, r1 @ shift function code to pin position
orr r2, r2, r6 @ enter function code
str r2, [r0] @ update register
mov r0, 0 @ return 0;
ldr r4, [sp, 4] @ restore r4
ldr r5, [sp, 8] @ r5
ldr r6, [sp,12] @ r6
ldr fp, [sp, 16] @ fp
ldr lr, [sp, 20] @ lr
add sp, sp, 24 @ sp
bx lr @ return
Selecting the function of a pin involves working with three bits within a 32-bit register. We need to be careful not to disturb the other 29 bits in the register. The first step is to clear the bits within the desired 3-bit field. In the following code segment the value in register we are working with has been loaded into r2 and the pin number is in r1.
mov r3, r1 @ need to multiply pin add r1, r1, r3 1 @ position by 3 mov r3, PIN_FIELD @ gpio pin field lsl r3, r3, r1 @ shift to pin position bic r2, r2, r3 @ clear pin field
Multiplying the pin number by \(2\) (left shift one bit) and adding it to itself is a fast, simple way to multiply by \(3\text{.}\)
Clearing the three bits requires a new instruction, bic.
BIC-
Performs a bitwise AND between the NOT of a bit pattern and a value in a register, thus clearing the bits in the register as specified by the bit pattern.
BIC{S}{<c>} {<Rd>,} <Rn>, #<const> % immediate BIC{S}{<c>} {<Rd>,} <Rn>, <Rm>{, <shift>} % register BIC{S}{<c>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> % register-shifted registerIf ‘
S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.<c>is the condition code, Table 9.2.1.<Rd>specifies the destination register, and<Rm>and<Rn>are the source registers.<Rs>contains the shift amount in the “register-shifted register” form.\(-257 \le const \le +256\text{,}\) or \(const = +256, +260, +264, \ldots, +65280\text{,}\) or \(const = -261, -265, \ldots, -65281\text{.}\) This odd sequence of values will be explained in Section 11.3.3
<shift>and<type>are explained in Section 9.2.3
In the “immediate” form, a bitwise AND is performed between the NOT of
<const>and the value in<Rn>. In the “register” and “register-shifted register” forms, a bitwise AND is performed between the value in<Rn>and the NOT of the value in<Rm>. If a shift is specified, the value in<Rm>is shifted by the specified amount before the AND is performed. If<Rd>is present the result is stored there and<Rn>is unchanged. If not, the result is stored in<Rn>. The values in<Rm>and<Rs>are unchanged.
After the bit field has been cleared, we can now use orr to store the new function code in the 3-bit field without disturbing the other 29 bits:
lsl r6, r6, r1 @ shift function code to pin position orr r2, r2, r6 @ enter function code
For the second step, Table 19.2.7 shows the locations of the registers that are used to set or clear a pin once its function has been selected and the pin number that corresponds to each bit in the set and clear registers.
| Name | Datasheet Address | GPIO Offset | Bits | Corresponding Pins |
GPSET0 |
\(\hex{0x7e20001c}\) | \(\hex{0x001c}\) | \(\binary{31}\) – \(\binary{0}\) | \(31\) – \(0\) |
GPSET1 |
\(\hex{0x7e200020}\) | \(\hex{0x0020}\) | \(\binary{21}\) – \(\binary{0}\) | \(53\) – \(32\) |
GPCLR0 |
\(\hex{0x7e200028}\) | \(\hex{0x0028}\) | \(\binary{31}\) – \(\binary{0}\) | \(31\) – \(0\) |
GPCLR1 |
\(\hex{0x7e20002c}\) | \(\hex{0x002c}\) | \(\binary{21}\) – \(\binary{0}\) | \(53\) – \(32\) |
Setting a pin can be accomplished as shown in Listing 19.2.8.
@ gpioPinSet.s
@ Sets a GPIO pin. Assumes that GPIO registers
@ have been mapped to programming memory.
@ Calling sequence:
@ r0 <- address of GPIO in mapped memory
@ r1 <- pin number
@ bl gpioPinSet
@ 2017-09-30: Bob Plantz
@ Define my Raspberry Pi
.cpu cortex-a53
.fpu neon-fp-armv8
.syntax unified @ modern syntax
@ Constants for assembler
.equ PIN,1 @ 1 bit for pin
.equ PINS_IN_REG,32
.equ GPSET0,0x1c @ set register offset
@ The program
.text
.align 2
.global gpioPinSet
.type gpioPinSet, %function
gpioPinSet:
sub sp, sp, 16 @ space for saving regs
str r4, [sp, 0] @ save r4
str r5, [sp, 4] @ r5
str fp, [sp, 8] @ fp
str lr, [sp, 12] @ lr
add fp, sp, 12 @ set our frame pointer
add r4, r0, GPSET0 @ pointer to GPSET regs.
mov r5, r1 @ save pin number
@ Compute address of GPSET register and pin field
mov r3, PINS_IN_REG @ divisor
udiv r0, r5, r3 @ GPSET number
mul r1, r0, r3 @ compute remainder
sub r1, r5, r1 @ for relative pin position
lsl r0, r0, 2 @ 4 bytes in a register
add r0, r0, r4 @ address of GPSETn
@ Set up the GPIO pin funtion register in programming memory
ldr r2, [r0] @ get entire register
mov r3, PIN @ one pin
lsl r3, r3, r1 @ shift to pin position
orr r2, r2, r3 @ set bit
str r2, [r0] @ update register
mov r0, 0 @ return 0;
ldr r4, [sp, 0] @ restore r4
ldr r5, [sp, 4] @ r5
ldr fp, [sp, 8] @ fp
ldr lr, [sp, 12] @ lr
add sp, sp, 16 @ restore sp
bx lr @ return
It is important to understand that storing a \(\binary{0}\) in the bit position corresponding to a pin does not clear the pin. To clear a pin, you need to store a \(\binary{1}\) in the corresponding bit in the appropriate GPCLRn register. This eliminates the possiblity of accidentally clearing other pins while setting one pin. The clear operation operates in the same manner.
