/** unregister setup */ static void _unregister() { if(!_setup) NFT_LOG_NULL(); /* free all hardware nodes */ LedHardware *h; for(h = led_setup_get_hardware(_setup); h; h = led_hardware_list_get_next(h)) { /* unregister all tiles of hardware */ LedTile *t; for(t = led_hardware_get_tile(h); t; t = led_tile_list_get_next(t)) { tile_unregister_from_gui(led_tile_get_privdata(t)); } /* unregister chain of hardware */ chain_unregister_from_gui(led_chain_get_privdata (led_hardware_get_chain(h))); /* unregister hardware */ hardware_unregister_from_gui(led_hardware_get_privdata(h)); } led_setup_destroy(_setup); _setup = NULL; free(_current_filename); _current_filename = NULL; }
/** register new setup */ NftResult setup_register_to_gui(LedSetup * s) { if(!s) NFT_LOG_NULL(NFT_FAILURE); /* previous setup? */ if(_setup) _unregister(); /* initialize our element descriptor and set as privdata in niftyled * model */ LedHardware *h; for(h = led_setup_get_hardware(s); h; h = led_hardware_list_get_next(h)) { /* create new hardware element */ if(!hardware_register_to_gui(h)) { g_warning("failed to allocate new hardware element"); return false; } /* create chain of this hardware */ if(!chain_register_to_gui(led_hardware_get_chain(h))) { g_warning("failed to allocate new chain element"); return false; } /* walk all tiles belonging to this hardware & initialize */ LedTile *t; for(t = led_hardware_get_tile(h); t; t = led_tile_list_get_next(t)) { if(!tile_register_to_gui(t)) { g_warning ("failed to allocate new tile element"); return false; } } } /* save new setup */ _setup = s; /* allocate renderer */ if(!(_renderer = renderer_setup_new())) { g_error("Failed to allocate renderer for Setup"); _unregister(); return NFT_FAILURE; } /* initially draw setup */ renderer_setup_damage(); 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; }
/** * 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_hardware(NftPrefs * p, NftPrefsNode * n, void *obj, void *userptr) { if(!p || !n || !obj) NFT_LOG_NULL(NFT_FAILURE); /* hardware "object" */ LedHardware *h = obj; /* name of hardware */ if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_NAME, (char *) led_hardware_get_name(h))) return NFT_FAILURE; /* plugin family of hardware */ if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_PLUGIN, (char *) led_hardware_plugin_get_family (h))) return NFT_FAILURE; /* id of hardware */ if(!nft_prefs_node_prop_string_set(n, LED_HARDWARE_PROP_ID, (char *) led_hardware_get_id(h))) return NFT_FAILURE; /* LED stride */ if(!nft_prefs_node_prop_int_set(n, LED_HARDWARE_PROP_STRIDE, led_hardware_get_stride(h))) return NFT_FAILURE; /* handle custom plugin properties */ int i, a = led_hardware_plugin_prop_get_count(h); for(i = 0; i < a; i++) { LedPluginCustomProp *prop; if(!(prop = led_hardware_plugin_prop_get_nth(h, i))) { NFT_LOG(L_ERROR, "Could not get property %d (but %d registered). This is a bug!", i, a); break; } /* create new node for property */ NftPrefsNode *pnode; if(! (pnode = nft_prefs_node_alloc(LED_HARDWARE_PROPERTY_NAME))) { NFT_LOG(L_ERROR, "Failed to create new node."); return NFT_FAILURE; } /* name of property */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_NAME, (char *) led_hardware_plugin_prop_get_name(prop))) return NFT_FAILURE; /* handle various types of properties */ switch (led_hardware_plugin_prop_get_type(prop)) { case LED_HW_CUSTOM_PROP_STRING: { /* save type */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE, "string")) return NFT_FAILURE; /* get string */ char *string; if(!led_hardware_plugin_prop_get_string(h, led_hardware_plugin_prop_get_name (prop), &string)) return NFT_FAILURE; /* save value */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE, string)) return NFT_FAILURE; break; } case LED_HW_CUSTOM_PROP_INT: { /* save type */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE, "int")) return NFT_FAILURE; /* get integer */ int integer; if(!led_hardware_plugin_prop_get_int(h, led_hardware_plugin_prop_get_name (prop), &integer)) return NFT_FAILURE; /* convert to string */ char *string; if(!(string = alloca(64))) { NFT_LOG_PERROR("alloca"); return NFT_FAILURE; } snprintf(string, 64, "%d", integer); /* save value */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE, string)) return NFT_FAILURE; break; } case LED_HW_CUSTOM_PROP_FLOAT: { /* save type */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_TYPE, "float")) return NFT_FAILURE; /* get float */ float fp; if(!led_hardware_plugin_prop_get_float(h, led_hardware_plugin_prop_get_name (prop), &fp)) return NFT_FAILURE; /* convert to string */ char *string; if(!(string = alloca(64))) { NFT_LOG_PERROR("alloca"); return NFT_FAILURE; } snprintf(string, 64, "%f", fp); /* save value */ if(!nft_prefs_node_prop_string_set (pnode, LED_HARDWARE_PROPERTY_PROP_VALUE, string)) return NFT_FAILURE; break; } /* unsupported type */ default: { NFT_LOG(L_WARNING, "Property \"%s\" is of unsupported type. Ignoring", led_hardware_plugin_prop_get_name (prop)); continue; } } /* add node as child of this node */ nft_prefs_node_add_child(n, pnode); } /* chain of this hardware */ LedChain *c; if((c = led_hardware_get_chain(h))) { /* generate prefs node from chain */ NftPrefsNode *node; if(!(node = led_prefs_chain_to_node(p, c))) return NFT_FAILURE; /* add node as child of this node */ nft_prefs_node_add_child(n, node); } /* tiles of this hardware */ LedTile *t; for(t = led_hardware_get_tile(h); t; t = led_tile_list_get_next(t)) { NftPrefsNode *node; if(!(node = led_prefs_tile_to_node(p, t))) return NFT_FAILURE; /* add node as child of this node */ nft_prefs_node_add_child(n, node); } /* all OK */ return NFT_SUCCESS; }
/** * 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; }
int main(int argc, char *argv[]) { /* current configuration */ LedPrefs *p = NULL; /** current setup */ LedSetup *s = NULL; /** list of LED hardware adapters */ LedHardware *hw = NULL; /* input pixel-frame buffer */ LedFrame *frame = NULL; /** width of map */ LedFrameCord width; /** height of map */ LedFrameCord height; /* check libniftyled binary version compatibility */ NFT_LED_CHECK_VERSION /* set default loglevel to INFO */ nft_log_level_set(L_INFO); /* initialize exit handlers */ #if WIN32 int signals[] = { SIGINT, SIGABRT }; #else int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT }; #endif unsigned int i; for(i=0; i<sizeof(signals)/sizeof(int); i++) { if(signal(signals[i], _exit_signal_handler) == SIG_ERR) { NFT_LOG_PERROR("signal()"); return -1; } } /* default result of main() function */ int res = -1; /* default fps */ _c.fps = 25; /* default endianess */ _c.is_big_endian = FALSE; #if HAVE_IMAGEMAGICK == 1 /* default handle-input-as-raw */ _c.raw = FALSE; #endif /* default looping */ _c.do_loop = FALSE; /* set "running" flag */ _c.running = TRUE; /* default pixel-format */ strncpy(_c.pixelformat, "RGB u8", sizeof(_c.pixelformat)); /* default prefs-filename */ if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcat.xml")) return -1; /* parse commandline arguments */ if(!_parse_args(argc, argv)) return -1; /* print welcome msg */ NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcat_version_long()); NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get())); #if HAVE_IMAGEMAGICK == 1 /* initialize imagemagick */ if(!_c.raw) { if(!im_init(&_c)) { NFT_LOG(L_ERROR, "Failed to initialize ImageMagick"); return -1; } } #endif /* initialize preferences context */ if(!(p = led_prefs_init())) return -1; /* parse prefs-file */ LedPrefsNode *pnode; if(!(pnode = led_prefs_node_from_file(_c.prefsfile))) { NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"", _c.prefsfile); goto m_deinit; } /* create setup from prefs-node */ if(!(s = led_prefs_setup_from_node(p, pnode))) { NFT_LOG(L_ERROR, "No valid setup found in preferences file."); led_prefs_node_free(pnode); goto m_deinit; } /* free preferences node */ led_prefs_node_free(pnode); /* determine width of input-frames */ if(!_c.width) /* width of mapped chain */ width = led_setup_get_width(s); else /* use value from cmdline arguments */ width = _c.width; /* determine height of input-frames */ if(!_c.height) /* height of mapped chain */ height = led_setup_get_height(s); else height = _c.height; /* validate dimensions */ if(width <= 0 || height <= 0) { NFT_LOG(L_ERROR, "Dimensions %dx%d not possible in this universe. Exiting.", width, height); goto m_deinit; } /* allocate frame (where our pixelbuffer resides) */ NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)", width, height, _c.pixelformat); LedPixelFormat *format = led_pixel_format_from_string(_c.pixelformat); if(!(frame = led_frame_new(width, height, format))) goto m_deinit; /* get first toplevel hardware */ if(!(hw = led_setup_get_hardware(s))) goto m_deinit; /* initialize hardware */ /*if(!(led_hardware_init(hw, ledcount, (LedGreyscaleFormat) format))) { NFT_LOG(L_ERROR, "failed to initialize hardware."); goto m_deinit; }*/ /* initialize pixel->led mapping */ if(!led_hardware_list_refresh_mapping(hw)) goto m_deinit; /* precalc memory offsets for actual mapping */ LedHardware *ch; for(ch = hw; ch; ch = led_hardware_list_get_next(ch)) { if(!led_chain_map_from_frame(led_hardware_get_chain(ch), frame)) goto m_deinit; } /* set correct gain to hardware */ if(!led_hardware_list_refresh_gain(hw)) goto m_deinit; #if HAVE_IMAGEMAGICK == 1 /* determine format that ImageMagick should provide */ if(!_c.raw) { if(!(im_format(&_c, format))) { NFT_LOG(L_ERROR, "Failed to determine valid ImageMagick format"); goto m_deinit; } } #endif /* do we have at least one filename? */ if(!_c.files[0]) { NFT_LOG(L_ERROR, "No input file(s) given"); goto m_deinit; } /* initially sample time for frame-timing */ if(!led_fps_sample()) goto m_deinit; #if ! WIN32 /* initialize alarm-signal handler for periodical fps output */ { struct sigaction sa; struct itimerval timer; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &_alarm_signal_handler; sigaction(SIGALRM, &sa, NULL); timer.it_value.tv_sec = 1; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 1; timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); } #endif /* get data-buffer of frame to write our pixels to */ char *buf; if(!(buf = led_frame_get_buffer(frame))) { NFT_LOG(L_ERROR, "Frame has NULL buffer"); goto m_deinit; } /* walk all files (supplied as commandline arguments) and output them */ int filecount; for(filecount = 0; _c.files[filecount]; filecount++) { NFT_LOG(L_VERBOSE, "Getting pixels from \"%s\"", _c.files[filecount]); /* open file */ if(_c.files[filecount][0] == '-' && strlen(_c.files[filecount]) == 1) { _c.fd = STDIN_FILENO; } else { if((_c.fd = open(_c.files[filecount], O_RDONLY)) < 0) { NFT_LOG(L_ERROR, "Failed to open \"%s\": %s", _c.files[filecount], strerror(errno)); continue; } } #if HAVE_IMAGEMAGICK == 1 /** initialize stream for ImageMagick */ if(!_c.raw) { if(!(im_open_stream(&_c))) continue; } #endif /* output file frame-by-frame */ while(_c.running) { #if HAVE_IMAGEMAGICK == 1 /* use imagemagick to load file if we're not in "raw-mode" */ if(!_c.raw) { /* load frame to buffer using ImageMagick */ if(!im_read_frame(&_c, width, height, buf)) break; } else { #endif /* read raw frame */ if(raw_read_frame(&_c.running, buf, _c.fd, led_pixel_format_get_buffer_size( led_frame_get_format(frame), led_frame_get_width(frame)*led_frame_get_height(frame))) == 0) continue; #if HAVE_IMAGEMAGICK == 1 } #endif /* set endianess (flag will be changed when conversion occurs) */ led_frame_set_big_endian(frame, _c.is_big_endian); /* print frame for debugging */ //nft_frame_buffer_print(frame); /* fill chain of every hardware from frame */ LedHardware *h; for(h = hw; h; h = led_hardware_list_get_next(h)) { if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame)) { NFT_LOG(L_ERROR, "Error while mapping frame"); break; } } /* send frame to hardware(s) */ NFT_LOG(L_DEBUG, "Sending frame"); led_hardware_list_send(hw); /* delay in respect to fps */ if(!led_fps_delay(_c.fps)) break; /* latch hardware */ NFT_LOG(L_DEBUG, "Showing frame"); led_hardware_list_show(hw); /* save time when frame is displayed */ if(!led_fps_sample()) break; /* clear frame */ //nft_frame_clear_buffer(frame); } #if HAVE_IMAGEMAGICK == 1 if(!_c.raw) im_close_stream(&_c); #else close(_c.fd); #endif /* loop endlessly? */ if((_c.running) && (!_c.files[filecount+1]) && _c.do_loop) { /* start over by resetting the for-loop */ filecount = -1; } } /* all ok */ res = 0; m_deinit: /* free setup */ led_setup_destroy(s); /* free frame */ led_frame_destroy(frame); /* destroy config */ led_prefs_deinit(p); #if HAVE_IMAGEMAGICK == 1 /* deinitialize ImageMagick */ im_deinit(&_c); #endif return res; }
int main(int argc, char *argv[]) { nft_log_level_set(L_DEBUG); /* register new dummy hardware called "nlo01" */ LedHardware *h; if(!(h = led_hardware_new("nlo01", "dummy"))) { NFT_LOG(L_ERROR, "Hardware creation FAILED"); return -1; } /* initialize any hardware that can be found (id="*"), define 12 * connected LEDs (4 BGR pixels). Greyscale data should be provided in * unsigned 8-bit format */ if(!led_hardware_init(h, "*", 12, "BGR u8")) { NFT_LOG(L_ERROR, "failed to initialize hardware"); return -1; } /********************************************************************** * niftyled basically provides 2 ways to send data to LED hardware: * * 1. set "raw" greyscale value of a LED in a chain connected to a * correctly initialized LED hardware * * 1.1 use the API to set each greyscale value * * 1.2 directly write to the RAW buffer * * * 2. send a complete pixelframe and have niftyled translate that to * mapped LEDs connected to one or more LED hardware devices * according to the current setup configuration (where each LED * has been assigned a X/Y coordinate and a "Component" that refers * to a component of a pixel at this position in the pixelframe) */ /****** METHOD 1.1 *******/ /* get chain of this hardware */ LedChain *c = led_hardware_get_chain(h); /* set all LEDs to half brightness */ LedCount l; for(l = 0; l < led_chain_get_ledcount(c); l++) { led_chain_set_greyscale(c, l, 128); } /* send data to hardware */ led_hardware_send(h); /* show previously sent hardware (latch to LEDs) */ led_hardware_show(h); /****** METHOD 1.2 *******/ /* ...or access raw pixelbuffer */ uint8_t *pixels = led_chain_get_buffer(c); /* walk all pixels to turn on all LEDs */ int i; for(i = 0; i < 16; i++) pixels[i] = 0xff; /* send data to hardware */ led_hardware_send(h); /* show previously sent hardware (latch to LEDs) */ led_hardware_show(h); /****** METHOD 2 - s. ledcat sources *******/ /* deinitialize hardware */ led_hardware_deinit(h); return 0; }
int main(int argc, char *argv[]) { /** return value of main() */ int res = 1; /* current configuration */ LedPrefs *prefs = NULL; /* current setup */ LedSetup *setup = NULL; /** framebuffer for captured image */ LedFrame *frame = NULL; /* check binary version compatibility */ NFT_LED_CHECK_VERSION /* set default loglevel to INFO */ nft_log_level_set(L_INFO); /* initialize exit handlers */ int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT }; unsigned int i; for(i=0; i<sizeof(signals)/sizeof(int); i++) { if(signal(signals[i], _exit_signal_handler) == SIG_ERR) { NFT_LOG_PERROR("signal()"); goto _m_exit; } } /* default fps */ _c.fps = 25; /* default mechanism */ _c.method = METHOD_MIN+1; /* default config-filename */ if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcap.xml")) goto _m_exit; /* parse cmdline-arguments */ if(!_parse_args(argc, argv)) goto _m_exit; /* print welcome msg */ NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcap_version_long()); NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get())); /* initialize preferences context */ if(!(prefs = led_prefs_init())) return -1; /* parse prefs-file */ LedPrefsNode *pnode; if(!(pnode = led_prefs_node_from_file(_c.prefsfile))) { NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"", _c.prefsfile); goto _m_exit; } /* create setup from prefs-node */ if(!(setup = led_prefs_setup_from_node(prefs, pnode))) { NFT_LOG(L_ERROR, "No valid setup found in preferences file."); led_prefs_node_free(pnode); goto _m_exit; } /* free preferences node */ led_prefs_node_free(pnode); /* determine width of input-frames */ LedFrameCord width, height; if((width = led_setup_get_width(setup)) > _c.width) { NFT_LOG(L_WARNING, "LED-Setup width (%d) > our width (%d). Using setup-value", width,_c.width); /* use dimensions of mapped chain */ _c.width = width; } /* determine height of input-frames */ if((height = led_setup_get_height(setup)) > _c.height) { NFT_LOG(L_WARNING, "LED-Setup height (%d) > our height (%d). Using setup-value.", height, _c.height); /* use dimensions of mapped chain */ _c.height = height; } if(_c.width < 0) { NFT_LOG(L_ERROR, "width (%d) < 0", _c.width); goto _m_exit; } if(_c.height < 0) { NFT_LOG(L_ERROR, "height (%d) < 0", _c.height); goto _m_exit; } /* sanitize x-offset @todo check for maximum */ if(_c.x < 0) { NFT_LOG(L_ERROR, "Invalid x coordinate: %d, using 0", _c.x); _c.x = 0; } /* sanitize y-offset @todo check for maximum */ if(_c.y < 0) { NFT_LOG(L_ERROR, "Invalid y coordinate: %d, using 0", _c.y); _c.y = 0; } /* initialize capture mechanism (only imlib for now) */ if(!capture_init(_c.method)) goto _m_exit; /* allocate framebuffer */ NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)", _c.width, _c.height, capture_format()); if(!(frame = led_frame_new(_c.width, _c.height, led_pixel_format_from_string(capture_format())))) goto _m_exit; /* respect endianess */ led_frame_set_big_endian(frame, capture_is_big_endian()); /* get first hardware */ LedHardware *hw; if(!(hw = led_setup_get_hardware(setup))) goto _m_exit; /* initialize pixel->led mapping */ if(!led_hardware_list_refresh_mapping(hw)) goto _m_exit; /* precalc memory offsets for actual mapping */ if(!led_chain_map_from_frame(led_hardware_get_chain(hw), frame)) goto _m_exit; /* set saved gain to all registered hardware instances */ if(!led_hardware_list_refresh_gain(hw)) goto _m_exit; /* print some debug-info */ led_frame_print(frame, L_VERBOSE); led_hardware_print(hw, L_VERBOSE); /* initially sample time for frametiming */ if(!led_fps_sample()) goto _m_exit; /* output some useful info */ NFT_LOG(L_INFO, "Capturing %dx%d pixels at position x/y: %d/%d", _c.width, _c.height, _c.x, _c.y); /* loop until _c.running is set to FALSE */ _c.running = TRUE; while(_c.running) { /* capture frame */ if(!(capture_frame(frame, _c.x, _c.y))) break; /* print frame for debugging */ //led_frame_buffer_print(frame); /* map from frame */ LedHardware *h; for(h = hw; h; h = led_hardware_list_get_next(h)) { if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame)) { NFT_LOG(L_ERROR, "Error while mapping frame"); break; } } /* send frame to hardware(s) */ led_hardware_list_send(hw); /* delay in respect to fps */ if(!led_fps_delay(_c.fps)) break; /* show frame */ led_hardware_list_show(hw); /* save time when frame is displayed */ if(!led_fps_sample()) break; } /* mark success */ res = 0; _m_exit: /* deinitialize capture mechanism */ capture_deinit(); /* free frame */ led_frame_destroy(frame); /* destroy config */ led_setup_destroy(setup); /* destroy config */ led_prefs_deinit(prefs); return res; }
/** * 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; }