Skip to content
Snippets Groups Projects
Commit eb36cf8e authored by daniel's avatar daniel
Browse files

Copy over files from ledctrl

parent 8f1e275e
Branches
No related tags found
No related merge requests found
bin_PROGRAMS = \
mensa-control
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/include
# $(some_CFLAGS)
EXTRA_DIST = \
autogen.sh
......@@ -14,12 +6,4 @@ MAINTAINERCLEANFILES = \
aclocal.m4 \
Makefile.in
#
# binary
#
mensa_control_SOURCES = \
mensa-control.c
#mensa_control_LDADD = \
# $(some_LIBS)
SUBDIRS = src/
......@@ -2,8 +2,8 @@ AC_PREREQ(2.59)
esyscmd([echo "define(myversion, $(dir=$(basename $(pwd)); if test \"${dir%%-trunk}\" != \"$dir\"; then echo 99999999-9; else prefix=${dir%%-[0-9]*-[0-9]}; echo ${dir##$prefix-}; fi))"])
AC_INIT([mensa-control], myversion, [bugs@pengutronix.de])
AC_CONFIG_SRCDIR([mensa-control.c])
AC_INIT([mensa-control], myversion, [daniel@totalueberwachung.de])
AC_CONFIG_SRCDIR([src])
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
......@@ -42,6 +42,8 @@ AM_INIT_AUTOMAKE([foreign no-exeext dist-bzip2])
#AC_SUBST(REQUIRES_LIBSOMETHING)
#PKG_CHECK_MODULES(libsomething, $REQUIRES_LIBSOMETHING)
PKG_CHECK_MODULES(ZMQ, libzmq)
#
# Debugging
......@@ -65,6 +67,7 @@ fi
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
bin_PROGRAMS = \
mensa-ctrl mensa-serv
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/include
$(ZMQ_CFLAGS)
#
# binary
#
ledctrl_SOURCES = \
mensactrl.c
ledctrl_LDADD = \
$(ZMQ_LIBS)
ledserv_SOURCES = \
mensaserv.c
ledserv_LDADD = \
$(ZMQ_LIBS)
/*
* Control WS281X LEDs connected to the LCDIF
*
* Code taken from the proof-of-concept tool by
* (C) 2013 Jeroen Domburg (jeroen AT spritesmods.com)
* This program 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 3 of the License, or
* (at your option) any later version.
* This program 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <math.h>
#include <zmq.h>
struct pixel {
uint16_t x, y;
uint8_t r, g, b;
} __attribute__((packed));
struct ws281x_fb {
int x_res, y_res;
int fd;
uint8_t *inputfb;
uint16_t *fbmem;
};
//This will encode a framebuffer with per-led RGB values into the weird framebuffer
//data values we need to form the correct WS2811 driving waveform.
void encodeToFb(struct ws281x_fb *wsfb) {
int pix, col, bit, bitmask, strip, n;
int p=0;
for (pix=0; pix<wsfb->x_res; pix++) { //STRIPLEN points...
for (col=0; col<3; col++) { //...of 3 bytes (r, g. b)
bitmask=0x80;
for (bit=0; bit<8; bit++) { //...of 8 bits each.
/* At 4MHz, a bit has 5 cycles. For an 1, it's high 4, low one. For an 0, it's high one, low 4. */
p++; /* First cycle is always 1 */
n=0;
//Iterate through every LED-strip to fetch the bit it needs to send out. Combine those
//in n.
for (strip=0; strip<wsfb->y_res; strip++) {
if (wsfb->inputfb[(wsfb->x_res*strip*3)+(pix*3)+col]&bitmask) n|=1<<strip;
}
wsfb->fbmem[p++]=n;
wsfb->fbmem[p++]=n; //Middle 3 are dependent on bit value
wsfb->fbmem[p++]=n;
p++; /* Last cycle is always 0 */
bitmask>>=1; //next bit in byte
}
}
}
}
//Helper function to set the value of a single pixel in the 'framebuffer'
//of LED pixel values.
void setPixel(struct ws281x_fb *wsfb, int pixel, int strip, int r, int g, int b) {
int pos=(strip*wsfb->x_res*3)+pixel*3;
if (strip<0 || strip>=wsfb->x_res) return;
if (pixel<0 || pixel>=wsfb->y_res) return;
wsfb->inputfb[pos++]=r; //My strips have R and G switched.
wsfb->inputfb[pos++]=g;
wsfb->inputfb[pos++]=b;
}
static struct ws281x_fb *setup_fb(const char *devname, int x, int y)
{
struct ws281x_fb *wsfb = malloc(sizeof(struct ws281x_fb));
int i;
wsfb->fd = open(devname, O_RDWR);
if (wsfb->fd < 0) {
perror("opening fb");
free(wsfb);
exit(1);
}
wsfb->inputfb = malloc(x*y*3);
if (!wsfb->inputfb) {
free(wsfb);
exit(1);
}
memset(wsfb->inputfb, 0, x*y*3);
wsfb->fbmem=mmap(NULL, x*5*24*2, PROT_READ|PROT_WRITE, MAP_SHARED, wsfb->fd, 0);
if (wsfb->fbmem==NULL) {
perror("mmap'ing fb");
free(wsfb->inputfb);
free(wsfb);
exit(1);
}
for (i = 0; i < x*y*5*24; i++) {
/* Init frame buffer bit clock. */
if (i % 5 == 0)
wsfb->fbmem[i] = 0xffff;
if (i % 5 == 4)
wsfb->fbmem[i] = 0x00;
}
wsfb->x_res = x;
wsfb->y_res = y;
return wsfb;
}
int main(int argc, char *argv[]) {
struct ws281x_fb *wsfb;
void *context = zmq_ctx_new ();
void *subscriber = zmq_socket (context, ZMQ_SUB);
int rc;
if (argc != 2)
exit(1);
rc = zmq_connect (subscriber, "tcp://10.0.0.1:5556");
if (rc < 0)
perror("zmq_connect");
rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE,
NULL, 0);
if (rc < 0)
perror("zmq_connect");
wsfb = setup_fb(argv[1], 10, 2);
while (1) {
struct pixel pix;
zmq_recv(subscriber, &pix, sizeof(pix), 0);
printf("(%u, %u): r=%02x g=%02x b=%02x\n", pix.x, pix.y, pix.r, pix.g, pix.b);
setPixel(wsfb, pix.x, pix.y, pix.r, pix.g, pix.b);
encodeToFb(wsfb);
}
return 0;
}
/*
* Control WS281X LEDs connected to the LCDIF
*
* Code taken from the proof-of-concept tool by
* (C) 2013 Jeroen Domburg (jeroen AT spritesmods.com)
* This program 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 3 of the License, or
* (at your option) any later version.
* This program 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <math.h>
#include <zmq.h>
struct pixel {
uint16_t x, y;
uint8_t r, g, b;
} __attribute__((packed));
static void fade(void *publisher)
{
struct pixel pix1 = { .x = 0, .y = 0, .r = 0, .g = 0, .b = 0 };
struct pixel pix2 = { .x = 1, .y = 0, .r = 0, .g = 0, .b = 0 };
struct pixel pix3 = { .x = 2, .y = 0, .r = 0, .g = 0, .b = 0 };
int state = 0;
while (1) {
switch (state) {
case 0:
pix1.r++;
pix2.g++;
pix3.b++;
if (pix1.r == 255)
state++;
break;
case 1:
pix1.r--;
pix1.g++;
pix2.g--;
pix2.b++;
pix3.b--;
pix3.r++;
if (pix1.g == 255)
state++;
break;
case 2:
pix1.g--;
pix1.b++;
pix2.b--;
pix2.r++;
pix3.r--;
pix3.g++;
if (pix1.b == 255)
state++;
break;
case 3:
pix1.b--;
pix1.r++;
pix2.r--;
pix2.g++;
pix3.g--;
pix3.b++;
if (pix1.r == 255)
state = 1;
break;
}
zmq_send(publisher, &pix1, sizeof(pix1), 0);
printf("(%u, %u): r=%02x g=%02x b=%02x\n", pix1.x, pix1.y, pix1.r, pix1.g, pix1.b);
//zmq_send(publisher, &pix2, sizeof(pix2), 0);
//printf("(%u, %u): r=%02x g=%02x b=%02x\n", pix2.x, pix2.y, pix2.r, pix2.g, pix2.b);
//zmq_send(publisher, &pix3, sizeof(pix3), 0);
//printf("(%u, %u): r=%02x g=%02x b=%02x\n", pix3.x, pix3.y, pix3.r, pix3.g, pix3.b);
usleep(10000);
}
}
int main(void)
{
void *context = zmq_ctx_new ();
void *publisher = zmq_socket (context, ZMQ_PUB);
int rc;
rc = zmq_bind (publisher, "tcp://*:5556");
if (rc < 0)
perror("zmq_bind");
fade(publisher);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment