Hi all,
I'm trying to send and receive data from a PCDJ DAC-2 controller. I found an excellent resource entitled "How to add support for undocumented third party hardware controllers" at
www.codeproject.com, and I thought i'd have a crack at getting it to work under Linux, since the author has fully reverse engineered the data flowing back and forth (saved me the job of finishing my own reverse engineering effort!). The author even provided a driver, but it's only for Windows.
The ftdi_sio module supports this device since 2.6.17 (I think), and udev creates a node at /dev/tts/USB0 when the controller is plugged in:
Code:
ls -l /dev/tts/USB0
crw-rw---- 1 root tty 188, 0 2007-09-09 03:23 /dev/tts/USB0
The output from setserial looks a bit strange though - shouldn't there be a UART listed?:
Code:
# setserial -av /dev/tts/USB0
/dev/tts/USB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 0
closing_wait: infinte
Flags: spd_normal low_latency
The code I have written to set the serial port up doesn't seem to do much - I pretty much followed the example given at
http://www.easysw.com/~mike/serial/ but still no dice. I want to set the port to B57600, 8N1, no flow control, then output the byte sequence 0xff 0x01 0x01 to initialise the controller. The code I put together to do this is:
Code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int openPort(const char *device)
{
int fd;
// O_NOCTTY: program is not the controlling terminal - set to
// prevent other inputs (keyboard etc) from affecting this process.
//
// O_NDELAY: we don't care what state the DTD signal line is in (i.e.
// if the target interface is up) - set this flag to prevent
// this process from blocking while waiting for the DCD line
// to be the space voltage.
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1)
{
perror("openPort(): could not open /dev/tts/USB0 - ");
}
else
{
fcntl(fd, F_SETFL, 0);
}
return fd;
}
int main(int argc, char **argv)
{
int i;
int bytesWritten = 0;
char initString[4] = {0xff, 0x01, 0x01, 0x00};
char recvBuffer; //[64];
struct termios options;
memset(&recvBuffer, 0x00, sizeof(recvBuffer));
int portFD = openPort("/dev/tts/USB0");
if(portFD != -1)
{
//Set input and output baud rate of port
tcgetattr(portFD, &options);
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
//Enable receiver and set local mode
options.c_cflag |= (CLOCAL | CREAD);
//8 data bits, no parity (8N1)
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE; //clear csize flag
options.c_cflag |= CS8;
//Disable hardware and software flow control
options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
//Set input mode = raw
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//Set output mode = raw
options.c_oflag &= ~OPOST;
options.c_cc[VMIN] = 0; //min number of chars to read
options.c_cc[VTIME] = 10; //time to wait for all chars to be read
//Now immediately set the options on the port
tcsetattr(portFD, TCSANOW, &options);
bytesWritten = write(portFD, initString, sizeof(initString));
if(bytesWritten < 0)
{
printf("write() of initString failed!\n");
}
//Do not block read() if no data waiting to be read
// fcntl(portFD, F_SETFL, FNDELAY);
// for(;;)
// {
read(portFD, &recvBuffer, sizeof(recvBuffer));
printf("received: %s\n", recvBuffer);
// }
close(portFD);
}
return 0;
}
Does anyone have any ideas on what else I can try to make this work? I think the controller would be a good match for some of the audio libraries that are floating around out there, it'd be a shame not to get this working.
Thanks in advance,
--Hexstatic
Edited to add: I'm running my serial program as root for now, so I don't think it's a problem with permissions.
Edited again: I've changed the udev rule to allow myself to access the port instead of needing to be root, and also added myself to the tty group, but still no joy.