User avatar
TimG
Posts: 330
Joined: Tue Apr 03, 2012 12:15 am
Location: Switzerland

GPIO: switching between ALT functions

Mon Apr 01, 2013 3:05 pm

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.

User avatar
joan
Posts: 16247
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO: switching between ALT functions

Mon Apr 01, 2013 3:17 pm

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.

User avatar
TimG
Posts: 330
Joined: Tue Apr 03, 2012 12:15 am
Location: Switzerland

Re: GPIO: switching between ALT functions

Mon Apr 01, 2013 3:47 pm

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:

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/
gpio_alt.c:

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;
}

walt
Posts: 17
Joined: Wed Apr 02, 2014 3:32 am
Location: boston

Re: GPIO: switching between ALT functions

Tue Sep 30, 2014 6:18 am

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

User avatar
joan
Posts: 16247
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO: switching between ALT functions

Tue Sep 30, 2014 7:11 am

They are all gpio functions. Use input/output to set the two gpio functions not covered by alt0-alt5.

vvn2023
Posts: 33
Joined: Fri Dec 19, 2014 6:42 am

Re: GPIO: switching between ALT functions

Mon Feb 23, 2015 5:21 am

Hi,

Is there any API to set the alt function in the kernel code ie in machine driver?

Thanks,
vvn

msperl
Posts: 356
Joined: Thu Sep 20, 2012 3:40 pm

Re: GPIO: switching between ALT functions

Mon Feb 23, 2015 6:09 am

This kind of things would best get handled via device tree overlays - it then sets things up correctly on boot...

Martin

User avatar
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

Mon Feb 23, 2015 12:38 pm

msperl wrote:This kind of things would best get handled via device tree overlays - it then sets things up correctly on boot...

Martin
https://github.com/fivdi/onoff/wiki/Ena ... spberry-Pi
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.

malevil
Posts: 4
Joined: Mon Jun 06, 2016 7:34 pm

Re: GPIO: switching between ALT functions

Mon Jun 06, 2016 7:40 pm

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!

User avatar
joan
Posts: 16247
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO: switching between ALT functions

Mon Jun 06, 2016 8:09 pm

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!
There must be dozens of ways of doing this now.

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.

malevil
Posts: 4
Joined: Mon Jun 06, 2016 7:34 pm

Re: GPIO: switching between ALT functions

Mon Jun 06, 2016 8:24 pm

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...

User avatar
joan
Posts: 16247
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO: switching between ALT functions

Mon Jun 06, 2016 8:32 pm

malevil 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...
pigs m 18 5 # set GPIO18 to mode ALT5

malevil
Posts: 4
Joined: Mon Jun 06, 2016 7:34 pm

Re: GPIO: switching between ALT functions

Mon Jun 06, 2016 9:12 pm

joan wrote:
malevil 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...
pigs m 18 5 # set GPIO18 to mode ALT5
Thank you!
That works! :)

User avatar
Michiel O.
Posts: 178
Joined: Mon Dec 12, 2016 12:06 pm

Re: GPIO: switching between ALT functions

Mon Jul 22, 2019 6:23 am

joan wrote: From the command line you can use my pigs to start hardware PWM on the relevant GPIO.
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

User avatar
joan
Posts: 16247
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO: switching between ALT functions

Mon Jul 22, 2019 6:40 am

Thanks, have corrected the links.

Return to “Interfacing (DSI, CSI, I2C, etc.)”