Strona 2 z 2

: 26 sierpnia 2015, 11:58
autor: pawkrol
Pokaż

Kod: Zaznacz cały

ls -l /etc/lcd4linux.conf
Tak na marginesie to skąd miałeś sterowniki do ramek SPF-85V i SPF-72H.
Może załącz zmodyfikowany plik drv_SamsungSPF.c może komuś się przyda.

: 26 sierpnia 2015, 13:40
autor: kamil2234
Repozytorium ściągamy z svn co https://ssl.bulix.org/svn/lcd4linux/trunk lcd4linux

potem wydajemy polecenia:

Kod: Zaznacz cały

cd lcd4linux
Wystraczy podmienić plik drv_SamsungSPF.c na ten kod poniżej.

Kod: Zaznacz cały

/* $Id: drv_SamsungSPF 975 2009-01-18 11:16:20Z michael $
   * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_SamsungSPF.c $
   *
   * SamsungSPF lcd4linux driver
   *
   * Copyright (C) 2012 Sascha Plazar <sascha@plazar.de>
   * Copyright (C) 2005, 2006, 2007 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
   *
   * This driver is based on playusb.c created on Aug 2, 2010 by Andre Puschmann
   * which is in turn based on code from Grace Woo:
   *    http://web.media.mit.edu/~gracewoo/stuff/picframe
   *
   * This file is part of LCD4Linux.
   *
   * LCD4Linux is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2, or (at your option)
   * any later version.
   *
   * LCD4Linux is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   */

/*
   *
   * exported fuctions:
   *
   * struct DRIVER drv_SamsungSPF
   *
   */

#include "config.h"

#include <stdio.h>
#include <string.h>

#include <usb.h>
#include <jpeglib.h>

#include "debug.h"
#include "cfg.h"
#include "qprintf.h"
#include "timer.h"
#include "drv.h"

/* graphic display? */
#include "drv_generic_graphic.h"

// Drivername for verbose output
static char Name[] = "SamsungSPF";

struct SPFdev {
    const char type[64];
    const int vendorID;
    struct {
        const int storageMode;
        const int monitorMode;
    } productID;
    const unsigned int xRes;
    const unsigned int yRes;
};

static struct SPFdev spfDevices[] = {
     {
     .type = "SPF-72H",
     .vendorID = 0x04e8,
     .productID = {0x200a, 0x200b},
     .xRes = 800,
     .yRes = 480,
     },
    {
     .type = "SPF-75H",
     .vendorID = 0x04e8,
     .productID = {0x200e, 0x200f},
     .xRes = 800,
     .yRes = 480,
     },
    {
     .type = "SPF-83H",
     .vendorID = 0x04e8,
     .productID = {0x200c, 0x200d},
     .xRes = 800,
     .yRes = 600,
     },
    {
     .type = "SPF-85H",
     .vendorID = 0x04e8,
     .productID = {0x2012, 0x2013},
     .xRes = 800,
     .yRes = 600,
     },
    {
     .type = "SPF-85P",
     .vendorID = 0x04e8,
     .productID = {0x2016, 0x2017},
     .xRes = 800,
     .yRes = 600,
     },
    {
     .type = "SPF-85V",
     .vendorID = 0x04e8,
     .productID = {0x201a, 0x201f},
     .xRes = 800,
     .yRes = 600,
     },
    {
     .type = "SPF-87H",
     .vendorID = 0x04e8,
     .productID = {0x2033, 0x2034},
     .xRes = 800,
     .yRes = 480,
     },
    {
     .type = "SPF-107H",
     .vendorID = 0x04e8,
     .productID = {0x2035, 0x2036},
     .xRes = 1024,
     .yRes = 600,
     },
    {
     .type = "SPF-105P",
     .vendorID = 0x04e8,
     .productID = {0x201c, 0x201b},
     .xRes = 1024,
     .yRes = 600,
     },
    {
     .type = "SPF-1000P",
     .vendorID = 0x04e8,
     .productID = {0x2039, 0x2040},
     .xRes = 1024,
     .yRes = 600,
     },
    {
     .type = "SPF-700T",
     .vendorID = 0x04e8,
     .productID = {0x204f, 0x2050},
     .xRes = 800,
     .yRes = 600,
     },
};

static int numFrames = sizeof(spfDevices) / sizeof(spfDevices[0]);

