Dear Group,
I'm looking for a command-line utility to switch GPIO pins between their alternative functions. Does such a thing exist?
So far I've only found C code, mostly variations on this from Gert & Dom:
http://elinux.org/RPi_Low-level_peripherals#C_2
I don't mind wrapping this up into something which can be called from a Bash script, but I thought I'd ask if somebody has done it already.
Re: GPIO: switching between ALT functions
Not that I'm aware of. WiringPi gpio command line lets you set input or output or pwm. I know of nothing which allows the setting of a gpio to any of its 8 modes from the command line.
Re: GPIO: switching between ALT functions
OK. Well I put the code from http://elinux.org/RPi_Low-level_peripherals#C_2 in a simple wrapper and it seems to work ok. I've copied it below for comments & suggestions.
-Tim
Compile as follows:
gpio_alt.c:
-Tim
Compile as follows:
Code: Select all
gcc -o gpio_alt gpio_alt.c
sudo chown root:root gpio_alt
sudo chmod u+s gpio_alt
sudo mv gpio_alt /usr/local/bin/
Code: Select all
/*
Utility to switch Raspberry-Pi GPIO pin functions
Tim Giles 01/04/2013
Usage:
$ gpio_alt -p PIN_NUMBER -f ALT_NUMBER
Based on RPi code from Dom and Gert, 15-Feb-2013, <http://elinux.org/RPi_Low-level_peripherals#C_2>
and Gnu getopt() example <http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt>
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
int mem_fd;
void *gpio_map;
volatile unsigned *gpio;
void setup_io();
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
int main (int argc, char **argv) {
int opt, flag, n_pin, n_alt;
flag=0;
while ((opt = getopt (argc, argv, "hp:f:")) != -1) {
switch (opt) {
case 'h':
break;
case 'p':
n_pin = atoi(optarg); flag |= 0b0001; break;
case 'f':
n_alt = atoi(optarg); flag |= 0b0010; break;
case '?':
// getopt() prints error messages, so don't need to repeat them here
return 1;
default:
abort ();
}
}
if (flag != 0b0011) {
fprintf (stderr, "Usage:\n$ gpio_alt -p PIN_NUM -f FUNC_NUM\n");
return 1;
}
setup_io(); // Set up gpi pointer for direct register access
INP_GPIO(n_pin); // Always use INP_GPIO(x) before using SET_GPIO_ALT(x,y)
SET_GPIO_ALT(n_pin, n_alt);
printf("Set pin %i to alternative-function %i\n", n_pin, n_alt);
return 0;
}
void setup_io() {
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap GPIO */
gpio_map = mmap(
NULL, //Any adddress in our space will do
BLOCK_SIZE, //Map length
PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
MAP_SHARED, //Shared with other processes
mem_fd, //File to map
GPIO_BASE //Offset to GPIO peripheral
);
close(mem_fd); //No need to keep mem_fd open after mmap
if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map);//errno also set!
exit(-1);
}
// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;
}
Re: GPIO: switching between ALT functions
Great. I follow your steps, and PWM0, 1 on GPIO12 / 13 are worked as alt0 function.
Thank you .
But I have a little question, how to roll back to GPIO function. From datasheet, alt0 --alt5 is other functions, so what value of ALT_NUMBER should be for GPIO?
gpio_alt -p PIN_NUMBER -f ALT_NUMBER
Thank you .
But I have a little question, how to roll back to GPIO function. From datasheet, alt0 --alt5 is other functions, so what value of ALT_NUMBER should be for GPIO?
gpio_alt -p PIN_NUMBER -f ALT_NUMBER
Re: GPIO: switching between ALT functions
They are all gpio functions. Use input/output to set the two gpio functions not covered by alt0-alt5.
Re: GPIO: switching between ALT functions
Hi,
Is there any API to set the alt function in the kernel code ie in machine driver?
Thanks,
vvn
Is there any API to set the alt function in the kernel code ie in machine driver?
Thanks,
vvn
Re: GPIO: switching between ALT functions
This kind of things would best get handled via device tree overlays - it then sets things up correctly on boot...
Martin
Martin
- DougieLawson
- Posts: 42644
- Joined: Sun Jun 16, 2013 11:19 pm
- Location: A small cave in deepest darkest Basingstoke, UK
Re: GPIO: switching between ALT functions
https://github.com/fivdi/onoff/wiki/Ena ... spberry-Pimsperl wrote:This kind of things would best get handled via device tree overlays - it then sets things up correctly on boot...
Martin
Languages using left-hand whitespace for syntax are ridiculous
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
DMs sent on https://twitter.com/DougieLawson or LinkedIn will be answered next month.
Fake doctors - are all on my foes list.
The use of crystal balls and mind reading is prohibited.
Re: GPIO: switching between ALT functions
Thanks for the GPIO ALT switching code! It's been working for me nice on my RPi 2.
Unfortunately on my RPi 3 I wanted to reproduce the same ALT switching, but doesn't work
Neither found a proper GPIO map for RPi 3 with all the ALT functions, so I cannot validate if it's changed.
I'm wanted to use the GPIO 18 / ALT5 PWM function. Does anyone else has experience about this on RPi 3?
Should I use different code for switching or the GPIO mapping changed?
" pi@raspberrypi:~ $ gpio_alt -p 18 -f 5 "
Thanks!
Unfortunately on my RPi 3 I wanted to reproduce the same ALT switching, but doesn't work

