static int raspberrypiWaitForInterrupt(int pin, int ms) { int x = 0; uint8_t c = 0; struct pollfd polls; if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->waitForInterrupt: Invalid pin number %d", pin); return -1; } if(pinModes[pin] != SYS) { wiringXLog(LOG_ERR, "raspberrypi->waitForInterrupt: Trying to read from pin %d, but it's not configured as interrupt", pin); return -1; } if(sysFds[pin] == -1) { wiringXLog(LOG_ERR, "raspberrypi->waitForInterrupt: GPIO %d not set as interrupt", pin); return -1; } polls.fd = sysFds[pin]; polls.events = POLLPRI; x = poll(&polls, 1, ms); /* Don't react to signals */ if(x == -1 && errno == EINTR) { x = 0; } (void)read(sysFds[pin], &c, 1); lseek(sysFds[pin], 0, SEEK_SET); return x; }
static int raspberrypiPinMode(int pin, int mode) { int fSel, shift; if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->pinMode: Invalid pin number %d (0 >= pin <= 31)", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { pinModes[pin] = mode; if(wiringPiMode == WPI_MODE_PINS) { pin = pinToGpio[pin]; } else if(wiringPiMode == WPI_MODE_PHYS) pin = physToGpio[pin]; else if(wiringPiMode != WPI_MODE_GPIO) return -1; fSel = gpioToGPFSEL[pin]; shift = gpioToShift[pin]; if(mode == INPUT) { *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)); } else if(mode == OUTPUT) { *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift); } } return 0; }
static int raspberrypiDigitalWrite(int pin, int value) { if(pinModes[pin] != OUTPUT) { wiringXLog(LOG_ERR, "raspberrypi->digitalWrite: Trying to write to pin %d, but it's not configured as output", pin); return -1; } if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->digitalWrite: Invalid pin number %d (0 >= pin <= 31)", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { if(wiringPiMode == WPI_MODE_PINS) { pin = pinToGpio[pin] ; } else if(wiringPiMode == WPI_MODE_PHYS) { pin = physToGpio[pin] ; } else if(wiringPiMode != WPI_MODE_GPIO) { return -1; } if(value == LOW) *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31); else *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31); } return 0; }
static int raspberrypiDigitalRead(int pin) { if(pinModes[pin] != INPUT && pinModes[pin] != SYS) { wiringXLog(LOG_ERR, "raspberrypi->digitalRead: Trying to write to pin %d, but it's not configured as input", pin); return -1; } if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->digitalRead: Invalid pin number %d (0 >= pin <= 31)", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { if(wiringPiMode == WPI_MODE_PINS) { pin = pinToGpio[pin] ; } else if (wiringPiMode == WPI_MODE_PHYS) { pin = physToGpio[pin] ; } else if (wiringPiMode != WPI_MODE_GPIO) { return -1; } if((*(gpio + gpioToGPLEV[pin]) & (1 << (pin & 31))) != 0) { return HIGH; } else { return LOW; } } return 0; }
static int raspberrypiISR(int pin, int mode) { int i = 0, fd = 0, match = 0, count = 0; const char *sMode = NULL; char path[35], c, line[120]; FILE *f = NULL; if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->isr: Invalid pin number %d", pin); return -1; } pinModes[pin] = SYS; if(mode == INT_EDGE_FALLING) { sMode = "falling" ; } else if(mode == INT_EDGE_RISING) { sMode = "rising" ; } else if(mode == INT_EDGE_BOTH) { sMode = "both"; } else { wiringXLog(LOG_ERR, "raspberrypi->isr: Invalid mode. Should be INT_EDGE_BOTH, INT_EDGE_RISING, or INT_EDGE_FALLING"); return -1; } sprintf(path, "/sys/class/gpio/gpio%d/value", pinToGpio[pin]); fd = open(path, O_RDWR); if(fd < 0) { if((f = fopen("/sys/class/gpio/export", "w")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->isr: Unable to open GPIO export interface: %s", strerror(errno)); return -1; } fprintf(f, "%d\n", pinToGpio[pin]); fclose(f); } sprintf(path, "/sys/class/gpio/gpio%d/direction", pinToGpio[pin]); if((f = fopen(path, "w")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->isr: Unable to open GPIO direction interface for pin %d: %s", pin, strerror(errno)); return -1; } fprintf(f, "in\n"); fclose(f); sprintf(path, "/sys/class/gpio/gpio%d/edge", pinToGpio[pin]); if((f = fopen(path, "w")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->isr: Unable to open GPIO edge interface for pin %d: %s", pin, strerror(errno)); return -1; } if(strcasecmp(sMode, "none") == 0) { fprintf(f, "none\n"); } else if(strcasecmp(sMode, "rising") == 0) { fprintf(f, "rising\n"); } else if(strcasecmp(sMode, "falling") == 0) { fprintf(f, "falling\n"); } else if(strcasecmp (sMode, "both") == 0) { fprintf(f, "both\n"); } else { wiringXLog(LOG_ERR, "raspberrypi->isr: Invalid mode: %s. Should be rising, falling or both", sMode); return -1; } fclose(f); if((f = fopen(path, "r")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->isr: Unable to open GPIO edge interface for pin %d: %s", pin, strerror(errno)); return -1; } match = 0; while(fgets(line, 120, f) != NULL) { if(strstr(line, sMode) != NULL) { match = 1; break; } } fclose(f); if(match == 0) { wiringXLog(LOG_ERR, "raspberrypi->isr: Failed to set interrupt edge to %s", sMode); return -1; } sprintf(path, "/sys/class/gpio/gpio%d/value", pinToGpio[pin]); if((sysFds[pin] = open(path, O_RDONLY)) < 0) { wiringXLog(LOG_ERR, "raspberrypi->isr: Unable to open GPIO value interface: %s", strerror(errno)); return -1; } changeOwner(path); sprintf(path, "/sys/class/gpio/gpio%d/edge", pinToGpio[pin]); changeOwner(path); ioctl(fd, FIONREAD, &count); for(i=0; i<count; ++i) { read(fd, &c, 1); } close(fd); return 0; }
static int setup(void) { int fd; int boardRev; boardRev = piBoardRev(); if(boardRev == 1) { pinToGpio = pinToGpioR1; physToGpio = physToGpioR1; } else { if(piModel2 == 1) { BCM2708_PERI_BASE = 0x3F000000; } pinToGpio = pinToGpioR2; physToGpio = physToGpioR2; } #ifdef O_CLOEXEC if((fd = open("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) { #else if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) { #endif wiringXLog(LOG_ERR, "raspberrypi->setup: Unable to open /dev/mem: %s", strerror(errno)); return -1; } gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); if((int32_t)gpio == -1) { wiringXLog(LOG_ERR, "raspberrypi->setup: mmap (GPIO) failed: %s", strerror(errno)); return -1; } return 0; } static int raspberrypiDigitalRead(int pin) { if(pinModes[pin] != INPUT && pinModes[pin] != SYS) { wiringXLog(LOG_ERR, "raspberrypi->digitalRead: Trying to write to pin %d, but it's not configured as input", pin); return -1; } if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->digitalRead: Invalid pin number %d", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { pin = pinToGpio[pin]; if((*(gpio + gpioToGPLEV[pin]) & (1 << (pin & 31))) != 0) { return HIGH; } else { return LOW; } } return 0; } static int raspberrypiDigitalWrite(int pin, int value) { if(pinModes[pin] != OUTPUT) { wiringXLog(LOG_ERR, "raspberrypi->digitalWrite: Trying to write to pin %d, but it's not configured as output", pin); return -1; } if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->digitalWrite: Invalid pin number %d", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { pin = pinToGpio[pin]; if(value == LOW) *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31); else *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31); } return 0; } static int raspberrypiPinMode(int pin, int mode) { int fSel, shift; if(raspberrypiValidGPIO(pin) != 0) { wiringXLog(LOG_ERR, "raspberrypi->pinMode: Invalid pin number %d", pin); return -1; } if((pin & PI_GPIO_MASK) == 0) { pinModes[pin] = mode; pin = pinToGpio[pin]; fSel = gpioToGPFSEL[pin]; shift = gpioToShift[pin]; if(mode == INPUT) { *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)); } else if(mode == OUTPUT) { *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift); } } return 0; }