struct usb_device *myDev;
usb_dev_handle *myDevHandle;
struct SPFdev *myFrame;

typedef struct {
    unsigned char R, G, B;
} RGB;

static struct {
    RGB *buf;
    int dirty;
    int fbsize;
} image;

static struct {
    unsigned char *buf;
    unsigned long int size;
} jpegImage;


/****************************************/
/***  hardware dependant functions    ***/
/****************************************/


/* please note that in-memory compression doesn't work satisfactory */
int convert2JPG()
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    int row_stride;             /* physical row width in buffer */
    JSAMPROW row_pointer[1];    /* pointer to a single row */

    /* Initialize compression frame */
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &jpegImage.buf, &jpegImage.size);

    cinfo.image_width = myFrame->xRes;
    cinfo.image_height = myFrame->yRes;
    cinfo.input_components = sizeof(RGB);
    cinfo.in_color_space = JCS_RGB;

    /* call some jpeg helpers */
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 100, 1);   /*set the quality [0..100]  */
    jpeg_start_compress(&cinfo, 1);

    row_stride = cinfo.image_width;

    /* Convert line by line */
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0] = (JSAMPROW) (image.buf + (cinfo.next_scanline * row_stride));
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    /* Finish compression and free internal memory */
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    return 0;
}


// Find specific Samsung device
static void drv_SamsungSPF_find()
{
    info("%s: Searching SPF.", Name);

    /* open USB device */
    struct usb_bus *bus;
    struct usb_device *dev;

    usb_init();
    usb_find_busses();
    usb_find_devices();

    for (bus = usb_busses; bus; bus = bus->next) {
        for (dev = bus->devices; dev; dev = dev->next) {
            if (dev->descriptor.idVendor == myFrame->vendorID) {
                if (dev->descriptor.idProduct == myFrame->productID.storageMode) {

                    info("Samsung photoframe in Mass Storage mode found.");
                    myDev = dev;

                    return;
                } else if (dev->descriptor.idProduct == myFrame->productID.monitorMode) {

                    info("Samsung photoframe in Custom Product mode found.");
                    myDev = dev;

                    return;
                }
            }
        }
    }

    free(bus);
    myDev = 0;
}


static int drv_SamsungSPF_open()
{
    if (!myDev) {
        error("%s: No device specified!", Name);
        return -1;
    }

    int res = -1;
    char buf[256];

    if (myDev->descriptor.idProduct == myFrame->productID.storageMode) {
        info("%s: Opening device and switching to monitor mode", Name);

        myDevHandle = usb_open(myDev);

        setuid(getuid());

        strcpy(buf, "** no string **");
        res = usb_get_string_simple(myDevHandle, myDev->descriptor.iManufacturer, buf, sizeof(buf));
        debug("usb_get_string_simple => %d, %s", res, buf);

        memset(buf, 0, 256);

        res = usb_control_msg(myDevHandle, USB_TYPE_STANDARD | USB_ENDPOINT_IN,
                              USB_REQ_GET_DESCRIPTOR, 0xfe, 0xfe, buf, 0xfe, 1000);
        /* usb_close( myDev ); */
        // Sleep some time before research
        sleep(1);
        drv_SamsungSPF_find();
    } else
        info("%s: No device in storage mode found", Name);

    if (myDev->descriptor.idProduct == myFrame->productID.storageMode) {
        error("%s: Was not able to switch to monitor mode!", Name);
        return -1;
    }

    if (myDev->descriptor.idProduct == myFrame->productID.monitorMode) {
        info("%s: Device '%s' is now in monitor mode.", Name, myFrame->type);
        myDevHandle = usb_open(myDev);
        return 0;
    }

    error("Unknown error: usb_control_msg() = %d", res);
    return -1;
}


