tcdrain

Below is a section of code that I am using to talk to the devc-ser8250. I am
using an xtreme pc-104, 4-port serial card and talking RS-485 on the serial
line. The serial card acts as a master, the devices we talk to are slave and
have no control of the RTS line. From the code below you can see that we
assert RTS, I previously ran this driver compiled with QNX Neutrino release
dated Dec 2000. Now using CodeWarrior IDE version 2.1 build 4.2.5.766, QNX
SDK Patch 1.1.0A (RTOS 6.1), the driver stopped working. I placed a scope on
the line to watch what was happening on the line and our 485 command was
going out on the line but RTS was remaining asserted for 20 - 30
milliseconds after the last character was sent and it would still have RTS
asserted when the reply was sent back, normally within 2-3 milliseconds of
the last character being written to the device (recall the slave IO device
has not sense of the state of RTS). I commented out the tcdrain call from
the code below and then RTS was de-asserted in time for us to see the
response from the slave device.

Any idea why tcdrain is now taking so long when in the previous version of
Neutrino it returned quickly?

============================================================================

// Enable RTS – taking control of the RS-485 line

i_Data = _CTL_RTS_CHG | _CTL_RTS;

if (devctl(m_iFileDes, DCMD_CHR_SERCTL, &i_Data, sizeof(i_Data), NULL))

{

CREATE_EXCEPTION(ce, CESerialUnknownError);

ce << “Can’t set RTS “” << sys_errlist[errno] << “””;

throw ce;

}

// Actually output the message

if (write (m_iFileDes, msg, usMsgLen) < usMsgLen)

{

CREATE_EXCEPTION(ce, CESerialUnknownError);

ce << “Can’t set write “” << sys_errlist[errno] << “””;

throw ce;

}

// Ensure all I/O is sent

if (tcdrain(m_iFileDes) != 0) //Sends all I/O data

{

int iSaveErr = errno;

TRACE(tr, TRIO, 3) << “ERROR: tcdrain returned “” << sys_errlist[errno] <<
“””;

tr.flush();

}

//Wait until transmitter empty register in UART is set

do

ucRegister = in8(m_port.uiBase + LSR); // Check line status register

while ((ucRegister & 0x40) != 0x40); // Check transmitter empty bit

i_Data = _CTL_RTS_CHG;

if (devctl (m_iFileDes, DCMD_CHR_SERCTL, &i_Data, sizeof(i_Data), NULL) !=
EOK)

{

CREATE_EXCEPTION(ce, CESerialUnknownError);

ce << “Can’t clear RTS “” << sys_errlist[errno] << “””;

throw ce;

}

}