Always a fan of timely posts, I decided I should share some knowledge about the Raspberry Pi 1 GPIO controller layout. AKA the Broadcom SoC BCM2835 GPIO controller.
This week I’ve been revisiting Alex Chadwick’s excellent Baking Pi course.
Yes, I still have my original Raspberry Pi 1 Model B. Though It’s been a while since I’ve used it. And so, to scratch a bit of a nostalgic itch, and also to brush up on my ARM assembly, I decided to revisit the course.
The first thing I struggled with was understanding what all the values I was being told to usin my assembly to interact with the GPIO controller actually meant. Though Alex does a great job of simplifying the explanation of the way the GPIO controller works, I still felt like I needed to understand better what the structure of the GPIO controller was.
The course helpfully provides a simple figure explaining the layout. I felt I still needed to better visualize the structure of controller to understand why the values I was being told to use were what they were.
Being a fairly visual learner, I turned to the datasheet for the SoC (which is helpfully included in the course materials) and cross referenced it with the explanation in the course to produce the following layout:
GPIO Controller Layout:
Bits High - Low:
31---------------------------------------0
------------------------------------------------------
GPFSEL0:
bytes 9 8 7 6 5 4 3 2 1 0
0-3 | | | | | | | | | |
0x20200000: 00 000 000 000 000 000 000 000 000 000 000
GPFSEL1:
bytes 19 18 17 16 15 14 13 12 11 10
4-7 | | | | | | | | | |
0x20200004: 00 000 000 000 000 000 000 000 000 000 000
GPFSEL2:
bytes 29 28 27 26 25 24 23 22 21 20
8-11 | | | | | | | | | |
0x20200008: 00 000 000 000 000 000 000 000 000 000 000
GPFSEL3:
bytes 39 38 37 36 35 34 33 32 31 30
12-15 | | | | | | | | | |
0x2020000C: 00 000 000 000 000 000 000 000 000 000 000
GPFSEL4:
bytes 49 48 47 46 45 44 43 42 41 40
16-19 | | | | | | | | | |
0x20200010: 00 000 000 000 000 000 000 000 000 000 000
GPFSEL5:
bytes 53 52 51 50
20-23 | | | |
0x20200014: 00 000 000 000 000 000 000 000 000 000 000
RESERVED:
bytes
24-27
0x20200018: 0000_0000 0000_0000 0000_0000 0000_0000
GPSET0:
bytes
28-31 31---------------------------------------0
0x2020001C: 0000_0000 0000_0000 0000_0000 0000_0000
GPSET1:
bytes
32-35 53-------------------------32
0x20200020: 0000_0000 0000_0000 0000_0000 0000_0000
RESERVED:
bytes
36-39
0x20200024: 0000_0000 0000_0000 0000_0000 0000_0000
GPCLR0:
bytes
40-43 31---------------------------------------0
0x20200028: 0000_0000 0000_0000 0000_0000 0000_0000
GPCLR1:
bytes
44-47 53-------------------------32
0x2020002C: 0000_0000 0000_0000 0000_0000 0000_0000
RESERVED:
bytes
48-51
0x20200030: 0000_0000 0000_0000 0000_0000 0000_0000
GPLEV0:
bytes
52-55 31---------------------------------------0
0x20200034: 0000_0000 0000_0000 0000_0000 0000_0000
GPLEV1:
bytes
56-59 53-------------------------32
0x20200038: 0000_0000 0000_0000 0000_0000 0000_0000This, of course, does not the entire GPIO controller (only the parts that are relevant to the course). But hopefully it helps others understand the layout a bit better too.
While putting this together, I also realized that part of my confusion was caused because sometimes it wasn’t clear when the course was referring to the pins or bytes by their ordinal number or their index (starting at zero). So acutally mapping it out helped me understand that better too.
Function Select:
The first section (GPFSEL0-GPFSEL5) needs a little more explanation.
The frist 21 and 1/2 bytes of the GPIO controller are used to configure the function of the GPIO pins. Each pin has 3 bits to configure its function. The first 10 pins are configured in GPFSEL0, the next 10 in GPFSEL1, and so on.
Each pin’s function select bits can be used with the following values to configure the pin’s behavior.
000 = GPIO Pin is an input
001 = GPIO Pin is an output
100 = GPIO Pin takes alternate function 0
101 = GPIO Pin takes alternate function 1
110 = GPIO Pin takes alternate function 2
111 = GPIO Pin takes alternate function 3
011 = GPIO Pin takes alternate function 4
010 = GPIO Pin takes alternate function 5