Friday, May 27, 2016

Pulse any GPIO Pin from Bare Metal on a Raspberry Pi 3

Any of the usable GPIO pins on the Raspberry Pi model B can be pulsed from bare metal with a few changes to the code from the prior post. The following commands were used to compile this code on the Raspberry Pi 3 Model B.

$ arm-none-eabi-gcc -O2 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv8-a -mtune=cortex-a53 \ -nostartfiles pulse.c -o kernel.elf






-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

/* 
 * Bare Metal program for toggling any GPIO pin on the Raspberry Pi 3 Model B
 * Copyright (C) 05-27-2016  Bryan R. Hinton
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#define GPIO_BASE  0x3f200000 /* GPIO base address for rpi3 */
#define GPSET0_OFFSET  0x07    /* GPIO Pin Output Set 0 Offset */
#define GPCLR0_OFFSET  0x0a    /* GPIO Pin Output Clear 0 Offset */
#define MAXPINCNT 26

int main(void)
{
   /* static const array of usable gpio pins on raspberry pi 3 */
   static const unsigned int gpiopin[MAXPINCNT] =  {2,3,4,17,27,22,10,9,11,5,6,\
                                   13,19,26,14,15,18,23,24,25,8,7,12,16,20,21};

   /* select pin index */
   int pinidx = 1;

   /* setup gpio base address */
   volatile unsigned int *gpio_base = (unsigned int *)GPIO_BASE;

  /* set gpio(n) for input by clearing bits (GPIO_PIN%10)*3 GPFSEL(N)
   * where (GPIO_PIN%10)*3 is FSEL(N) or the three configuration bits for GPIO(N)
   * 1. Find the gpio function select(gpfsel) register for the GPIO pin.
   *  Pins 0-9 use gpfsel 0
   *  Pins 10-19 use gpfsel 1
   *  Pins 20-29 use gpfsel 2
   *  Pins 30-39 use gpfsel 3
   *  Pins 40-49 use gpfsel 4
   *  Pins 50-53 use gpfsel 5
   * 2. Set or Clear the function select bits in that register for the designated gpio pin
   *  gpio pin 5 is set for input in gpfsel 0 by clearing bits 15-17  
   *  gpio pin 5 is set for output in gpfsel 0 by setting bits 15-17 to 001  
   *  gpio pin 22 is set for input in gpfsel 2 by clearing bits 6-8  
   *  gpio pin 22 is set for output in gpfsel 2 by setting bits 6-8 to 001 */

  /*  set gpiopin[pinidx] for input by clearing bits k,k+1,K+2 in gpfsel n.
   *  gpfsel(2) gpiopin 22 bit string mask for gp input 11111111111111111111111000111111 (rval)
   *  gpfsel(0) gpiopin 3 bit string mask for gp input 11111111111111111111000111111111 (rval) */
   *(gpio_base + (*(gpiopin+pinidx)%10)) &= ~(7  < ((*(gpiopin+pinidx)%10)*3));

  /*  set gpiopin[pinidx] for output by setting bits k,k+1,k+2 to 001 in gpfsel n.
   *  gpfsel(2) gpiopin 22 bit string mask for gp output 00000000000000000000000001000000 (rval)
   *  gpfsel(2) gpiopin 3 bit string mask for gp output 00000000000000000000001000000000 (rval) */
   *(gpio_base + (*(gpiopin+pinidx)%10)) |= (1 << ((*(gpiopin+pinidx)%10)*3));

   /* iterate through each usable gpio pin and pulse it */
   while(1) {

      /* set gpio pin */
      *(gpio_base + GPSET0_OFFSET) |= (1 << (*(gpiopin+pinidx)));

      /* clear gpio pin */
      *(gpio_base + GPCLR0_OFFSET) &= (1 << (*(gpiopin+pinidx)));
   }
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJXSN4dAAoJEKJTsaf+3Ky+11EP/3uf38uUC7SbyAE5Jp0SwfMC
YhIgC92Erb4A5OKK9dOx7FzCgwCdU7ifoCjPcjZonxkFqMt/lEpFa7MaqHqpsUWt
vxHmXHx5V/9WCVAy8acunAlVcWhimls9dqJni5gfIpSH80C1Nvph14UTgYB3ejs+
onCsipkIqK4/YOih58ZNqHYOleVvX8DpQvnY+mGgqYzuhITtOddgYmgmwK3FOy6s
1EjP3xLo3ovs1FGX11j/ZRdlpoh1MnivJtUNIuTXMv+4BYKv8asQbDdukkYYRM+L
VEulKrjYveJZtiWElZ0csL1sMoeBZV4pWsKhtriWcS08XsscqJXc2D8RrlgbrR08
MhoKYoXUZcAxH6pXJC6KkI/pIITKkhqzO+XgoOL+VLiUqldMu00sWUuk9muHx4EH
jtSxpI9aQZOiNwDe+iomOsIfwFA5Zon6TAga0EesMUDGRt9/qlYM2y7nwooOZAkD
/Jinz/QmYp9+bRkxDMUiBm8zwa4o6EkfycJ33Sye4fviwmjwUgftBUPKWgCDldac
Qk7VbMSzjlyJ/wPOOIGEppDcQXwwH87d1TOwy+sr2OLjO2eZpAs7P6ZgV9YNcVvA
CZKGPD6fZm5jkVYjNjbxyHk517uuCIUWYptCFFPUnNbCPvLl3klsBasStG+7HJCP
/IPgYPuswmijA06lAC4I
=y2H9
-----END PGP SIGNATURE-----


Github Repo

No comments:

Post a Comment