Hugh
Hugh

Reputation: 8932

Specifying non-standard baud rate for FTDI virtual serial port under Linux

I have a USB device I'm trying to communicate with over a virtual serial port provided by the ftdi_sio kernel module. However, I'm having some trouble setting the baud rate of the port to 14400:

Does anyone have any ideas about this? It'd be pretty easy to fix this by hacking up the kernel module, but I'm really looking for a solution that doesn't require kernel changes.

Upvotes: 3

Views: 13698

Answers (2)

Tim H
Tim H

Reputation: 31

Shodanex's solution works with an NDI Polaris Spectra (baud 1.2mbps) under Linux. As specified, open the serial device (/dev/ttyUSB0) with B38400,

int port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
tcgetattr(port,&g_initialAtt);// save this to restore later
newAtt=g_initialAtt;
newAtt.c_cflag = B38400 | CS8 | CLOCAL | CREAD; 
cfmakeraw(&newAtt);
tcsetattr(port,TCSANOW,&newAtt);

then execute:

if(ioctl(port, TIOCGSERIAL, &sstruct) < 0){
    printf("Error: could not get comm ioctl\n"); 
    exit(0); 
}
sstruct.custom_divisor = custDiv;
//sstruct.flags &= 0xffff ^ ASYNC_SPD_MASK; NO! makes read fail.
sstruct.flags |= ASYNC_SPD_CUST; 
if(ioctl(port, TIOCSSERIAL, &sstruct) < 0){
    printf("Error: could not set custom comm baud divisor\n"); 
    exit(0); 
}

Upvotes: 3

shodanex
shodanex

Reputation: 15406

You can't change baud base, I suppose it is hardware related. So messing with the module won't do you any good. In your third point you only talk about the first method proposed for setting a custom baudrate, where you need to access the tty->alt_speed. It seems there is no interface to directly set tty struct from userspace, at least not with the ftdi_sio driver.
However, there is another method explained in the comments :

     * 3. You can also set baud rate by setting custom divisor as follows
     *    - set tty->termios->c_cflag speed to B38400
     *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as
     *      follows:
     *      o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
     *      o custom_divisor set to baud_base / your_new_baudrate

Did you try it ?

Upvotes: 4

Related Questions