/* dummy function that sends something to the display */
static int drv_SamsungSPF_send(char *data, unsigned int len)
{
    char usb_hdr[12] = { 0xa5, 0x5a, 0x18, 0x04, 0xff, 0xff,
        0xff, 0xff, 0x48, 0x00, 0x00, 0x00
    };
    char buffer[1] = { 0x0 };
    int usb_timeout = 1000;
    int usb_endpoint = 0x2;
    int ret;

    *(int *) (usb_hdr + 4) = len;

    debug("bytes_to_send: %d, offset: %d", len, 12);

    /* Send USB header */
    if ((ret = usb_bulk_write(myDevHandle, usb_endpoint, usb_hdr, 12, usb_timeout)) < 0) {
        error("%s: Error occurred while writing data to device.", Name);
        error("%s: usb_bulk_write returned: %d", Name, ret);
        return -1;
    }

    /* Send JPEG image */
    if ((ret = usb_bulk_write(myDevHandle, usb_endpoint, data, len, usb_timeout)) < 0) {
        error("%s: Error occurred while writing data to device.", Name);
        error("%s: usb_bulk_write returned: %d", Name, ret);
        return -1;
    }

    /* Finish transmission by sending zero */
    if ((ret = usb_bulk_write(myDevHandle, usb_endpoint, buffer, 1, usb_timeout)) < 0) {
        error("%s: Error occurred while writing data to device.", Name);
        error("%s: usb_bulk_write returned: %d", Name, ret);
        return -1;
    }

    return 0;
}


/* for graphic displays only */
static void drv_SamsungSPF_blit(const int row, const int col, const int height, const int width)
{
    int r, c;

    for (r = row; r < row + height; r++) {
        for (c = col; c < col + width; c++) {
            RGB p1 = image.buf[r * myFrame->xRes + c];
            RGBA p2 = drv_generic_graphic_rgb(r, c);
            if (p1.R != p2.R || p1.G != p2.G || p1.B != p2.B) {
                image.buf[r * myFrame->xRes + c].R = p2.R;
                image.buf[r * myFrame->xRes + c].G = p2.G;
                image.buf[r * myFrame->xRes + c].B = p2.B;
                image.dirty = 1;
            }
        }
    }
}


static void drv_SamsungSPF_timer( __attribute__ ((unused))
                                 void *notused)
{
    if (image.dirty) {
        debug("FB dirty, writing jpeg...");
        convert2JPG();

        /* Sent image to display */
        if ((drv_SamsungSPF_send((char *) jpegImage.buf, jpegImage.size)) != 0) {
            error("%s: Error occurred while sending jpeg image to device.", Name);
        }
        /* Clean dirty bit */
        image.dirty = 0;

        /* Free JPEG buffer since a new is allocated each time an image is
           compressed */
        if (jpegImage.size)
            free(jpegImage.buf);
        jpegImage.size = 0;
    }
}


/* start graphic display */
static int drv_SamsungSPF_start(const char *section)
{
    int timerInterval = 1000;
    char *s;

    cfg_number(section, "update", timerInterval, 0, -1, &timerInterval);
    debug("Updating display every %dms", timerInterval);

    DROWS = myFrame->yRes;
    DCOLS = myFrame->xRes;
    info("%s: Using SPF with %dx%d pixels.", Name, DCOLS, DROWS);

    s = cfg_get(section, "Font", "6x8");
    if (s == NULL || *s == '\0') {
        error("%s: no '%s.Font' entry from %s", Name, section, cfg_source());
        return -1;
    }

    XRES = -1;
    YRES = -1;
    if (sscanf(s, "%dx%d", &XRES, &YRES) != 2 || XRES < 1 || YRES < 1) {
        error("%s: bad Font '%s' from %s", Name, s, cfg_source());
        return -1;
    }

    if (XRES < 6 || YRES < 8) {
        error("%s: bad Font '%s' from %s (must be at least 6x8)", Name, s, cfg_source());
        return -1;
    }
    free(s);

    /* Allocate framebuffer */
    image.fbsize = myFrame->xRes * myFrame->yRes * sizeof(RGB);
    image.buf = malloc(image.fbsize);
    memset(image.buf, 128, image.fbsize);
    image.dirty = 0;

    /* JPEG buffer is allocated by jpeglib */
    jpegImage.buf = 0;
    jpegImage.size = 0;

    /* regularly transmit the image */
    timer_add(drv_SamsungSPF_timer, NULL, timerInterval, 0);

    return 0;
}



/****************************************/
/***        exported functions        ***/
/****************************************/


/* list models */
int drv_SamsungSPF_list(void)
{
    int i;

    printf("SamsungSPF driver, supported models [");
    for (i = 0; i < numFrames; i++) {
        printf("%s", spfDevices[i].type);
        if (i < numFrames - 1)
            printf(", ");
    }
    printf("]\n");

    return 0;
}


