I'm looking for a device driver for vxworks on a PC 486 target. I like to
have a device driver for the UART 16550 to be able to use the 38400 bauds
rate and the fifo of the this chip.
Thanks for your help
Francois Pertin
The more recent releases of VxWorks should support FIFO capability of
16550. If not, the following code fragment may help.
David
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
/* This to be added to sysSerialHwInit() */
/* Enable FIFO. that FIFO control
register has the same address as interrupt ID register. */
{
sysOutByte(i8250Chan[i].iid, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14);
}
/* Replace ISR i8250Int() with this */
/*******************************************************************************
*
* ns16550Int - handle a receiver/transmitter interrupt
*
* This is a hack to take advantage of ns16550's 16 bytes FIFO. In the
* most part, ns16550 is similar to i8250. So we don't duplicate the
* data structure and other functions, but merely replace the interrupt
* service routine. This routine is adapted from i8250int and Linux
* kernel code (serial.c). See also ST16C554 data sheet.
*/
void ns16550Int
(
I8250_CHAN *pChan
)
{
char outChar;
char interruptID;
char lineStatus;
int ix = 0;
int xmitCount;
interruptID = (*pChan->inByte) ( pChan->iid );
do {
interruptID &= 0x06;
if (interruptID == 0x06)
lineStatus = (*pChan->inByte) (pChan->lst);
else if (interruptID == 0x04)
{
do {
if (pChan->putRcvChar != NULL)
(*pChan->putRcvChar)( pChan->putRcvArg,
(*pChan->inByte) (pChan->data) );
else
(*pChan->inByte) (pChan->data);
} while ( (*pChan->inByte) (pChan->lst) & 0x01 );
}
else if (interruptID == 0x02)
{
/* check transmitter holding buffer */
if ( (*pChan->inByte) (pChan->lst) & 0x20 )
{
/* start with fifo size */
xmitCount = 16;
do {
if ((pChan->getTxChar != NULL) &&
(*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK )
(*pChan->outByte) (pChan->data, outChar);
else
{
(*pChan->outByte) (pChan->ier, 0x01);
break;
}
} while (--xmitCount > 0);
}
}
interruptID = (*pChan->inByte) (pChan->iid);
} while (((interruptID & 0x01) == 0) && (ix++ < 8));
}
--
--------------------------------------------------------------
David Zhu
Jet Propulsion Laboratory e-mail: Davi...@jpl.nasa.gov
MS 198-235 phone: 818-354-9058
4800 Oak Grove Dr. fax: 818-393-5007
Pasadena, CA 91109
If you have access to the source for the VxWorks i8250 UART driver
(included in PC BSPs), this is not too difficult.
The spots to be modified are:
UART Initialization :
The FIFO control register (same address as the interrupt id register)
must be initialized. A value of 0x81 initializes the UART to cause an
interrupt after 8 received characters. If the two most significant bits
of the interrupt id register are set to 1 afterwards, the UART is a FIFO
type, not a FIFO-less 8250, 16450 etc.
Interrupt Service Routine :
Reading of the receiver data register must be continued, until the least
significant bit of the line status register is zero, to empty the whole
receiver-side FIFO.
Writing to the transmit data register can be repeated up to 16 times, if
the transmitbuffer of the driver contains enough data.
We use such a modified driver on a PC486 for sending and receiving at 115 kBaud
on 2 serial lines without noticeable data loss.
Hope, this helps
-----------------------------------------------------
Friedrich Ensslin
3SOFT GmbH
Wetterkreuz 19a , D-91058 Erlangen , Germany
phone: +49-9131-7701-113 , fax: +49-9131-7701-333
email: ens...@3SOFT.de