void wiringXSerialPutChar(int fd, unsigned char c) { if(fd > 0) { write(fd, &c, 1); } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); } }
void wiringXSerialFlush(int fd) { if(fd > 0) { tcflush(fd, TCIOFLUSH); } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); } }
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 raspberrypiGC(void) { int i = 0, fd = 0; char path[35]; FILE *f = NULL; for(i=0;i<NUM_PINS;i++) { if(pinModes[i] == OUTPUT) { pinMode(i, INPUT); } else if(pinModes[i] == SYS) { sprintf(path, "/sys/class/gpio/gpio%d/value", pinToGpio[i]); if((fd = open(path, O_RDWR)) > 0) { if((f = fopen("/sys/class/gpio/unexport", "w")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->gc: Unable to open GPIO unexport interface: %s", strerror(errno)); } fprintf(f, "%d\n", pinToGpio[i]); fclose(f); close(fd); } } if(sysFds[i] > 0) { close(sysFds[i]); sysFds[i] = -1; } } if(gpio) { munmap((void *)gpio, BLOCK_SIZE); } return 0; }
void wiringXSerialPuts(int fd, char *s) { if(fd > 0) { write(fd, s, strlen(s)); } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); } }
static int changeOwner(char *file) { uid_t uid = getuid(); uid_t gid = getgid(); if(chown(file, uid, gid) != 0) { if(errno == ENOENT) { wiringXLog(LOG_ERR, "raspberrypi->changeOwner: File not present: %s", file); return -1; } else { wiringXLog(LOG_ERR, "raspberrypi->changeOwner: Unable to change ownership of %s: %s", file, strerror (errno)); return -1; } } return 0; }
int waitForInterrupt(int pin, int ms) { if(platform != NULL) { if(platform->waitForInterrupt) { int x = platform->waitForInterrupt(pin, ms); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling waitForInterrupt", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support waitForInterrupt", platform->name); wiringXGC(); } } return -1; }
int wiringXSPISetup(int channel, int speed) { if(platform != NULL) { if(platform->SPISetup) { int x = platform->SPISetup(channel, speed); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling SPISetup", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support SPISetup", platform->name); wiringXGC(); } } return -1; }
int wiringXSPIDataRW(int channel, unsigned char *data, int len) { if(platform != NULL) { if(platform->SPIDataRW) { int x = platform->SPIDataRW(channel, data, len); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling SPIDataRW", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support SPIDataRW", platform->name); wiringXGC(); } } return -1; }
int wiringXI2CSetup(int devId) { if(platform != NULL) { if(platform->I2CSetup) { int x = platform->I2CSetup(devId); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling I2CSetup", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support I2CSetup", platform->name); wiringXGC(); } } return -1; }
int wiringXI2CWriteReg16(int fd, int reg, int data) { if(platform != NULL) { if(platform->I2CWriteReg16) { int x = platform->I2CWriteReg16(fd, reg, data); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling I2CWriteReg16", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support I2CWriteReg16", platform->name); wiringXGC(); } } return -1; }
int wiringXI2CReadReg8(int fd, int reg) { if(platform != NULL) { if(platform->I2CReadReg8) { int x = platform->I2CReadReg8(fd, reg); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling I2CReadReg8", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support I2CReadReg8", platform->name); wiringXGC(); } } return -1; }
int wiringXISR(int pin, int mode) { if(platform != NULL) { if(platform->isr) { int x = platform->isr(pin, mode); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling isr", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support isr", platform->name); wiringXGC(); } } return -1; }
int digitalRead(int pin) { if(platform != NULL) { if(platform->digitalRead) { int x = platform->digitalRead(pin); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling digitalRead", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support digitalRead", platform->name); wiringXGC(); } } return -1; }
int wiringXAnalogRead(int channel){ if(platform != NULL) { if(platform->analogRead) { int x = platform->analogRead(channel); if(x == -1) { wiringXLog(LOG_ERR, "%s: error while calling analogRead", platform->name); wiringXGC(); } else { return x; } } else { wiringXLog(LOG_ERR, "%s: platform doesn't support analogRead", platform->name); wiringXGC(); } } return -1; }
int wiringXSetup(void) { #ifndef _WIN32 if(wiringXLog == NULL) { wiringXLog = _fprintf; } if(wiringXSupported() == 0) { if(setup == -2) { hummingboardInit(); raspberrypiInit(); bananapiInit(); ci20Init(); radxaInit(); odroidInit(); int match = 0; struct platform_t *tmp = platforms; while(tmp) { if(tmp->identify() >= 0) { platform = tmp; match = 1; break; } tmp = tmp->next; } if(match == 0) { wiringXLog(LOG_ERR, "hardware not supported"); wiringXGC(); return -1; } else { wiringXLog(LOG_DEBUG, "running on a %s", platform->name); } setup = platform->setup(); return setup; } else { return setup; } } #endif return -1; }
int wiringXValidGPIO(int gpio) { if(platform != NULL) { if(platform->validGPIO) { return platform->validGPIO(gpio); } else { wiringXLog(LOG_ERR, "%s: platform doesn't support gpio number validation", platform->name); wiringXGC(); } } return -1; }
static int exynos5422ISR(int i, enum isr_mode_t mode) { struct layout_t *pin = NULL; char path[PATH_MAX]; if(exynos5422->irq == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been mapped", exynos5422->brand, exynos5422->chip); return -1; } if(exynos5422->fd <= 0 || exynos5422->gpio == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been setup by wiringX", exynos5422->brand, exynos5422->chip); return -1; } pin = &exynos5422->layout[exynos5422->irq[i]]; sprintf(path, "/sys/class/gpio/gpio%d", exynos5422->irq[i]); if((soc_sysfs_check_gpio(exynos5422, path)) == -1) { sprintf(path, "/sys/class/gpio/export"); if(soc_sysfs_gpio_export(exynos5422, path, exynos5422->irq[i]) == -1) { return -1; } } sprintf(path, "/sys/class/gpio/gpio%d/direction", exynos5422->irq[i]); if(soc_sysfs_set_gpio_direction(exynos5422, path, "in") == -1) { return -1; } sprintf(path, "/sys/class/gpio/gpio%d/edge", exynos5422->irq[i]); if(soc_sysfs_set_gpio_interrupt_mode(exynos5422, path, mode) == -1) { return -1; } sprintf(path, "/sys/class/gpio/gpio%d/value", exynos5422->irq[i]); if((pin->fd = soc_sysfs_gpio_reset_value(exynos5422, path)) == -1) { return -1; } pin->mode = PINMODE_INTERRUPT; return 0; }
static int exynos5422Setup(void) { int i = 0; if((exynos5422->fd = open("/dev/mem", O_RDWR | O_SYNC )) < 0) { wiringXLog(LOG_ERR, "wiringX failed to open /dev/mem for raw memory access"); return -1; } /* * Mapping the GPIO register areas. * -> 0: 0x13400000, 1: 0x13410000, 2: 0x14000000, 3: 0x14010000, 4: 0x03860000 */ for (i = 0; i < 5; ++i) { if((exynos5422->gpio[i] = mmap(0, exynos5422->page_size, PROT_READ|PROT_WRITE, MAP_SHARED, exynos5422->fd, exynos5422->base_addr[i])) == MAP_FAILED) { wiringXLog(LOG_ERR, "wiringX failed to map the %s %s GPIO memory address", exynos5422->brand, exynos5422->chip); return -1; } } return 0; }
static int setup(void) { int fd; int boardRev; int model, rev, mem, maker, overVolted; boardRev = piBoardRev(); if(boardRev == 1) { pinToGpio = pinToGpioR1; physToGpio = physToGpioR1; } else { if(piModel2 == 1) { BCM2708_PERI_BASE = 0x3F000000; } pinToGpio = pinToGpioR2; physToGpio = physToGpioR2; } if((fd = open("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) { 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; } if(piBoardId(&model, &rev, &mem, &maker, &overVolted) == -1) { return -1; } if(model == PI_MODEL_CM) { wiringPiMode = WPI_MODE_GPIO; } else { wiringPiMode = WPI_MODE_PINS; } return 0; }
int wiringXSerialGetChar(int fd) { uint8_t x = 0; if(fd > 0) { if(read(fd, &x, 1) != 1) { return -1; } return ((int)x) & 0xFF; } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); return -1; } }
int wiringXSerialDataAvail(int fd) { int result = 0; if(fd > 0) { if(ioctl(fd, FIONREAD, &result) == -1) { return -1; } return result; } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); return -1; } }
int raspberrypiSPISetup(int channel, int speed) { int fd; const char *device = NULL; channel &= 1; if(channel == 0) { device = "/dev/spidev0.0"; } else { device = "/dev/spidev0.1"; } if((fd = open(device, O_RDWR)) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to open device %s: %s", device, strerror(errno)); return -1; } spiSpeeds[channel] = speed; spiFds[channel] = fd; if(ioctl(fd, SPI_IOC_WR_MODE, &spiMode) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set write mode for device %s: %s", device, strerror(errno)); return -1; } if(ioctl(fd, SPI_IOC_RD_MODE, &spiMode) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set read mode for device %s: %s", device, strerror(errno)); return -1; } if(ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set write bits_per_word for device %s: %s", device, strerror(errno)); return -1; } if(ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set read bits_per_word for device %s: %s", device, strerror(errno)); return -1; } if(ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set write max_speed for device %s: %s", device, strerror(errno)); return -1; } if(ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPISetup: Unable to set read max_speed for device %s: %s", device, strerror(errno)); return -1; } return fd; }
void wiringXSerialPrintf(int fd, char *message, ...) { va_list argp; char buffer[1024]; memset(&buffer, '\0', 1024); if(fd > 0) { va_start(argp, message); vsnprintf(buffer, 1023, message, argp); va_end(argp); wiringXSerialPuts(fd, buffer); } else { wiringXLog(LOG_ERR, "Serial interface is not opened"); } }
int raspberrypiSPIDataRW(int channel, unsigned char *data, int len) { struct spi_ioc_transfer spi; memset(&spi, 0, sizeof(spi)); // found at http://www.raspberrypi.org/forums/viewtopic.php?p=680665#p680665 channel &= 1; spi.tx_buf = (unsigned long)data; spi.rx_buf = (unsigned long)data; spi.len = len; spi.delay_usecs = spiDelay; spi.speed_hz = spiSpeeds[channel]; spi.bits_per_word = spiBPW; if(ioctl(spiFds[channel], SPI_IOC_MESSAGE(1), &spi) < 0) { wiringXLog(LOG_ERR, "raspberrypi->SPIDataRW: Unable to read/write from channel %d: %s", channel, strerror(errno)); return -1; } return 0; }
int wiringXGC(void) { int i = 0; if(platform != NULL) { i = platform->gc(); } platform = NULL; struct platform_t *tmp = platforms; while(platforms) { tmp = platforms; free(platforms->name); platforms = platforms->next; free(tmp); } if(platforms != NULL) { free(platforms); } wiringXLog(LOG_DEBUG, "garbage collected wiringX library"); return i; }
void platform_register(struct platform_t **dev, const char *name) { *dev = MALLOC(sizeof(struct platform_t)); (*dev)->name = NULL; (*dev)->pinMode = NULL; (*dev)->digitalWrite = NULL; (*dev)->digitalRead = NULL; (*dev)->identify = NULL; (*dev)->waitForInterrupt = NULL; (*dev)->isr = NULL; (*dev)->I2CRead = NULL; (*dev)->I2CReadReg8 = NULL; (*dev)->I2CReadReg16 = NULL; (*dev)->I2CWrite = NULL; (*dev)->I2CWriteReg8 = NULL; (*dev)->I2CWriteReg16 = NULL; if(!((*dev)->name = MALLOC(strlen(name)+1))) { wiringXLog(LOG_ERR, "out of memory"); exit(0); } strcpy((*dev)->name, name); (*dev)->next = platforms; platforms = (*dev); }
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; }
static int piBoardRev(void) { FILE *cpuFd; char line[120], revision[120], hardware[120], name[120]; char *c; static int boardRev = -1; if((cpuFd = fopen("/proc/cpuinfo", "r")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->identify: Unable open /proc/cpuinfo"); return -1; } while(fgets(line, 120, cpuFd) != NULL) { if(strncmp(line, "Revision", 8) == 0) { strcpy(revision, line); } if(strncmp(line, "Hardware", 8) == 0) { strcpy(hardware, line); } } fclose(cpuFd); sscanf(hardware, "Hardware%*[ \t]:%*[ ]%[a-zA-Z0-9 ./()]%*[\n]", name); if(strstr(name, "BCM2708") != NULL) { if(boardRev != -1) { return boardRev; } if((cpuFd = fopen("/proc/cpuinfo", "r")) == NULL) { wiringXLog(LOG_ERR, "raspberrypi->identify: Unable to open /proc/cpuinfo"); return -1; } while(fgets(line, 120, cpuFd) != NULL) { if(strncmp(line, "Revision", 8) == 0) { break; } } fclose(cpuFd); if(strncmp(line, "Revision", 8) != 0) { wiringXLog(LOG_ERR, "raspberrypi->identify: No \"Revision\" line"); return -1; } for(c = &line[strlen(line) - 1] ; (*c == '\n') || (*c == '\r'); --c) { *c = 0; } for(c = line; *c; ++c) { if(isdigit(*c)) { break; } } if(!isdigit(*c)) { wiringXLog(LOG_ERR, "raspberrypi->identify: No numeric revision string"); return -1; } if(strlen(c) < 4) { wiringXLog(LOG_ERR, "raspberrypi->identify: Bogus \"Revision\" line (too small)"); return -1; } c = c + strlen(c) - 4; if((strcmp(c, "0002") == 0) || (strcmp(c, "0003") == 0)) { boardRev = 1; } else { boardRev = 2; } return boardRev; } else if(strstr(name, "BCM2709") != NULL) { piModel2 = 1; boardRev = 2; return boardRev; } else { return -1; } }