Raspberry Pi IoT In C - Pi 5 Memory Mapped GPIO |
Written by Harry Fairhead | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Wednesday, 10 January 2024 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Page 2 of 4
Each register has the same format for each GPIO line. For example, the status register is:
You can see that many of the 32 bits in the register are not used, but bit 9 is OUTTOPAD which is the final state of the GPIO line after register overrides have been applied. You can read its current value using:
uint32_t *PERIBase = map; uint32_t *GPIOBase = PERIBase + 0xd0000 / 4; int pin = 0; volatile uint32_t *addrGP0Status = This prints the current status of GP0 in binary. You can read the value of the bits to check that they correspond to what you would expect from the known status of the line. In most cases it is better to associate more familiar C data types with the memory area referenced. For example, the set of GPIO registers in which each status register is followed by the corresponding control register – is like an array of structs. For example: typedef struct{ uint32_t status; uint32_t ctrl; }GPIOregs; #define GPIO ((GPIOregs*)GPIOBase) This allows you to treat GPIO as an array of register structs and it allows the previous program to be written as: uint32_t *PERIBase = map; uint32_t *GPIOBase = PERIBase + 0xD0000 / 4; int pin=2; volatile uint32_t *addrGP0Status = The expression: GPIO[pin].status expands to: ((GPIOregs*)GPIOBase)[pin].status This is the general way you work with peripheral devices such as the PWM units or I2C hardware, but the GPIO is special in that it has another set of registers that control it. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Last Updated ( Wednesday, 10 January 2024 ) |