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_0000

This, 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