Exemple #1
0
/**
 * 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;
}