/* initialize driver & display */
/* use this function for a graphic display */
int drv_SamsungSPF_init(const char *section, const int quiet)
{
    info("%s: Initializing SPF.", Name);

    char *s;
    int i;

    myDev = 0;
    myFrame = 0;

    // Look for model entry in config
    s = cfg_get(section, "Model", NULL);
    if (s == NULL || *s != '\0') {
        s = cfg_get(section, "Model", NULL);
        if (s == NULL || *s == '\0') {

            drv_SamsungSPF_list();
            error("%s: no '%s.Model' entry from %s", Name, section, cfg_source());
            return -1;
        }
    }
    // Look for specified device
    for (i = 0; i < numFrames; i++) {
        if (strcasecmp(s, spfDevices[i].type) == 0) {
            myFrame = &spfDevices[i];
            info("%s: Configured for model %s.", Name, spfDevices[i].type);
            break;
        }
    }

    if (!myFrame) {
        drv_SamsungSPF_list();
        error("%s: unknown model '%s'!", Name, s);
        return -1;
    }

    free(s);

    /* try to open USB device */
    drv_SamsungSPF_find();
    if (!myDev) {
        error("%s: No Samsung '%s' found!", Name, myFrame->type);
        return -1;
    }

    /* open display and switch to monitor mode if necessary */
    if (drv_SamsungSPF_open() == -1)
        return -1;

    int ret;

    /* real worker functions */
    drv_generic_graphic_real_blit = drv_SamsungSPF_blit;

    /* start display */
    if ((ret = drv_SamsungSPF_start(section)) != 0)
        return ret;

    /* initialize generic graphic driver */
    if ((ret = drv_generic_graphic_init(section, Name)) != 0)
        return ret;

    if (!quiet) {
        char buffer[40];
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
        if (drv_generic_graphic_greet(buffer, NULL)) {
            sleep(3);
            drv_generic_graphic_clear();
        }
    }

    return 0;
}


/* close driver & display */
/* use this function for a graphic display */
int drv_SamsungSPF_quit(const int quiet)
{

    info("%s: shutting down.", Name);

    /* clear display */
    drv_generic_graphic_clear();

    /* say goodbye... */
    if (!quiet) {
        drv_generic_graphic_greet("goodbye!", NULL);
    }

    drv_generic_graphic_quit();

    debug("closing connection");
    printf("%s: Closing driver...\n", Name);
    usb_close(myDevHandle);
    free(myDev);
    free(myDevHandle);

    return (0);
}


/* use this one for a graphic display */
DRIVER drv_SamsungSPF = {
    .name = Name,
    .list = drv_SamsungSPF_list,
    .init = drv_SamsungSPF_init,
    .quit = drv_SamsungSPF_quit,
};
Następnie trzebaq poddać pliki kompilacji :)

Kod: Zaznacz cały

./configure
  ./bootstrap  

make

Jak widać żeby kompilacja przebiegła prawidło potrzebne były dodatkowe pakiety, które trzeba było uprzednio doinstalować.

Dalej mam jeszcze problem z odpaleniem :

Kod: Zaznacz cały

pi@raspberrypi3 /etc $ ls -l /etc/lcd4linux.conf
-rw------- 1 root root 344 Aug 25 19:35 /etc/lcd4linux.conf

: 26 sierpnia 2015, 14:18
autor: pawkrol
To wygląda na to iż uprawnienia muszą być takie jak użytkownika z którego uruchamiasz skrypt.
np

Kod: Zaznacz cały

chown  jan:jan/etc/lcd4linux.conf
W twoim przypadku powinieneś uruchomić z poziomu root (przez sudo)

: 26 sierpnia 2015, 18:07
autor: kamil2234
Cały czas próbuję z

Kod: Zaznacz cały

sudo lcd4linux -Fvv
:) Podniosłem uprawnia na 777 oraz zmieniałem grupę i właściciela pliku na "pi". Dalej nic...

: 26 sierpnia 2015, 18:24
autor: marcin1982
Zmienić uprawnienia jako root.

Po co do uruchomienia mieszasz sudo? Uruchom z konta użytkownika.

: 26 sierpnia 2015, 18:46
autor: kamil2234
Zmieniłem ramkę na SPF-72H i poszło, ale z kolejnymi błędami.

Kod: Zaznacz cały

