Raspberry Pi 5 IoT In C - Gpio5
Written by Harry Fairhead   
Tuesday, 01 April 2025
Article Index
Raspberry Pi 5 IoT In C - Gpio5
Initializing GPIO
PAD Configuration
Examples

Examples

With Gpio5 available it is very easy to write blinky by typing in a program targeting the Pico:

#include <stdio.h>
#include <stdlib.h>
#include "Gpio5.h"
int main(int argc, char **argv)
{
    rp1_Init();
    gpio_init(2);
    gpio_set_dir(2, true);
    while (true)
    {
        gpio_put(2, 1);
        sleep(1);
        gpio_put(2, 0);
        sleep(1);
    }
    return (EXIT_SUCCESS);
}

The only change that was required was adding the call to rp1_Init().


If you remove the sleep function calls then you will discover that the fastest pulses you can create using Gpio5 is 24ns which is comparable to the direct approach given earlier:

Gpio5ex1

Another Pico program that runs without modification is to produce two pulses out of phase:

#include <stdio.h>
#include <stdlib.h>
#include "Gpio5.h"
int main(int argc, char **argv)
{
  int pin1 = 4;
  int pin2 = 2;
  rp1_Init();
  gpio_init(pin1);
  gpio_set_dir(pin1, true);
  gpio_init(pin2);
  gpio_set_dir(pin2, true);
  uint32_t mask = (1 << pin1) | (1 << pin2);
  uint32_t value1 = 1 << pin1;
  uint32_t value2 = 1 << pin2;
  while (true)
  {
    gpio_put_masked(mask, value1);
    gpio_put_masked(mask, value2);
  }
  return (EXIT_SUCCESS);


}

The only change needed was the addition of the call to rp1_Init(). However, if you look at the output:

Gpio5ex2

you will notice that the speed has reduced to 1.14µs. This is because of setting the state of the two lines at the same time without changing the other lines. The slowdown is due to the need to read the RIO. If you set the lines without worrying about reading the state of the other lines then you get back to 24ns pulses.

Finally, here’s an example of using a GPIO line as input:

#include <stdio.h>
#include <stdlib.h>
#include "Gpio5.h"
int main(int argc, char **argv)
{
  int pin1 = 4;
  int pin2 = 2;
  rp1_Init();
  gpio_init(pin1);
  gpio_set_dir(pin1, false);
  gpio_pull_up(pin1);
  gpio_init(pin2);
  gpio_set_dir(pin2, true);
  while (true)
  {
    if (gpio_get(pin1))
    {
      gpio_put(pin2, 0);
    }
    else
    {
      gpio_put(pin2, 1);
    }
  }
  return (EXIT_SUCCESS);
}

Again, the program is unchanged from a Pico program, except for the addition of rp1_Init().
As the internal pull-up resistor is used, the switch can be connected to the line and ground without any external resistors:

The program simply tests for the line, GPIO4, to be pulled low by the switch being closed and then sets GPIO2 high. If you connect GPIO2 to an LED or a logic analyzer you will see the effect of the button being closed – the LED will light up while it is pressed. That is, GPIO2 is set high when GPIO4 is pulled low by the switch.


If you change gpio_pull_up(pin1) to gpio_pull_down(pin1), the way the switch is connected becomes:

The program still works, but now GPIO2 is only high when the switch is pressed and hence, with no other changes to the program, the LED is on when the switch is not pressed.

Interrupts?

You may be wondering why the extensive list of Pico GPIO interrupt functions have not been added to Gpio5? The reason is that interrupts in Linux user space are not a good idea. It is part of the cost of using a complete operating system like Linux that things like raw interrupts are not allowed. In particular, the Linux kernel isn’t re-entrant and so a hardware interrupt that Linux knows nothing about, and could occur when the Linux kernel is running, is a very bad idea.

The proper way to implement GPIO interrupts so as to integrate with Linux is to write a kernel driver that allows you to use epolling to wait on a file handle, as is done in gpiod. This is a fairly large task and raises the question, why not simply use gpiod? Another alternative to using interrupts is simply to create a thread to monitor by polling a GPIO line and then use this to call an event function as needed.

Having said all of this, it is possible to work with raw GPIO interrupts, but there are some important restrictions. The first is that any interrupt handler should run for as short a time as possible and should not make any Linux system calls. This generally means that the interrupt routine cannot call any library functions that in turn make Linux system calls. Overall, this makes working with raw GPIO interrupts error prone and generally not very useful.

Summary

  • The Pi 5 has its peripherals implemented by the custom RP1 chip and this makes it incompatible with all previous versions of the Raspberry Pi.

  • The memory map and the register configurations are different to other Pis and more like those found in the Pico.

  • You can still work with the Pi 5’s registers using the standard memory-mapping techniques.

  • The /dev/mem device accesses all of the memory, but needs root privileges.

  • The /dev/gpiomem0 device only provides the GPIO registers, but it can be used without root privileges.

  • The Pi 5 uses the same RIO-based GPIO implementation as the Pico. To use the GPIO lines you first have to select RIO mode.

  • Each GPIO line also has a PAD and a PAD control register.

  • The RIO registers are used to control and read the state of the GPIO line.

  • Using direct register access, the Pi 5 can produce well-formed 25ns pulses

  • Although using the registers directly is a good way to get started, creating functions, and hence a library to do the same job, is a good idea.

  • The Gpio5 library is based on the Pico SDK GPIO functions and it allows you to run Pico GPIO programs with little modification.

  • Working with raw interrupts under Linux is not easy and best avoided.

Raspberry Pi 5 IoT In C
Drivers and Gpio5

By Harry Fairhead

CIoTPi5360
Buy from Amazon.

Contents

  1. The Pi 5 For The IoT
  2. C and Visual Studio Code
  3. Drivers: A First Program
  4. The GPIO Character Drive
  5. GPIO Using I/O Control
  6. GPIO Events
  7. GPIO Hardware With Gpio5
         Extract: GPIO Registers
         Extract: GPIO5 ***NEW!
  8. Some Electronics
  9. The Device Tree
  10. Pulse Width Modulation
  11. SPI Devices
  12. I2C Driver and Gpio5
  13. Sensor Drivers – Linux IIO & hwmon
  14. 1-Wire Bus
  15. The PIO 313
  16. Going Further With Drivers
  17. Appendix I Gpio5

 <ASIN:1871962943>

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Microsoft Announces Hyperlight Wasm
01/04/2025

Microsoft has released Hyperlight Wasm, a Hyperlight virtual machine (VM) "micro-guest" that can run Wasm component workloads written in many programming languages.



Software Security Report Finds Third Party Code Most Problematic
12/03/2025

 

The latest edition of Veracode's annual State of Software Security report has identified that 80% of the applications tested over the last year have at least one security flaw, and just u [ ... ]


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Tuesday, 01 April 2025 )