/** * initialize hardware */ static NftResult _spi_init(void *privdata, const char *id) { NFT_LOG(L_DEBUG, "Initializing LDP8806 hardware"); struct priv *p = privdata; /* pixelformat supported? */ LedPixelFormat *format = led_chain_get_format(led_hardware_get_chain(p->hw)); const char *fmtstring = led_pixel_format_to_string(format); int bytes_per_pixel = led_pixel_format_get_bytes_per_pixel(format); int components_per_pixel = led_pixel_format_get_n_components(format); int bytes_per_component = bytes_per_pixel / components_per_pixel; if(bytes_per_component != 1) { NFT_LOG(L_ERROR, "We need a format with 8 bits per pixel-component. Format %s has %d bytes-per-pixel and %d components-per-pixel.", fmtstring, bytes_per_pixel, components_per_pixel); return NFT_FAILURE; } NFT_LOG(L_DEBUG, "Using \"%s\" as pixel-format", fmtstring); /* * check if id = "*" in this case we should try to automagically find our device, * we'll just use a default in this case * @todo cycle through all devices */ if(strcmp(id, "*") == 0) { strncpy(p->id, "/dev/spidev0.0", sizeof(p->id)); } else { /* copy our id (and/or change it) */ strncpy(p->id, id, sizeof(p->id)); } /* open SPI port */ if((p->fd = open(p->id, O_RDWR)) == -1) { NFT_LOG(L_ERROR, "Failed to open port \"%s\"", p->id); NFT_LOG_PERROR("open()"); return NFT_FAILURE; } /* Set SPI parameters */ if(ioctl(p->fd, SPI_IOC_WR_MODE, &p->spiMode) < 0) return NFT_FAILURE; if(ioctl(p->fd, SPI_IOC_RD_MODE, &p->spiMode) < 0) return NFT_FAILURE; if(ioctl(p->fd, SPI_IOC_WR_BITS_PER_WORD, &p->spiBPW) < 0) return NFT_FAILURE; if(ioctl(p->fd, SPI_IOC_RD_BITS_PER_WORD, &p->spiBPW) < 0) return NFT_FAILURE; if(ioctl(p->fd, SPI_IOC_WR_MAX_SPEED_HZ, &p->spiSpeed) < 0) return NFT_FAILURE; if(ioctl(p->fd, SPI_IOC_RD_MAX_SPEED_HZ, &p->spiSpeed) < 0) return NFT_FAILURE; NFT_LOG(L_DEBUG, "SPI \"%d\" initialized (mode: %d, bits-per-word: %d, speed-hz: %d)", p->spiMode, p->spiBPW, p->spiSpeed); return NFT_SUCCESS; }
/** * initialize hardware */ static NftResult _usb_init(void *privdata, const char *id) { Niftylino *n = privdata; struct usb_bus *bus; struct usb_device *dev; struct usb_dev_handle *h; /* save id */ strncpy(n->id, id, sizeof(n->id)); /* get our chain */ LedChain *chain = led_hardware_get_chain(n->hw); /* pixel-format of our chain */ LedPixelFormat *format = led_chain_get_format(chain); /* pixelformat supported? */ NiftylinoValueWidth vw; switch (led_pixel_format_get_bytes_per_pixel(format) / led_pixel_format_get_n_components(format)) { /* 8 bit values */ case 1: { vw = NIFTYLINO_8BIT_VALUES; break; } /* 16 bit values */ case 2: { vw = NIFTYLINO_16BIT_VALUES; break; } /* unsupported format */ default: { NFT_LOG(L_ERROR, "Unsupported format requested: %d bytes-per-pixel, %d components-per-pixel", led_pixel_format_get_bytes_per_pixel(format), led_pixel_format_get_n_components(format)); return NFT_FAILURE; } } /* find (new) busses */ usb_find_busses(); /* find (new) devices */ usb_find_devices(); /* open niftylino usb-device */ char serial[255]; /* walk all busses */ for(bus = usb_get_busses(); bus; bus = bus->next) { /* walk all devices on bus */ for(dev = bus->devices; dev; dev = dev->next) { /* found niftylino? */ if((dev->descriptor.idVendor != VENDOR_ID) || (dev->descriptor.idProduct != PRODUCT_ID)) { continue; } /* try to open */ if(!(h = usb_open(dev))) /* device allready open or other error */ continue; /* interface already claimed by driver? */ char driver[1024]; if(!(usb_get_driver_np(h, 0, driver, sizeof(driver)))) { // NFT_LOG(L_ERROR, "Device already claimed by // \"%s\"", driver); continue; } /* reset device */ usb_reset(h); usb_close(h); // ~ if(usb_reset(h) < 0) // ~ { // ~ /* reset failed */ // ~ usb_close(h); // ~ continue; // ~ } /* re-open */ if(!(h = usb_open(dev))) /* device allready open or other error */ continue; /* clear any previous halt status */ // usb_clear_halt(h, 0); /* claim interface */ if(usb_claim_interface(h, 0) < 0) { /* device claim failed */ usb_close(h); continue; } /* receive string-descriptor (serial number) */ if(usb_get_string_simple(h, 3, serial, sizeof(serial)) < 0) { usb_release_interface(h, 0); usb_close(h); continue; } /* device id == requested id? (or wildcard id * requested? */ if(strlen(n->id) == 0 || strncmp(n->id, serial, sizeof(serial)) == 0 || strncmp(n->id, "*", 1) == 0) { /* serial-number... */ strncpy(n->id, serial, sizeof(n->id)); /* usb device handle */ n->usb_handle = h; /* set format */ NFT_LOG(L_INFO, "Setting bitwidth to %d bit", (vw == NIFTYLINO_8BIT_VALUES ? 8 : 16)); if(!_set_format(privdata, vw)) { NFT_LOG(L_ERROR, "Failed to set greyscale format to %s.", vw == NIFTYLINO_8BIT_VALUES ? "u8" : "u16"); return NFT_FAILURE; } return NFT_SUCCESS; } /* close this adapter */ usb_release_interface(h, 0); usb_close(h); } } return NFT_FAILURE; }
/** * initialize hardware */ static NftResult _hw_init(void *privdata, const char *id) { NFT_LOG(L_DEBUG, "Initializing arduino-max72xx hardware"); struct priv *p = privdata; /* ... do checks ... */ /* pixelformat supported? */ LedPixelFormat *format = led_chain_get_format(led_hardware_get_chain(p->hw)); if(led_pixel_format_get_bytes_per_pixel(format) != 1) { NFT_LOG(L_ERROR, "This hardware only supports 1 bpp formats (e.g. \"Y u8\")"); return NFT_FAILURE; } if(led_pixel_format_get_n_components(format) != 1) { NFT_LOG(L_ERROR, "This hardware only supports 1 component per pixel (e.g. \"Y u8\")"); return NFT_FAILURE; } const char *fmtstring = led_pixel_format_to_string(led_chain_get_format (led_hardware_get_chain(p->hw))); NFT_LOG(L_DEBUG, "Using \"%s\" as pixel-format", fmtstring); /* * check if id = "*" in this case we should try to automagically find our device, * we'll just use a default in this case */ if(strcmp(id, "*") == 0) { strncpy(p->id, "/dev/ttyUSB0", sizeof(p->id)); } else { /* copy our id (and/or change it) */ strncpy(p->id, id, sizeof(p->id)); } /* open serial port */ if((p->fd = open(p->id, O_RDWR | O_NOCTTY)) == -1) { NFT_LOG(L_ERROR, "Failed to open port \"%s\"", p->id); NFT_LOG_PERROR("open()"); return NFT_FAILURE; } /* save current port settings */ tcgetattr(p->fd, &p->oldtio); /* space for new tio structure */ struct termios newtio; memset(&newtio, 0, sizeof(struct termios)); /* set new port settings */ newtio.c_cflag = B115200 | CS8 | CSTOPB | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VMIN] = 1; newtio.c_cc[VTIME] = 5; tcflush(p->fd, TCIFLUSH); tcsetattr(p->fd, TCSANOW, &newtio); return NFT_SUCCESS; }