|
|
|
/* dmx.c */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <err.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <strings.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include "dmx.h"
|
|
|
|
|
|
|
|
#define PORT "/dev/ttyU0"
|
|
|
|
#define DMX_PACKETSIZE (DMX_UNIVERSESIZE + 6)
|
|
|
|
|
|
|
|
int dmxfd;
|
|
|
|
|
|
|
|
char dmxpacket[DMX_UNIVERSESIZE + DMX_PACKETSIZE];
|
|
|
|
char *dmxuniverse;
|
|
|
|
|
|
|
|
void dmx_open(void)
|
|
|
|
{
|
|
|
|
struct termios t;
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
dmxfd = open(PORT, O_NONBLOCK | O_RDWR, 0);
|
|
|
|
if (dmxfd == -1) {
|
|
|
|
err(1, "failed to open DMX port");
|
|
|
|
}
|
|
|
|
|
|
|
|
flags = fcntl(dmxfd, F_GETFL);
|
|
|
|
fcntl(dmxfd, F_SETFL, flags & ~O_NONBLOCK);
|
|
|
|
|
|
|
|
tcgetattr(dmxfd, &t);
|
|
|
|
cfmakeraw(&t);
|
|
|
|
t.c_cflag = CLOCAL | CREAD | CS8;
|
|
|
|
tcsetattr(dmxfd, TCSANOW, &t);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dmx_close(void)
|
|
|
|
{
|
|
|
|
close(dmxfd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void dmx_dumpparams(void)
|
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
int more;
|
|
|
|
char *ptr;
|
|
|
|
int bytes;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
buf[0] = 0x7e;
|
|
|
|
buf[1] = 3;
|
|
|
|
buf[2] = 2;
|
|
|
|
buf[3] = 0;
|
|
|
|
buf[4] = 0;
|
|
|
|
buf[5] = 0;
|
|
|
|
buf[6] = 0xe7;
|
|
|
|
if (write(dmxfd, buf, 7) != 7)
|
|
|
|
printf("didn't write 7 bytes\n");
|
|
|
|
|
|
|
|
more = 1;
|
|
|
|
ptr = buf;
|
|
|
|
bytes = 0;
|
|
|
|
len = 0;
|
|
|
|
while (more) {
|
|
|
|
if (read(dmxfd, ptr, 1) != 1)
|
|
|
|
goto out;
|
|
|
|
bytes++;
|
|
|
|
ptr++;
|
|
|
|
if (buf[0] != 0x7e) {
|
|
|
|
printf("Invalid packet received\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (bytes == 4)
|
|
|
|
len = buf[2] | (buf[3] << 8);
|
|
|
|
if (bytes == len + 5) {
|
|
|
|
if (buf[bytes-1] != (char)0xe7) {
|
|
|
|
printf("Invalid packet end\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
more = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Received packet:\n");
|
|
|
|
printf("%x %x %x %x %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
|
|
|
|
|
|
|
out:
|
|
|
|
printf("buffer contents:\n");
|
|
|
|
printf("%x %x %x %x %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int dmx_init(void)
|
|
|
|
{
|
|
|
|
dmx_open();
|
|
|
|
dmxpacket[0] = 0x7e;
|
|
|
|
dmxpacket[1] = 6;
|
|
|
|
dmxpacket[2] = (DMX_UNIVERSESIZE+1) & 0xff;
|
|
|
|
dmxpacket[3] = ((DMX_UNIVERSESIZE+1) >> 8) & 0xff;
|
|
|
|
dmxpacket[4] = 0; /* start code */
|
|
|
|
bzero(dmxpacket+5, DMX_UNIVERSESIZE);
|
|
|
|
dmxpacket[DMX_UNIVERSESIZE+5] = 0xe7;
|
|
|
|
dmxuniverse = dmxpacket+5;
|
|
|
|
// dmx_dumpparams();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dmx_setchannel(int channel, int value)
|
|
|
|
{
|
|
|
|
assert(channel < DMX_UNIVERSESIZE);
|
|
|
|
dmxuniverse[channel] = (char)value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dmx_output(void)
|
|
|
|
{
|
|
|
|
int off = 0;
|
|
|
|
// char *buf = dmxpacket;
|
|
|
|
// printf("%x %x %x %x %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
|
|
|
while (off < DMX_PACKETSIZE) {
|
|
|
|
int r;
|
|
|
|
r = write(dmxfd, dmxpacket + off, DMX_PACKETSIZE - off);
|
|
|
|
// printf("write returned %d\n", r);
|
|
|
|
if (r == -1)
|
|
|
|
err(1, "error writing packet");
|
|
|
|
off += r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|