audiodriverwriter, on Oct 9 2008, 08:51 AM, said:
Ok, good to hear it works. Now I only need to know how I send messages to the serial port from C/C++ (so, no script or whatever) and if I can do that within an interrupt.
Anyway, I now have verified that all the registers of the Envy24HT chip on the hackintosh machine are the same as on my other system, right before sending the signal to start playing, so there can't be anything wrongly set-up now. By having serial debug in the interrupt handler I could find out if it enters the handler at all.
Opening the Serial Port original link
OR u can search "serial port" at
apple developer
To open a serial port, the MyOpenSerialPort function, shown in Listing 1-7, calls the open function, passing the device file path, as well as the following constants:
*
O_RDWR: open for reading and writing
*
O_NOCTTY: don’t assign a controlling terminal
*
O_NONBLOCK: allow subsequent I/O on the device to be nonblocking
These constants and the open and fcntl functions are defined in fcntl.h.
If open returns a valid file descriptor, MyOpenSerialPort performs the following additional steps:
1.
It calls the ioctl function, passing TIOCEXCL, to prevent additional opens on the device, except from a root-owned process.
2.
It calls the fcntl function, passing the value F_SETFL to clear the O_NONBLOCK flag so subsequent I/O will block.
3.
It calls the tcgetattr function to save the current file settings in the global static structure gOriginalTTYAttrs, of type termios. These values will be restored later by the MyCLoseSerialPort function (Listing 1-10). The termios structure and the tcgetattr and tcsetattr functions are defined in the header termios.h.
4.
It sets some fields of options, a local termios structure, using values defined in the header termios.h. These options specify, among other things, raw input mode, a one second timeout value for blocking reads, and input and output baud rates. MyOpenSerialPort then passes the options structure to the tcsetattr function to set new values for the serial port (the changes won’t take effect until the call to tcsetattr). The constant TCSANOW is also defined in termios.h, and indicates that the change should be made immediately.
5.
Finally, it returns the file descriptor obtained from the call to open.
You can find the headers mentioned in this section in header files in Kernel.framework, System.framework, or the directory /usr/include.
Listing 1-7 Opening the serial port specified by the passed device file
static int MyOpenSerialPort(const char *deviceFilePath)
{
int fileDescriptor = -1;
int handshake;
struct termios options;
// Open the serial port read/write, with no controlling terminal,
// and don't wait for a connection.
// The O_NONBLOCK flag also causes subsequent I/O on the device to
// be non-blocking.
// See open(2) ("man 2 open") for details.
fileDescriptor = open(deviceFilePath, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fileDescriptor == -1)
{
printf("Error opening serial port %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
goto error;
}
// Note that open() follows POSIX semantics: multiple open() calls to
// the same file will succeed unless the TIOCEXCL ioctl is issued.
// This will prevent additional opens except by root-owned processes.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if (ioctl(fileDescriptor, TIOCEXCL) == kMyErrReturn)
{
printf("Error setting TIOCEXCL on %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
goto error;
}
// Now that the device is open, clear the O_NONBLOCK flag so
// subsequent I/O will block.
// See fcntl(2) ("man 2 fcntl") for details.
if (fcntl(fileDescriptor, F_SETFL, 0) == kMyErrReturn)
{
printf("Error clearing O_NONBLOCK %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
goto error;
}
// Get the current options and save them so we can restore the
// default settings later.
if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == kMyErrReturn)
{
printf("Error getting tty attributes %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
goto error;
}
// The serial port attributes such as timeouts and baud rate are set by
// modifying the termios structure and then calling tcsetattr to
// cause the changes to take effect. Note that the
// changes will not take effect without the tcsetattr() call.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
options = gOriginalTTYAttrs;
// Print the current input and output baud rates.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
printf("Current input baud rate is %d\n", (int) cfgetispeed(&options));
printf("Current output baud rate is %d\n", (int) cfgetospeed(&options));
// Set raw input (non-canonical) mode, with reads blocking until either
// a single character has been received or a one second timeout expires.
// See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios")
// for details.
cfmakeraw(&options);
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 10;
// The baud rate, word length, and handshake options can be set as follows:
cfsetspeed(&options, B19200); // Set 19200 baud
options.c_cflag |= (CS7 |// Use 7 bit words
PARENB | // Enable parity (even parity if PARODD
// not also set)
CCTS_OFLOW | // CTS flow control of output
CRTS_IFLOW); // RTS flow control of input
// Print the new input and output baud rates.
printf("Input baud rate changed to %d\n", (int) cfgetispeed(&options));
printf("Output baud rate changed to %d\n", (int) cfgetospeed(&options));
// Cause the new options to take effect immediately.
if (tcsetattr(fileDescriptor, TCSANOW, &options) == kMyErrReturn)
{
printf("Error setting tty attributes %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
goto error;
}
// To set the modem handshake lines, use the following ioctls.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if (ioctl(fileDescriptor, TIOCSDTR) == kMyErrReturn)
// Assert Data Terminal Ready (DTR)
{
printf("Error asserting DTR %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
}
if (ioctl(fileDescriptor, TIOCCDTR) == kMyErrReturn)
// Clear Data Terminal Ready (DTR)
{
printf("Error clearing DTR %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
}
handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
// Set the modem lines depending on the bits set in handshake.
if (ioctl(fileDescriptor, TIOCMSET, &handshake) == kMyErrReturn)
{
printf("Error setting handshake lines %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
}
// To read the state of the modem lines, use the following ioctl.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if (ioctl(fileDescriptor, TIOCMGET, &handshake) == kMyErrReturn)
// Store the state of the modem lines in handshake.
{
printf("Error getting handshake lines %s - %s(%d).\n",
deviceFilePath, strerror(errno), errno);
}
printf("Handshake lines currently set to %d\n", handshake);
// Success:
return fileDescriptor;
// Failure:
error:
if (fileDescriptor != kMyErrReturn)
{
close(fileDescriptor);
}
return -1;
}