/** * Object-to-Config function. * Creates a config-node (and subnodes) from a LedHardware model * @param c the current preferences context * @param n a freshly created prefs node that this function should fill with properties of obj * @param obj object of this class where preferences should be generated from * @result NFT_SUCCESS if everything went fine, NFT_FAILURE otherwise * @note you shouldn't call this function directly * It's used by nft_prefs_obj_to_node() etc. */ static NftResult _prefs_from_chain(NftPrefs * p, NftPrefsNode * n, void *obj, void *userptr) { if(!p || !n || !obj) NFT_LOG_NULL(NFT_FAILURE); /* chain to generate preferences from */ LedChain *c = obj; /* amount of LEDs in this chain - ledcount */ if(!nft_prefs_node_prop_int_set(n, LED_CHAIN_PROP_LEDCOUNT, led_chain_get_ledcount(c))) return NFT_FAILURE; /* pixel-format of this chain */ if(!nft_prefs_node_prop_string_set(n, LED_CHAIN_PROP_FORMAT, (char *) led_pixel_format_to_string (led_chain_get_format(c)))) return NFT_FAILURE; /* add all LEDs in this chain */ LedCount i; for(i = 0; i < led_chain_get_ledcount(c); i++) { /* generate prefs node from LED */ NftPrefsNode *node; if(! (node = led_prefs_led_to_node(p, led_chain_get_nth(c, i)))) return NFT_FAILURE; /* add node as child of this node */ if(!nft_prefs_node_add_child(n, node)) return NFT_FAILURE; } 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; }
/** * Config-to-Object function. * Creates a LedHardware model from a prefs node * @note you shouldn't call this function directly. * It's used by nft_prefs_obj_from_node() etc. */ static NftResult _prefs_to_hardware(LedPrefs * p, void **newObj, NftPrefsNode * n, void *userptr) { if(!p || !newObj || !n) NFT_LOG_NULL(NFT_FAILURE); /** initial result */ NftResult r = NFT_FAILURE; char *name = NULL; char *id = NULL; char *plugin_name = NULL; LedHardware *h = NULL; /* get hardware name */ if(! (name = nft_prefs_node_prop_string_get(n, LED_HARDWARE_PROP_NAME))) { NFT_LOG(L_ERROR, "\"hardware\" has no name"); goto _pth_end; } /* get plugin-name */ if(! (plugin_name = nft_prefs_node_prop_string_get(n, LED_HARDWARE_PROP_PLUGIN))) { NFT_LOG(L_ERROR, "\"hardware\" has no \"plugin\" type"); goto _pth_end; } /* get plugin-id */ if(!(id = nft_prefs_node_prop_string_get(n, LED_HARDWARE_PROP_ID))) { NFT_LOG(L_ERROR, "\"hardware\" has no \"id\" type"); goto _pth_end; } /* get stride */ LedCount stride; if(! (nft_prefs_node_prop_int_get (n, LED_HARDWARE_PROP_STRIDE, (int *) &stride))) { NFT_LOG(L_WARNING, "\"hardware\" has no \"stride\". Using 0 as default."); stride = 0; } /* create new hardware object */ if(!(h = led_hardware_new(name, plugin_name))) { NFT_LOG(L_ERROR, "Failed to initialize \"%s\" from \"%s\" plugin.", name, plugin_name); goto _pth_end; } /* set stride */ if(!(led_hardware_set_stride(h, stride))) { NFT_LOG(L_ERROR, "Failed to set stride (%d) of hardware \"%s\"", stride, name); goto _pth_end; } /* set id */ if(!(led_hardware_set_id(h, id))) { NFT_LOG(L_ERROR, "Failed to set ID \"%s\" of hardware \"%s\"", id, name); goto _pth_end; } /** @todo handle custom properties */ /* process child nodes */ LedPrefsNode *child; for(child = nft_prefs_node_get_first_child(n); child; child = nft_prefs_node_get_next(child)) { /* is child a tile node? */ if(led_prefs_is_tile_node(child)) { if(!led_hardware_append_tile (h, led_prefs_tile_from_node(p, child))) { NFT_LOG(L_ERROR, "Failed to add \"tile\" to \"%s\". Aborting.", name); goto _pth_end; } continue; } /* is child a chain node? */ else if(led_prefs_is_chain_node(child)) { LedChain *c; if(!(c = led_prefs_chain_from_node(p, child))) { NFT_LOG(L_ERROR, "Failed to create \"chain\" node of hardware %s", name); goto _pth_end; } if(!led_hardware_init (h, id, led_chain_get_ledcount(c), led_pixel_format_to_string(led_chain_get_format (c)))) { NFT_LOG(L_WARNING, "Failed to initialize hardware \"%s\"", name); } led_chain_destroy(c); } /* is child a plugin-property node? */ else if(strcmp (nft_prefs_node_get_name(child), LED_HARDWARE_PROPERTY_NAME) == 0) { char *name = NULL; char *type = NULL; char *value = NULL; /* get name of property */ if(! (name = nft_prefs_node_prop_string_get(child, LED_HARDWARE_PROPERTY_PROP_NAME))) { NFT_LOG(L_ERROR, "\"%s\" has no \"%s\" property", LED_HARDWARE_PROPERTY_NAME, LED_HARDWARE_PROPERTY_PROP_NAME); goto _pthp_end; } /* type of property */ if(! (type = nft_prefs_node_prop_string_get(child, LED_HARDWARE_PROPERTY_PROP_TYPE))) { NFT_LOG(L_ERROR, "\"%s\" has no \"%s\" property", LED_HARDWARE_PROPERTY_NAME, LED_HARDWARE_PROPERTY_PROP_TYPE); goto _pthp_end; } /* property value */ if(! (value = nft_prefs_node_prop_string_get(child, LED_HARDWARE_PROPERTY_PROP_VALUE))) { NFT_LOG(L_ERROR, "\"%s\" has no \"%s\" property", LED_HARDWARE_PROPERTY_NAME, LED_HARDWARE_PROPERTY_PROP_VALUE); goto _pthp_end; } /* decide about type */ switch (led_hardware_plugin_prop_type_from_string (type)) { /* int */ case LED_HW_CUSTOM_PROP_INT: { int integer; if(sscanf(value, "%32d", &integer) != 1) { NFT_LOG(L_ERROR, "Failed to parse integer from \"%s\" property (\"%s\")", LED_HARDWARE_PROPERTY_PROP_VALUE, value); goto _pthp_end; } if(!led_hardware_plugin_prop_set_int (h, name, integer)) { NFT_LOG(L_ERROR, "Failed to set \"%s\" = %d)", name, integer); goto _pthp_end; } break; } /* float */ case LED_HW_CUSTOM_PROP_FLOAT: { float f; if(sscanf(value, "%64f", &f) != 1) { NFT_LOG(L_ERROR, "Failed to parse float from \"%s\" property (\"%s\")", LED_HARDWARE_PROPERTY_PROP_VALUE, value); goto _pthp_end; } if(!led_hardware_plugin_prop_set_float (h, name, f)) { NFT_LOG(L_ERROR, "Failed to set \"%s\" = %f)", name, f); goto _pthp_end; } break; } /* string */ case LED_HW_CUSTOM_PROP_STRING: { if(!led_hardware_plugin_prop_set_string(h, name, value)) { NFT_LOG(L_ERROR, "Failed to set \"%s\" = \"%s\")", name, value); goto _pthp_end; } break; } /* huh? */ default: { NFT_LOG(L_ERROR, "Invalid plugin-property type: \"%s\"", type); break; } } _pthp_end: nft_prefs_free(name); nft_prefs_free(type); nft_prefs_free(value); continue; } else { NFT_LOG(L_WARNING, "Attempt to add \"%s\" node to hardware. Not allowed. (Ignoring node)", nft_prefs_node_get_name(child)); continue; } } /* everything pico bello */ r = NFT_SUCCESS; _pth_end: /* free strings */ nft_prefs_free(id); nft_prefs_free(plugin_name); nft_prefs_free(name); /* newly created hardware object */ *newObj = h; return r; }
/** * 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 _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; }