Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to raspberry-gpio-python version 0.7. #20

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 62 additions & 49 deletions ext/rpi_gpio/c_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Original code by Ben Croston modified for Ruby by Nick Lowery
(github.com/clockvapor)
Copyright (c) 2014-2016 Nick Lowery

Copyright (c) 2013-2015 Ben Croston
Copyright (c) 2013-2019 Ben Croston

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down Expand Up @@ -47,6 +47,11 @@ SOFTWARE.
#define PULLUPDN_OFFSET 37 // 0x0094 / 4
#define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4

#define PULLUPDN_OFFSET_2711_0 57
#define PULLUPDN_OFFSET_2711_1 58
#define PULLUPDN_OFFSET_2711_2 59
#define PULLUPDN_OFFSET_2711_3 60

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

Expand All @@ -65,7 +70,7 @@ int setup(void)
{
int mem_fd;
uint8_t *gpio_mem;
uint32_t peri_base;
uint32_t peri_base = 0;
uint32_t gpio_base;
unsigned char buf[4];
FILE *fp;
Expand All @@ -76,8 +81,7 @@ int setup(void)
// try /dev/gpiomem first - this does not require root privs
if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0)
{
gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0);
if ((uint32_t)gpio_map < 0) {
if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) {
return SETUP_MMAP_FAIL;
} else {
return SETUP_OK;
Expand All @@ -99,8 +103,7 @@ int setup(void)
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
return SETUP_CPUINFO_FAIL;

while(!feof(fp) && !found) {
fgets(buffer, sizeof(buffer), fp);
while(!feof(fp) && !found && fgets(buffer, sizeof(buffer), fp)) {
sscanf(buffer, "Hardware : %s", hardware);
if (strcmp(hardware, "BCM2708") == 0 || strcmp(hardware, "BCM2835") == 0) {
// pi 1 hardware
Expand All @@ -117,26 +120,22 @@ int setup(void)
return SETUP_NOT_RPI_FAIL;
}

if (!peri_base)
return SETUP_NOT_RPI_FAIL;
gpio_base = peri_base + GPIO_BASE_OFFSET;

// mmap the GPIO memory registers
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
return SETUP_DEVMEM_FAIL;
}

if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
return SETUP_MALLOC_FAIL;
}

if ((uint32_t)gpio_mem % PAGE_SIZE) {
gpio_mem += PAGE_SIZE - ((uint32_t) gpio_mem % PAGE_SIZE);
}

gpio_map = (uint32_t *) mmap((void *) gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base);
if ((uint32_t)gpio_mem % PAGE_SIZE)
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);

if ((uint32_t) gpio_map < 0) {
if ((gpio_map = (uint32_t *)mmap( (void *)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base)) == MAP_FAILED)
return SETUP_MMAP_FAIL;
}

return SETUP_OK;
}
Expand All @@ -158,9 +157,8 @@ int eventdetected(int gpio)
offset = EVENT_DETECT_OFFSET + (gpio/32);
bit = (1 << (gpio%32));
value = *(gpio_map+offset) & bit;
if (value) {
if (value)
clear_event_detect(gpio);
}
return value;
}

Expand All @@ -169,11 +167,10 @@ void set_rising_event(int gpio, int enable)
int offset = RISING_ED_OFFSET + (gpio/32);
int shift = (gpio%32);

if (enable) {
if (enable)
*(gpio_map+offset) |= 1 << shift;
} else {
else
*(gpio_map+offset) &= ~(1 << shift);
}
clear_event_detect(gpio);
}

Expand All @@ -196,11 +193,10 @@ void set_high_event(int gpio, int enable)
int offset = HIGH_DETECT_OFFSET + (gpio/32);
int shift = (gpio%32);

if (enable) {
if (enable)
*(gpio_map+offset) |= (1 << shift);
} else {
else
*(gpio_map+offset) &= ~(1 << shift);
}
clear_event_detect(gpio);
}

Expand All @@ -209,33 +205,51 @@ void set_low_event(int gpio, int enable)
int offset = LOW_DETECT_OFFSET + (gpio/32);
int shift = (gpio%32);

if (enable) {
if (enable)
*(gpio_map+offset) |= 1 << shift;
} else {
else
*(gpio_map+offset) &= ~(1 << shift);
}
clear_event_detect(gpio);
}

void set_pullupdn(int gpio, int pud)
{
int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
int shift = (gpio%32);

if (pud == PUD_DOWN) {
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) |
PUD_DOWN;
} else if (pud == PUD_UP) {
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
} else { // pud == PUD_OFF
// Check GPIO register
int is2711 = *(gpio_map+PULLUPDN_OFFSET_2711_3) != 0x6770696f;
if (is2711) {
// Pi 4 Pull-up/down method
int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4);
int pullshift = (gpio & 0xf) << 1;
unsigned int pullbits;
unsigned int pull = 0;
switch (pud) {
case PUD_OFF: pull = 0; break;
case PUD_UP: pull = 1; break;
case PUD_DOWN: pull = 2; break;
default: pull = 0; // switch PUD to OFF for other values
}
pullbits = *(gpio_map + pullreg);
pullbits &= ~(3 << pullshift);
pullbits |= (pull << pullshift);
*(gpio_map + pullreg) = pullbits;
} else {
// Legacy Pull-up/down method
int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32);
int shift = (gpio%32);

if (pud == PUD_DOWN) {
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN;
} else if (pud == PUD_UP) {
*(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP;
} else { // pud == PUD_OFF
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
}
short_wait();
*(gpio_map+clk_offset) = 1 << shift;
short_wait();
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
*(gpio_map+clk_offset) = 0;
}

short_wait();
*(gpio_map+clk_offset) = 1 << shift;
short_wait();
*(gpio_map+PULLUPDN_OFFSET) &= ~3;
*(gpio_map+clk_offset) = 0;
}

void setup_gpio(int gpio, int direction, int pud)
Expand Down Expand Up @@ -265,12 +279,11 @@ void output_gpio(int gpio, int value)
{
int offset, shift;

if (value) { // value == HIGH
if (value) // value == HIGH
offset = SET_OFFSET + (gpio/32);
} else { // value == LOW
offset = CLR_OFFSET + (gpio/32);
}

else // value == LOW
offset = CLR_OFFSET + (gpio/32);

shift = (gpio%32);

*(gpio_map+offset) = 1 << shift;
Expand All @@ -288,5 +301,5 @@ int input_gpio(int gpio)

void cleanup(void)
{
munmap((void *) gpio_map, BLOCK_SIZE);
munmap((void *)gpio_map, BLOCK_SIZE);
}
10 changes: 5 additions & 5 deletions ext/rpi_gpio/c_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Original code by Ben Croston modified for Ruby by Nick Lowery
(github.com/clockvapor)
Copyright (c) 2014-2016 Nick Lowery

Copyright (c) 2013-2015 Ben Croston
Copyright (c) 2013-2019 Ben Croston

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down Expand Up @@ -36,10 +36,10 @@ void set_low_event(int gpio, int enable);
int eventdetected(int gpio);
void cleanup(void);

#define SETUP_OK 0
#define SETUP_DEVMEM_FAIL 1
#define SETUP_MALLOC_FAIL 2
#define SETUP_MMAP_FAIL 3
#define SETUP_OK 0
#define SETUP_DEVMEM_FAIL 1
#define SETUP_MALLOC_FAIL 2
#define SETUP_MMAP_FAIL 3
#define SETUP_CPUINFO_FAIL 4
#define SETUP_NOT_RPI_FAIL 5

Expand Down