C Linux
From Cricut Hacking Wiki
Code examples
Current alpha version of Linux sources on SourceForge at http://licut.sourceforge.net
This Linux-specific code snippet opens /dev/ttyUSB0 and sets the rate to 200kbps and returns a handle for use by read() and write():
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <linux/serial.h>
int open_port_200kbps()
{
int handle = open( "/dev/ttyUSB0", O_RDWR | O_NOCTTY );
if (handle <= 0)
{
printf( "Failed to open %s - %d (%s)\n", "/dev/ttyUSB0", errno, strerror(errno) );
return -1;
}
struct termios oldtio,newtio;
tcgetattr( handle, &oldtio ); /* save current port settings */
bzero( &newtio, sizeof(newtio) );
// Set custom rate to 200kbps 8N1 - we're actually sending 8N2 but get 8N1 back
newtio.c_cflag = B38400 | /*CRTSCTS |*/ CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
/* set input mode (non-canonical, no echo,...) */
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received */
tcflush( handle, TCIFLUSH );
tcsetattr( handle, TCSANOW, &newtio );
// Now use TIOCSSERIAL ioctl to set custom divisor
// FTDI uses base_baud 24000000 so in theory a divisor
// of 120 should give us 200000 baud...
struct serial_struct sio; // From /usr/include/linux/serial.h
int ioctl_res = ioctl( handle, TIOCGSERIAL, &sio );
if (ioctl_res < 0)
{
printf( "Failed TIOCGSERIAL ioctl: error %d (%s)\n", errno, strerror(errno) );
close( handle );
return -1;
}
sio.flags = ((sio.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST);
sio.custom_divisor = sio.baud_base / 200000;
ioctl_res = ioctl( handle, TIOCSSERIAL, &sio );
if (ioctl_res < 0)
{
printf( "Failed TIOCSSERIAL ioctl: error %d (%s)\n", errno, strerror(errno) );
close( handle );
return -1;
}
return handle;
}
lio.Send is a simple function that adds an intercharacter delay of 1ms (running on Ubuntu 9.04):
int LicutIO::Send( const unsigned char *bytes, int length )
{
int n;
int actual_sent = 0;
for (n = 0; n < length; n++)
{
int write_res = write( m_handle, &bytes[n], 1 );
if (write_res < 1)
{
printf( "%s(%p,%u) - write returned %d, errno=%d (%s)\n", __FUNCTION__, bytes, length, write_res, errno, strerror(errno) );
}
else
{
actual_sent++;
}
// Add intercharacter delay after each character, including the last
usleep( 1000 );
}
return actual_sent;
}
After reading the results of each status command, I'm forcing an additional 250ms timeout.

