#include <stdio.h>
#include <stdlib.h>

#include <stdint.h>
#include <fcntl.h>

#include <sys/mman.h>

#define BLOCK_SIZE              (4*1024)

/* The base address of the GPIO peripheral (ARM Physical Address) */
#define GPIO_BASE       0x3F200000UL

#define LED_GPFSEL      GPIO_GPFSEL4
#define LED_GPFBIT      21
#define LED_GPSET       GPIO_GPSET1
#define LED_GPCLR       GPIO_GPCLR1
#define LED_GPIO_BIT    15

#define GPIO_GPFSEL0    0
#define GPIO_GPFSEL1    1
#define GPIO_GPFSEL2    2
#define GPIO_GPFSEL3    3
#define GPIO_GPFSEL4    4
#define GPIO_GPFSEL5    5

#define GPIO_GPSET0     7
#define GPIO_GPSET1     8

#define GPIO_GPCLR0     10
#define GPIO_GPCLR1     11

#define PAUSE 10000000

/** GPIO Register set */
volatile unsigned int* gpio;

/** Simple loop variable */
volatile unsigned int tim;



/** Main function - we'll never return from here */
int main(void)
{  int fd;

   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
   {  printf("can't open /dev/mem\n"); exit(0); }
   gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
   if((int)gpio==-1)

   {  printf("can't mmap\n"); exit(0); }


    /* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO
       peripheral register to enable GPIO16 as an output */

    gpio[LED_GPFSEL] |= (1 << LED_GPFBIT); 

    /* Never exit as there is no OS to exit to! */
    while(1)
    {
        for(tim = 0; tim < PAUSE; tim++)
            ;

        /* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
           for plus models )*/
        gpio[LED_GPCLR] = (1 << LED_GPIO_BIT); 

        for(tim = 0; tim < PAUSE; tim++)
            ;

        /* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
           for plus models )*/
        gpio[LED_GPSET] = (1 << LED_GPIO_BIT); 
    }
}
