-   Programming (
-   -   USB Serial Port Programming for PCDJ DAC-2 Controller (

Hexstatic 09-08-2007 10:00 PM

USB Serial Port Programming for PCDJ DAC-2 Controller
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, 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:


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?:


# 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 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:


#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 - ");
                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);                       
                //        }

                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,


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.

waftycrank 09-10-2007 05:31 PM

Hi ,
I read somewhere that setserial is obsolete, it certainly can't talk to my Prolific USB-to-Serial. Try using stty to interrogate your serial port.


All times are GMT -5. The time now is 02:54 PM.