Hi all,

Several years ago Rui Barreiros already posted a question on the subject
which at the time doesn't seem to have been resolved and I am running into
the same problem more or less:

The DMX packet is read but ends up shifted over different amounts of bit
every read.

I currently suspect that this is all dependent on when the OS issues the
ftdi_read_data() call, I suspect this because when I ran my test program
using gdb the shifts were a lot more extreme (almost 0.5 packet) then when
it was running directly.

The packet itself is basically:
1. BREAK (>= 88us of LOW)
2. MAB (>= 8us HIGH)
3. 25-513 data slots (1b start HIGH, 8b data, 2b STOP HIGH each)

So my question is: Is there any way to 'allign' the reads to the break+mab?

attached is my modified version of the serial_test.c example.

Side questions:
- Can someone on the list explain the different flow control options?
- What is the RTS?

Thanks,
Eliyahu - אליהו


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [email protected]   

/* serial_test.c

   Read/write data via serial I/O

   This program is distributed under the GPL, version 2
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <libftdi1/ftdi.h>


static int exitRequested = 0;
/*
 * sigintHandler --
 *
 *    SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
 */
static void
sigintHandler(int signum)
{
    exitRequested = 1;
}

void cleanExit(struct ftdi_context * ftdi) {
    ftdi_usb_close(ftdi);
    do_deinit:
    ftdi_free(ftdi);
}

int main(int argc, char **argv)
{
    struct ftdi_context *ftdi;
    unsigned char buf[513];
    memset(&buf, '\0', (sizeof(char) * 513));
    int f = 0, i;
    int vid = 0x403;
    int pid = 0x6011;
    int baudrate = 250000;
    int interface = INTERFACE_ANY;
    int do_write = 0;
    unsigned int pattern = 0xffff;
    int retval = EXIT_FAILURE;

    while ((i = getopt(argc, argv, "i:v:p:b:w::")) != -1)
    {
        switch (i)
        {
            case 'i': // 0=ANY, 1=A, 2=B, 3=C, 4=D
                interface = strtoul(optarg, NULL, 0);
                break;
            case 'v':
                vid = strtoul(optarg, NULL, 0);
                break;
            case 'p':
                pid = strtoul(optarg, NULL, 0);
                break;
            case 'b':
                baudrate = strtoul(optarg, NULL, 0);
                break;
            case 'w':
                do_write = 1;
                if (optarg)
                    pattern = strtoul(optarg, NULL, 0);
                if (pattern > 0xff)
                {
                    fprintf(stderr, "Please provide a 8 bit pattern\n");
                    exit(-1);
                }
                break;
            default:
                fprintf(stderr, "usage: %s [-i interface] [-v vid] [-p pid] [-b baudrate] [-w [pattern]]\n", *argv);
                exit(-1);
        }
    }

    // Init
    if ((ftdi = ftdi_new()) == 0)
    {
        fprintf(stderr, "ftdi_new failed\n");
        return EXIT_FAILURE;
    }

    // Select interface
    printf("Setting interface to: %d\n", interface);
    if(ftdi_set_interface(ftdi, interface) < 0) {
      fprintf(stderr, "unable to set interface: %d (%s)\n", f, ftdi_get_error_string(ftdi));
      cleanExit(ftdi);
      exit(-1);
    }
        
    // Open device
    printf("Opening Device\n");
    if(ftdi_usb_open(ftdi, vid, pid) < 0) {
      fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi));
      cleanExit(ftdi);
      exit(-1);
    }

    // Set baudrate
    printf("Setting baudrate to: %d\n", baudrate);
    if( ftdi_set_baudrate(ftdi, baudrate) < 0) {
        fprintf(stderr, "unable to set baudrate: %d (%s)\n", f, ftdi_get_error_string(ftdi));
	cleanExit(ftdi);
        exit(-1);
    }
    
    /* Set line parameters
     *
     * TODO: Make these parameters settable from the command line
     *
     * Parameters are choosen that sending a continous stream of 0x55 
     * should give a square wave
     *
     */
    printf("Reseting line \n");
    if(ftdi_usb_reset(ftdi) < 0) {
      fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi));
      cleanExit(ftdi);
      exit(-1);
    }
    printf("Setting line properties\n");
    if(ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_2, NONE, BREAK_OFF) < 0) {
        fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi));
	cleanExit(ftdi);
        exit(-1);
    }
    printf("Disabling flowcontrol\n");
    if(ftdi_setflowctrl(ftdi, SIO_DISABLE_FLOW_CTRL) < 0) {
      fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi));
      cleanExit(ftdi);
      exit(-1);
    }
    printf("Set RTS\n");
    if (ftdi_setrts(ftdi, 0) < 0) {
      fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 
      cleanExit(ftdi);
      exit(-1);
    }
    printf("Setting chunksize to 513\n");
    if(ftdi_read_data_set_chunksize(ftdi, sizeof(buf)) < 0) {
      fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 
      cleanExit(ftdi);
      exit(-1);
    }
    
    signal(SIGINT, sigintHandler);
    
    while (!exitRequested)
    {
      unsigned short status = 0;
      if(ftdi_poll_modem_status(ftdi, &status) < 0) {
	printf("Failed to poll modem status!\n");
      }
      if(status & 0x1000) {
        f = ftdi_read_data(ftdi, buf, sizeof(buf));
	if (f<0) {
	  fprintf(stderr, "Error reading: %d (%s)\n", f, ftdi_get_error_string(ftdi));
	  printf("sleeping\n");  
	  usleep(513  * 4);
        }
        else if(f == sizeof(buf) && !do_write)
        {
            fprintf(stderr, "read %d bytes\n", f);
	    printf("pattern read: \n");
	    int i;
	    for(i = 0; i < 513; i++) {
	      printf("%02X",buf[i]);
	      if(i % 51 == 0 && i != 0){
		printf("\n");
	      }
	    }
	    printf("\n");
            fflush(stderr);
            fflush(stdout);
        }
      }
    }
    signal(SIGINT, SIG_DFL);
    retval =  EXIT_SUCCESS;
    cleanExit(ftdi);
    return retval;
}

Reply via email to