diff --git a/mensa-control.c b/mensa-control.c deleted file mode 100644 index f89e37e6ffa704f8c0ace8d7158fdc24856ab146..0000000000000000000000000000000000000000 --- a/mensa-control.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <stdio.h> - -int main(void) -{ - printf("hello fish!\n"); - return 0; -} - diff --git a/src/Makefile.am b/src/Makefile.am index 6168a4703a0fc216891920cfbfc9ea3e2f8b1b11..c84955da02d0582dbba059e91c64dcc50383e466 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = \ - mensa-ctrl mensa-serv + mensactrl mensaserv AM_CPPFLAGS = \ -I$(top_srcdir)/include \ @@ -9,15 +9,15 @@ AM_CPPFLAGS = \ # # binary # -ledctrl_SOURCES = \ +mensactrl_SOURCES = \ mensactrl.c -ledctrl_LDADD = \ +mensactrl_LDADD = \ $(ZMQ_LIBS) -ledserv_SOURCES = \ +mensaserv_SOURCES = \ mensaserv.c -ledserv_LDADD = \ +mensaserv_LDADD = \ $(ZMQ_LIBS) diff --git a/src/mensactrl.c b/src/mensactrl.c index bb385da03805893d15f662bb1eee049e5b10c95a..625d178acfd05484f571c99fd9da8b1251dc5702 100644 --- a/src/mensactrl.c +++ b/src/mensactrl.c @@ -1,8 +1,7 @@ /* - * Control WS281X LEDs connected to the LCDIF + * Control Mensadisplay connected to the LCDIF * - * Code taken from the proof-of-concept tool by - * (C) 2013 Jeroen Domburg (jeroen AT spritesmods.com) + * (C) 2014 Daniel Willmann <daniel@totalueberwachung.de> * 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 @@ -33,98 +32,87 @@ #include <zmq.h> -struct pixel { - uint16_t x, y; - uint8_t r, g, b; -} __attribute__((packed)); +#include "common.h" -struct ws281x_fb { +struct mensa_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 - } +void encodeToFb(struct mensa_fb *mensafb) { + int pix, row, idx; + uint16_t pattern; + + for (row = 0; row < mensafb->y_res; row++) { + for (pix=0; pix<mensafb->x_res; pix++) { + idx = row*mensafb->x_res + pix; + if (mensafb->inputfb[idx] > 0) + pattern = 1; + else + pattern = 0; + pattern |= row << 13; + + mensafb->fbmem[idx] = pattern; } } } -//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; +void setPixel(struct mensa_fb *mensafb, int col, int row, uint8_t bright) +{ + int idx = row * mensafb->x_res + col; + + if (col < 0 || col >= mensafb->x_res) + return; + if (row < 0 || row >= mensafb->y_res) + return; + + mensafb->inputfb[idx] = bright; } -static struct ws281x_fb *setup_fb(const char *devname, int x, int y) +static struct mensa_fb *setup_fb(const char *devname, int x, int y) { - struct ws281x_fb *wsfb = malloc(sizeof(struct ws281x_fb)); + struct mensa_fb *mensafb = malloc(sizeof(struct mensa_fb)); int i; - wsfb->fd = open(devname, O_RDWR); - if (wsfb->fd < 0) { + mensafb->fd = open(devname, O_RDWR); + if (mensafb->fd < 0) { perror("opening fb"); - free(wsfb); + free(mensafb); exit(1); } - wsfb->inputfb = malloc(x*y*3); - if (!wsfb->inputfb) { - free(wsfb); + mensafb->inputfb = malloc(x*y*3); + if (!mensafb->inputfb) { + free(mensafb); exit(1); } - memset(wsfb->inputfb, 0, x*y*3); + memset(mensafb->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) { + mensafb->fbmem=mmap(NULL, x*5*24*2, PROT_READ|PROT_WRITE, MAP_SHARED, mensafb->fd, 0); + if (mensafb->fbmem==NULL) { perror("mmap'ing fb"); - free(wsfb->inputfb); - free(wsfb); + free(mensafb->inputfb); + free(mensafb); exit(1); } for (i = 0; i < x*y*5*24; i++) { /* Init frame buffer bit clock. */ if (i % 5 == 0) - wsfb->fbmem[i] = 0xffff; + mensafb->fbmem[i] = 0xffff; if (i % 5 == 4) - wsfb->fbmem[i] = 0x00; + mensafb->fbmem[i] = 0x00; } - wsfb->x_res = x; - wsfb->y_res = y; + mensafb->x_res = x; + mensafb->y_res = y; - return wsfb; + return mensafb; } int main(int argc, char *argv[]) { - struct ws281x_fb *wsfb; + struct mensa_fb *mensafb; void *context = zmq_ctx_new (); void *subscriber = zmq_socket (context, ZMQ_SUB); int rc; @@ -141,14 +129,14 @@ int main(int argc, char *argv[]) { if (rc < 0) perror("zmq_connect"); - wsfb = setup_fb(argv[1], 10, 2); + mensafb = setup_fb(argv[1], 40, 7); 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); + printf("(%u, %u): bright=%02x\n", pix.x, pix.y, pix.bright); + setPixel(mensafb, pix.x, pix.y, pix.bright); + encodeToFb(mensafb); } return 0; diff --git a/src/mensaserv.c b/src/mensaserv.c index 33d8ea4982152798c8e1c776e7afadad2b605d19..17741308935607833e3c225e8382a8f99e9a539a 100644 --- a/src/mensaserv.c +++ b/src/mensaserv.c @@ -1,8 +1,7 @@ /* - * Control WS281X LEDs connected to the LCDIF + * Control the Mensadisplay connected to the LCDIF * - * Code taken from the proof-of-concept tool by - * (C) 2013 Jeroen Domburg (jeroen AT spritesmods.com) + * (C) 2014 Daniel Willmann <daniel@totalueberwachung.de> * 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 @@ -33,63 +32,55 @@ #include <zmq.h> -struct pixel { - uint16_t x, y; - uint8_t r, g, b; -} __attribute__((packed)); +#include "common.h" + +/* + * Layout: + * + * Connector on the Individual boards + * ______ + * | 1 2| + * |_3 4| + * |5 6| + * |~7 8| + * | 9 10| + * ~~~~~~ + * + * Pinout + * Display iMX233 Function + * + * 1: NC + * 2: SIN/OUT LCD0-4 Data in for the shift regs + * 3: SCK LCDCLK Clock (rising edge) + * 4: GND GND + * 5: A0 LCD13 Address for the line to drive (LSB) + * 6: A1 LCD14 Possible values: 0-6 for lines 1-7 + * 7: A2 LCD15 Address for line MSB + * 8: /G GND Global Display /Enable + * 9: VCC +5V + * 10: RCK EN Strobe to latch data into the output + * + * 1: Keep /G low + * 2: Write data via SIN und SCK into the shift regs + * 3: Select row through A0-A2 + * 4: Update LED outputs with RCK + * 5: Goto 2 + */ 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; + int i = 0; + struct pixel pix; 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); + pix.x = i / 7; + pix.y = i % 7; + pix.bright = 0; + + zmq_send(publisher, &pix, sizeof(pix), 0); + i = (i + 1) % (7*20); + pix.bright = 255; + zmq_send(publisher, &pix, sizeof(pix), 0); + printf("(%u, %u): bright=%02x\n", pix.x, pix.y, pix.bright); usleep(10000); } }