kstmApp/src/pi_2_mmio.c
author Heinz Junkes <junkes@fhi-berlin.mpg.de>
Mon, 09 Jul 2018 13:36:24 +0200
changeset 4 f7598b2df637
parent 0 bd6bb22c6533
permissions -rw-r--r--
update
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     1
// Copyright (c) 2014 Adafruit Industries
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     2
// Author: Tony DiCola
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     3
// Based on code from Gert van Loo & Dom: http://elinux.org/RPi_Low-level_peripherals#GPIO_Code_examples
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     4
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     5
// Permission is hereby granted, free of charge, to any person obtaining a copy
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     6
// of this software and associated documentation files (the "Software"), to deal
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     7
// in the Software without restriction, including without limitation the rights
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
     9
// copies of the Software, and to permit persons to whom the Software is
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    10
// furnished to do so, subject to the following conditions:
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    11
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    12
// The above copyright notice and this permission notice shall be included in all
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    13
// copies or substantial portions of the Software.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    14
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    21
// SOFTWARE.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    22
#include <fcntl.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    23
#include <stdlib.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    24
#include <stdio.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    25
#include <string.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    26
#include <sys/mman.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    27
#include <sys/stat.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    28
#include <sys/types.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    29
#include <unistd.h>
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    30
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    31
#include "pi_2_mmio.h"
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    32
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    33
#define GPIO_BASE_OFFSET 0x200000
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    34
#define GPIO_LENGTH 4096
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    35
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    36
volatile uint32_t* pi_2_mmio_gpio = NULL;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    37
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    38
int pi_2_mmio_init(void) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    39
  if (pi_2_mmio_gpio == NULL) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    40
    // Check for GPIO and peripheral addresses from device tree.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    41
    // Adapted from code in the RPi.GPIO library at:
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    42
    //   http://sourceforge.net/p/raspberry-gpio-python/
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    43
    FILE *fp = fopen("/proc/device-tree/soc/ranges", "rb");
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    44
    if (fp == NULL) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    45
      return MMIO_ERROR_OFFSET;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    46
    }
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    47
    fseek(fp, 4, SEEK_SET);
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    48
    unsigned char buf[4];
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    49
    if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf)) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    50
      return MMIO_ERROR_OFFSET;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    51
    }
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    52
    uint32_t peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    53
    uint32_t gpio_base = peri_base + GPIO_BASE_OFFSET;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    54
    fclose(fp);
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    55
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    56
    int fd = open("/dev/mem", O_RDWR | O_SYNC);
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    57
    if (fd == -1) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    58
      // Error opening /dev/mem.  Probably not running as root.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    59
      return MMIO_ERROR_DEVMEM;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    60
    }
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    61
    // Map GPIO memory to location in process space.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    62
    pi_2_mmio_gpio = (uint32_t*)mmap(NULL, GPIO_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, gpio_base);
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    63
    close(fd);
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    64
    if (pi_2_mmio_gpio == MAP_FAILED) {
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    65
      // Don't save the result if the memory mapping failed.
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    66
      pi_2_mmio_gpio = NULL;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    67
      return MMIO_ERROR_MMAP;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    68
    }
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    69
  }
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    70
  return MMIO_SUCCESS;
bd6bb22c6533 First import
Heinz Junkes <junkes@fhi-berlin.mpg.de>
parents:
diff changeset
    71
}