Neither found a proper GPIO map for RPi 3 with all the ALT functions, so I cannot validate if it's changed.
I'm wanted to use the GPIO 18 / ALT5 PWM function. Does anyone else has experience about this on RPi 3?
Should I use different code for switching or the GPIO mapping changed?
" pi@raspberrypi:~ $ gpio_alt -p 18 -f 5 "
Thanks!
Re: GPIO: switching between ALT functions
There must be dozens of ways of doing this now.malevil wrote:Thanks for the GPIO ALT switching code! It's been working for me nice on my RPi 2.
Unfortunately on my RPi 3 I wanted to reproduce the same ALT switching, but doesn't work![]()
Neither found a proper GPIO map for RPi 3 with all the ALT functions, so I cannot validate if it's changed.
I'm wanted to use the GPIO 18 / ALT5 PWM function. Does anyone else has experience about this on RPi 3?
Should I use different code for switching or the GPIO mapping changed?
" pi@raspberrypi:~ $ gpio_alt -p 18 -f 5 "
Thanks!
From the command line you can use my pigs to start hardware PWM on the relevant GPIO.
Last edited by joan on Mon Jul 22, 2019 6:39 am, edited 1 time in total.
Re: GPIO: switching between ALT functions
Actually I'm routing the systems audio PWM signal there. It's works on RPi 2 as I described but not on RPi 3 for some reason...
Re: GPIO: switching between ALT functions
pigs m 18 5 # set GPIO18 to mode ALT5malevil wrote:Actually I'm routing the systems audio PWM signal there. It's works on RPi 2 as I described but not on RPi 3 for some reason...
Re: GPIO: switching between ALT functions
Thank you!joan wrote:pigs m 18 5 # set GPIO18 to mode ALT5malevil wrote:Actually I'm routing the systems audio PWM signal there. It's works on RPi 2 as I described but not on RPi 3 for some reason...
That works!

- Michiel O.
- Posts: 178
- Joined: Mon Dec 12, 2016 12:06 pm
Re: GPIO: switching between ALT functions
Correction:
The link you gave, http://abyz.co.uk/rpi/pigpio/pigs.html , seems to redirect to a website with articles abount all kinds of random things. I think the correct URLs would be http://abyz.me.uk/rpi/pigpio/pigs.html and http://abyz.me.uk/rpi/pigpio/pigs.html#HP
"You can't actually make computers run faster, you can only make them do less." - RiderOfGiraffes
Re: GPIO: switching between ALT functions
Thanks, have corrected the links.