You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
2.6 KiB
140 lines
2.6 KiB
/* 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; |
|
|
|
int dmx_open(void) |
|
{ |
|
struct termios t; |
|
int flags; |
|
|
|
dmxfd = open(PORT, O_NONBLOCK | O_RDWR, 0); |
|
if (dmxfd == -1) { |
|
warn("failed to open DMX port"); |
|
return 0; |
|
} |
|
|
|
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); |
|
|
|
return 1; |
|
} |
|
|
|
|
|
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) |
|
{ |
|
int rv; |
|
|
|
rv = 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 rv; |
|
} |
|
|
|
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]); |
|
|
|
if (dmxfd == -1) |
|
return; |
|
|
|
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; |
|
} |
|
} |
|
|
|
|