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;
}