Added doxygen style comments. Fixed a bug in open() return value. The class still doesn't work as it should.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2003-01-21 19:34:45 +00:00
parent f5b024fb5d
commit d376996084
+197 -91
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002, Jack Burton.
* Copyright 2002, Stefano Ceccherini.
* Copyright 2002, Marcus Overhagen.
* All rights reserved.
* Distributed under the terms of the MIT License.
@@ -21,20 +21,19 @@
/* The directory where the serial driver publishes its devices */
#define SERIAL_DIR "/dev/ports"
/*! \brief Creates and initializes a BSerialPort object.
/* Creates and initializes a BSerialPort object, */
/* query the driver, and builds a list of available */
/* serial ports. */
/* The BSerialPort object is initialized to these */
/* values: */
/* 19200 BPS, */
/* 8 Data Bits, */
/* 1 Stop Bit, */
/* No Parity, */
/* Hardware Flow Control, */
/* Infinite Timeout */
/* and Blocking mode. */
Query the driver, and builds a list of the available
serial ports.
The BSerialPort object is initialized to these values:
- \c B_19200_BPS
- \c B_DATA_BITS_8
- \c B_STOP_BIT_1
- \c B_NO_PARITY
- \c B_HARDWARE_CONTROL
- \c B_INFINITE_TIMEOUT
- Blocking mode
*/
BSerialPort::BSerialPort()
: ffd(-1),
fBaudRate(B_19200_BPS),
@@ -50,7 +49,9 @@ BSerialPort::BSerialPort()
}
/* Closes the port, if it's open, and deletes the devices list */
/*! \brief Frees the resources associated with the object.
Closes the port, if it's open, and deletes the devices list.
*/
BSerialPort::~BSerialPort()
{
if (ffd > 0)
@@ -63,28 +64,42 @@ BSerialPort::~BSerialPort()
}
/* Opens a serial port. @param a valid port name */
/*! \brief Opens a serial port.
\param portName A valid port name
(i.e."/dev/ports/serial2", "serial2", ...)
\return
- A positive number if the serialport has been succesfully opened.
- An errorcode (negative integer) if not.
*/
status_t
BSerialPort::Open(const char *portName)
{
char buf[64];
//TODO: Check if portName is a valid name
sprintf(buf, SERIAL_DIR"/%s", portName);
if (portName == NULL)
return B_BAD_VALUE; // Heheee, we won't crash
if (portName[0] != '/')
sprintf(buf, SERIAL_DIR"/%s", portName);
else
// A name like "/dev/ports/serial2" was passed
sprintf(buf, "%s", portName);
if (ffd > 0) //If this port is already open, close it
close(ffd);
ffd = open(buf, O_RDWR|O_NONBLOCK); //R5 seem to use this mask
// We want "open()" to return immediately
ffd = open(buf, O_RDWR|O_NONBLOCK);
if (ffd > 0)
DriverControl(); //Setup the port
return (ffd < 0) ? ffd : B_OK;
return (ffd > 0) ? ffd : errno;
}
/* Closes the port */
/*! \brief Closes the port.
*/
void
BSerialPort::Close(void)
{
@@ -94,33 +109,36 @@ BSerialPort::Close(void)
}
/* Read some data from the serial port. */
/* @param the buffer where to transfer the data */
/* @param how many bytes to read */
/*! \brief Reads some bytes from the serial port.
\param buf The buffer where to copy the data.
\param count The maximum amount of bytes to read.
\return The amount of data read.
*/
ssize_t
BSerialPort::Read(void *buf, size_t count)
{
if (ffd < 0) // We have no open port
return B_FILE_ERROR;
ssize_t err = read(ffd, buf, count);
return read(ffd, buf, count);
return (err >= 0) ? err : errno;
}
/* Write some data to the serial port. */
/* @param the buffer from which transfer the data */
/* @param how many bytes to write */
/*! \brief Writes some bytes to the serial port.
\param buf The buffer which copy the data from.
\param count The amount of bytes to write.
*/
ssize_t
BSerialPort::Write(const void *buf, size_t count)
{
if (ffd < 0) // We have no open port
return B_FILE_ERROR;
ssize_t err = write(ffd, buf, count);
return write(ffd, buf, count);
return (err >= 0) ? err : errno;
}
/* Set blocking mode */
/*! \brief Set blocking mode
\param Blocking If true, enables the blocking mode. If false, disables it.
*/
void
BSerialPort::SetBlocking(bool Blocking)
{
@@ -129,8 +147,13 @@ BSerialPort::SetBlocking(bool Blocking)
}
/* Set the timeout for the port */
/* Valid values: B_INFINITE_TIMEOUT or any value between 0 and 25000000 */
/*! \brief Set the timeout for the port.
\param microSeconds The timeout for the port.
Valid values are:
- \c B_INFINITE_TIMEOUT
- Any value between 0 and 25,000,000, but remember that the granularity
of the serial driver is 100,000 microseconds.
*/
status_t
BSerialPort::SetTimeout(bigtime_t microSeconds)
{
@@ -146,7 +169,33 @@ BSerialPort::SetTimeout(bigtime_t microSeconds)
}
/* Set the data rate (Baud rate) for the port */
/*! \brief Set the Baud rate for the port.
\param bitsPerSeconds The baud rate.
Valid values:
- \c B_0_BPS
- \c B_50_BPS
- \c B_75_BPS
- \c B_110_BPS
- \c B_134_BPS
- \c B_150_BPS
- \c B_200_BPS
- \c B_300_BPS
- \c B_600_BPS
- \c B_1200_BPS
- \c B_1800_BPS
- \c B_2400_BPS
- \c B_4800_BPS
- \c B_9600_BPS
- \c B_19200_BPS
- \c B_38400_BPS
- \c B_57600_BPS
- \c B_115200_BPS
- \c B_230400_BPS
- \c B_31250_BPS
\return
- \c B_OK if all goes fine,
- an error code if something goes wrong.
*/
status_t
BSerialPort::SetDataRate(data_rate bitsPerSecond)
{
@@ -156,7 +205,10 @@ BSerialPort::SetDataRate(data_rate bitsPerSecond)
}
/* Get the data rate (Baud Rate) */
/*! \brief Get the current Baud Rate.
\return The current Baud Rate.
*/
data_rate
BSerialPort::DataRate(void)
{
@@ -173,7 +225,9 @@ BSerialPort::SetDataBits(data_bits numBits)
}
/* Get the data bits */
/*! \brief Get the current data bits.
\return The current data bits.
*/
data_bits
BSerialPort::DataBits(void)
{
@@ -181,7 +235,12 @@ BSerialPort::DataBits(void)
}
/* Set the stop bits (1 or 2) */
/*! \brief Set the stop bits.
\param numBits The number of stop bits
Valid values:
- \c B_STOP_BITS_1 (or \c B_STOP_BIT_1)
- \c B_STOP_BITS_2
*/
void
BSerialPort::SetStopBits(stop_bits numBits)
{
@@ -190,7 +249,9 @@ BSerialPort::SetStopBits(stop_bits numBits)
}
/* Get the stop bits */
/*! \brief Get the current stop bits.
\return The current stop bits.
*/
stop_bits
BSerialPort::StopBits(void)
{
@@ -198,7 +259,13 @@ BSerialPort::StopBits(void)
}
/* Set the parity mode (ODD, PAIR, or NONE) */
/*! \brief Set the parity mode.
\param which The parity mode to set.
Valid values:
- \c B_ODD_PARITY
- \c B_EVEN_PARITY
- \c B_NO_PARITY
*/
void
BSerialPort::SetParityMode(parity_mode which)
{
@@ -207,7 +274,9 @@ BSerialPort::SetParityMode(parity_mode which)
}
/* Get the parity mode */
/*! \brief Get the parity mode.
\return The current parity mode.
*/
parity_mode
BSerialPort::ParityMode(void)
{
@@ -215,7 +284,8 @@ BSerialPort::ParityMode(void)
}
/* Clear the input buffer */
/*! \brief Clear the input buffer.
*/
void
BSerialPort::ClearInput(void)
{
@@ -223,7 +293,8 @@ BSerialPort::ClearInput(void)
}
/* Clear the output buffer */
/*! \brief Clear the output buffer.
*/
void
BSerialPort::ClearOutput(void)
{
@@ -231,7 +302,13 @@ BSerialPort::ClearOutput(void)
}
/* Set the flow control (HARDWARE, SOFTWARE, or NONE) */
/*! \brief Set the flow control
\param method The type of flow control.
Valid values:
- \c B_HARDWARE_CONTROL
- \c B_SOFTWARE_CONTROL
- \c B_NOFLOW_CONTROL
*/
void
BSerialPort::SetFlowControl(uint32 method)
{
@@ -240,7 +317,9 @@ BSerialPort::SetFlowControl(uint32 method)
}
/* Get the flow control */
/*! \brief Returns the selected flow control.
\return The flow control for the current open port.
*/
uint32
BSerialPort::FlowControl(void)
{
@@ -268,8 +347,11 @@ BSerialPort::SetRTS(bool asserted)
}
/* See how many chars are queued on the serial port, */
/* waiting to be read */
/*! \brief See how many chars are queued on the serial port.
\param wait_until_this_many A pointer to an int32 where you want
that value stored.
\return ?
*/
status_t
BSerialPort::NumCharsAvailable(int32 *wait_until_this_many)
{
@@ -282,7 +364,9 @@ BSerialPort::NumCharsAvailable(int32 *wait_until_this_many)
}
/* See if CTS is set */
/*! \brief See if the Clear to Send pin is asserted.
\return true if CTS is asserted, false if not.
*/
bool
BSerialPort::IsCTS(void)
{
@@ -295,7 +379,9 @@ BSerialPort::IsCTS(void)
}
/* See if DSR is set */
/*! \brief See if the Data Set Ready pin is asserted.
\return true if DSR is asserted, false if not.
*/
bool
BSerialPort::IsDSR(void)
{
@@ -308,7 +394,9 @@ BSerialPort::IsDSR(void)
}
/* See if RI is set */
/*! \brief See if the Ring Indicator pin is asserted.
\return true if RI is asserted, false if not.
*/
bool
BSerialPort::IsRI(void)
{
@@ -321,7 +409,9 @@ BSerialPort::IsRI(void)
}
/* See if DCD is set */
/*! \brief See if the Data Carrier Detect pin is asserted.
\return true if DCD is asserted, false if not.
*/
bool
BSerialPort::IsDCD(void)
{
@@ -334,10 +424,12 @@ BSerialPort::IsDCD(void)
}
/* Wait until there's something to read from the serial port. */
/* If no data is ready, it will always block, ignoring the */
/* value of SetBlocking(); however, it respects the timeout */
/* set by SetTimeout(). */
/*! \brief Wait until there's something to read from the serial port.
If no data is ready, it will always block, ignoring the
value of SetBlocking(); however, it respects the timeout
set by SetTimeout().
\return The number of bytes available to be read.
*/
ssize_t
BSerialPort::WaitForInput(void)
{
@@ -348,7 +440,10 @@ BSerialPort::WaitForInput(void)
}
/* Returns the number of available Serial Ports. */
/*! \brief Count the number of available Serial Ports.
\return An integer which represents the number of available
serial ports.
*/
int32
BSerialPort::CountDevices()
{
@@ -361,11 +456,14 @@ BSerialPort::CountDevices()
}
/* Get the device name for the given device.*/
/* The first parameter is the number of the device */
/* you want to know the name, the second is the buffer */
/* where you want to store the name, and the third is */
/* the length of that buffer. */
/*! \brief Get the device name for the given device.
\param n Number of the device you want to know the name of.
\param name The buffer where you want to store the name.
\param bufSize The size of the buffer.
\return
- \c B_ERROR if something goes wrong
- \c B_OK if all goes fine.
*/
status_t
BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
{
@@ -375,7 +473,8 @@ BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
if (_fDevices != NULL)
dev = static_cast<char*>(_fDevices->ItemAt(n));
if (dev != NULL && name != NULL) {
if (dev != NULL && name != NULL)
{
strncpy(name, dev, bufSize);
result = B_OK;
}
@@ -385,8 +484,10 @@ BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
/* Private or Reserved */
/* Query the serial driver about the available devices, */
/* and build a list of them. */
/*! \brief Build a list of available serial ports.
Query the serial driver about the available devices,
and build a list of them.
*/
void
BSerialPort::ScanDevices()
{
@@ -407,75 +508,80 @@ BSerialPort::ScanDevices()
}
/* Send the options to the serial driver. */
/* Returns B_OK if all goes fine, an error code */
/* if something goes wrong. */
/*! \brief Send the selected options to the serial driver.
\return
- \c B_OK if all goes fine,
- an error code if something goes wrong.
*/
int
BSerialPort::DriverControl()
{
struct termio termioControl;
struct termio options;
int err;
if (ffd < 0)
return B_NO_INIT;
//Load the current settings
err = ioctl(ffd, TCGETA, &termioControl);
err = tcgetattr(ffd, &options);
if (err < 0)
return errno;
// Reset all flags
termioControl.c_cflag &= ~(CRTSCTS | CSIZE | CBAUD | CSTOPB | PARODD | PARENB);
termioControl.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK);
termioControl.c_lflag &= ~(ECHO | ECHONL | ISIG | ICANON);
options.c_cflag &= ~(CRTSCTS | CSIZE | CBAUD | CSTOPB | PARODD | PARENB);
options.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK);
options.c_lflag &= ~(ECHO | ECHONL | ISIG | ICANON);
//Set the flags to the wanted values
if (fFlow & B_HARDWARE_CONTROL)
termioControl.c_cflag |= CRTSCTS;
options.c_cflag |= CRTSCTS;
if (fFlow & B_SOFTWARE_CONTROL)
termioControl.c_iflag |= (IXON | IXOFF);
options.c_iflag |= (IXON | IXOFF);
if (fStopBits & B_STOP_BITS_2)
termioControl.c_cflag |= CSTOPB; // We want 2 stop bits
options.c_cflag |= CSTOPB; // Set 2 stop bits
if (fDataBits == B_DATA_BITS_8)
termioControl.c_cflag |= CS8; // We want 8 data bits
if (fDataBits & B_DATA_BITS_8)
options.c_cflag |= CS8; // Set 8 data bits
//Ok, set the parity now
if (fParityMode != B_NO_PARITY)
{
termioControl.c_cflag |= PARENB; //Enable parity
options.c_cflag |= PARENB; //Enable parity
if (fParityMode == B_ODD_PARITY)
termioControl.c_cflag |= PARODD; //Select odd parity
options.c_cflag |= PARODD; //Select odd parity
}
//Set the baud rate
termioControl.c_cflag |= (fBaudRate & CBAUD);
cfsetispeed(&options, fBaudRate);
cfsetospeed(&options, fBaudRate);
//options.c_cflag |= (fBaudRate & CBAUD);
//Set the timeout
if (fBlocking)
{
if (fTimeout == B_INFINITE_TIMEOUT)
{
termioControl.c_cc[VTIME] = 0;
termioControl.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
}
else if (fTimeout == 0)
termioControl.c_cc[VMIN] = 0;
options.c_cc[VMIN] = 0;
else
{
int t = fTimeout / 100000;
termioControl.c_cc[VTIME] = (t == 0) ? 1 : t;
termioControl.c_cc[VMIN] = 1;
int timeout = fTimeout / 100000;
options.c_cc[VTIME] = (timeout == 0) ? 1 : timeout;
options.c_cc[VMIN] = 1;
}
} else
termioControl.c_cc[VMIN] = 0;
options.c_cc[VMIN] = 0;
//Ok, finished. Now tell the driver what we decided
err = ioctl(ffd, TCSETA, &termioControl);
err = tcsetattr(ffd, TCSANOW, &options);
return err > 0 ? err : errno;
return (err > 0) ? err : errno;
}