sudo lcd4linux -Fvv
LCD4Linux 0.11.0-SVN-1193 starting
Dump of /etc/lcd4linux.conf:
  Display                   'Samsung'
  Display:Samsung.Driver    'SamsungSPF'
  Display:Samsung.Model     'SPF-72H'
  Display:Samsung.Size      '20x2'
  Display:Samsung.Update    1000
  Layout                    'Simple'
  Layout:Simple.Row01.Col01 'HELLO'
  Widget:HELLO.Background   'ffffff'
  Widget:HELLO.class        'Text'
  Widget:HELLO.expression   'Hello World.'
  Widget:HELLO.Foreground   '000000'
  Widget:HELLO.Update       5000

[DBus] Error connecting to the dbus session bus: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11

[raspi] WARNING: Plugin is not enabled! (set 'enabled 1' to enable this plugin)
lcd4linux.c: initializing driver SamsungSPF
SamsungSPF: Initializing SPF.
SamsungSPF: Configured for model SPF-72H.
SamsungSPF: Searching SPF.
Samsung photoframe in Custom Product mode found.
SamsungSPF: No device in storage mode found
SamsungSPF: Device 'SPF-72H' is now in monitor mode.
drv_SamsungSPF.c: Updating display every 1000ms
SamsungSPF: Using SPF with 800x480 pixels.
initializing layout 'Simple'
layout.c: Layout:Simple: migrating 'row01.col01' to 'Layer:1.row01.col01'
Creating new timer group (5000 ms)
 widget 'HELLO': Class 'text', Parent '<root>', Layer 1, Row 0, Col 0 (to 0,10)
lcd4linux.c: starting main loop
drv_SamsungSPF.c: FB dirty, writing jpeg...
drv_SamsungSPF.c: bytes_to_send: 6627, offset: 12
SamsungSPF: Error occurred while writing data to device.
SamsungSPF: usb_bulk_write returned: -110
SamsungSPF: Error occurred while sending jpeg image to device.
Timer #0 skipped 3 interval(s) or 3000 ms.
drv_SamsungSPF.c: FB dirty, writing jpeg...
drv_SamsungSPF.c: bytes_to_send: 7498, offset: 12

tak wygląda teraz plik konfiguracyjny /etc/lcd4linux.conf

Kod: Zaznacz cały

Display Samsung {
    Driver  'SamsungSPF'
    Model   'SPF-72H'
    Size    '20x2'
    Update   1000
}

Widget HELLO {
    class 'Text'
    expression 'Hello World.'
    width 12
    align 'L'
    update 5000000
    Background 'ffffff'
    Foreground  '000000'
}

Layout Simple {
    Row01.Col01 'HELLO'
}

Display 'Samsung'
Layout  'Simple'

: 26 sierpnia 2015, 18:46
autor: pawkrol
Z ciekawości sprawdziłem ten pakiet (arch: amd64). Oczywiście kompilowany.

Teraz tak:
1) Uprawnienia musiałem mieć 600.
2) root:root - program uruchomił tylko root
3) user:user - program uruchomił tylko user

2 oraz 3 - Gdy ktoś inny uruchamiał błąd miałem identyczny do twojego.
security error: owner and/or group of '/etc/lcd4linux.conf' don't match

Dodane:

Używasz ramki SPF-72H ?

: 26 sierpnia 2015, 20:02
autor: kamil2234
tak spf-72h

Czytam kod sterownika i tak mnie korci czy przypadkiem nie zmienić usb_timeout = 1000 na 1500 albo więcej. Najpierw jednak zmienię może jeszcze kabel na inny.

Niestety zmiana kabla nic nie dała :( Udaje się na chwilę wrzucić biały background bez napisu.

Naprawiłem ten błąd:

Kod: Zaznacz cały

[raspi] WARNING: Plugin is not enabled! (set 'enabled 1' to enable this plugin)
dodając do configa /etc/lcd4linux.conf

taki wpis

Kod: Zaznacz cały



Plugin raspi {
    enabled 1
}
Zastanawiam się jeszcze nad tym błędem :

Kod: Zaznacz cały


[DBus] Error connecting to the dbus session bus: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11


: 27 sierpnia 2015, 13:34
autor: kamil2234
Niestety utknołem na tym błędzie :( Czy ktoś ma jakiś pomysł ?

Kod: Zaznacz cały


SamsungSPF: Error occurred while writing data to device. 
SamsungSPF: usb_bulk_write returned: -110 
SamsungSPF: Error occurred while sending jpeg image to device.