|The Pico/W In C: Direct To Hardware|
|Tuesday, 21 February 2023|
Page 1 of 4
Sometimes you just have to go beyond the SDK and work with the hardware - it's not so difficult. This is an extract from the latest book in the I Programmer Library, all about the Pico/W in C.
Programming the Raspberry Pi Pico In C
By Harry Fairhead
Buy from Amazon.
Direct To The Hardware
The SDK provides functions to let you access most of the hardware features of the Pico. They are very simple wrappers around the basic mechanism of working with the hardware – memory-mapped registers. You might think that bypassing the SDK and doing the job directly via hardware access would be attractive because it is more efficient – it isn’t. The SDK is such a light wrapper over the hardware there is very little point in trying to gain the few fractions of a microsecond that direct access provides. The obvious reason for knowing how to use memory-mapped registers is for situations where the SDK doesn’t provide a function that does what you want – perhaps a better reason is just to know how things work!
In this chapter we take a look at how the Pico presents its hardware for you to use and how to access it via basic software.
Some processors have special ways of connecting devices, but the Pico’s processor uses the more common memory-mapping approach. In this, each external device is represented by a set of memory locations or “registers” that control it. Each bit in the register controls some aspect of the way the device behaves. Groups of bits also can be interpreted as short integers which set operating values or modes.
How do you access a register? Simply by storing the values in it or by assigning its value to a variable. This is nothing new in C. The big difference is that you now have to refer not to a memory location provided by the system, but to a fixed address provided by the documentation. You still use a pointer, but one that is initialized by a constant or literal. For example, if you look in the documentation you will find that the GPIO registers start at address 0x40014000. The registers are defined by their offset from this starting address.
So for example the table of GPIO registers starts:
You can see that there are two registers for each GPIO line from GP0 to GP29, one control register and one status register.
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:
#include <stdio.h> #include "pico/stdlib.h" int main()
This prints the current status of GP0 in binary. If you want to find the status of GPn you need to use address 0x40014000+2n.
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 ( Tuesday, 21 February 2023 )|