📄 serialapi.c
字号:
}
ucb = &ucbList[ port ];
rb = ucb->inBuffer;
return ( rb->count );
}
WORD RtCloseComPort( BYTE port )
//-------------------------------------------------------------------------
// function: RtCloseComPort
//
// description: Closes the COM port by performing the following:
//
// - maps the appropriate UCB
// - checks if COM port is open
// - releases resources
// - Initalize the UCB with the default parameter
// - reset the COM port and disable interrupts
//
//----------------------------------------------------------------------------
{
UCB *ucb;
RINGBUFFER *rb;
ucb = &ucbList[port];
if ( !ucb->state )
{
return (COM_PORT_NOT_OPEN );
}
RtWritePortUchar(ucb->baseAddress + UART_IER, 0 ); //diable port interrupts
ucb->state = COM_STATE_IDLE;
rb = ucb->inBuffer;
rb->count = 0;
rb->nextSlotIn = 0;
rb->nextSlotOut = 0;
rb = ucb->outBuffer;
rb->count = 0;
rb->nextSlotIn = 0;
rb->nextSlotOut = 0;
ucb->stopBits = DEFAULT_STOP_BITS;
ucb->parity = DEFAULT_PARITY;
ucb->baudRate = DEFAULT_BAUD_RATE;
ucb->wordSize = DEFAULT_WORDSIZE;
ucb->fifoSize = DEFAULT_FIFO_SIZE;
ucb->fifoMask = DEFAULT_FIFO_MASK;
ucb->receiveISRActive = 0;
ucb->transmitISRActive = 0;
ucb->statsActive = 0;
ucb->lastError = 0;
ucb->errorCount = 0;
//DumpUcb("Driver:Close", ucb );
RtReleaseInterruptVector ( ucb->isrHandle );
RtDisablePortIo ( ucb->baseAddress, COM_IO_RANGE );
ucb->isrHandle = 0;
return( COM_NORMAL );
}
WORD InitializePort( UCB *ucb )
//----------------------------------------------------------------------------
// function: InitializePort
//
// description: Initializes a COM port using the UART Control Block (UCB)
// as follows:
// - Disable all interrupts for the port
// - Set the baud rate
// - Set the Line Control Register (i.e. stop bits, parity & word size )
// - Set the Fifo Control Register
// - Set the Modem Control Register
// - Enable Interrupts
//
//-----------------------------------------------------------------------------
{
BYTE tempRegister;
RtWritePortUchar(ucb->baseAddress + UART_IER, 0 );
//-------------------------------------------------
// Set up the baud rate. First turn on DLAB.
//-------------------------------------------------
RtWritePortUchar(ucb->baseAddress + UART_LCR, LCR_DIVISOR_LATCH );
RtWritePortUchar( ucb->baseAddress + UART_DIV_LATCH_LOW,
baudRateTable[ucb->baudRate].DLLow );
RtWritePortUchar( ucb->baseAddress + UART_DIV_LATCH_HIGH,
baudRateTable[ucb->baudRate].DLHigh );
RtWritePortUchar(ucb->baseAddress + UART_LCR, 0 );
//----------------------------------------------------
// now set up the line control register
//----------------------------------------------------
tempRegister = ucb->stopBits | ucb->parity | ucb->wordSize;
RtWritePortUchar(ucb->baseAddress + UART_LCR, tempRegister );
//------------------------------------------------------
// set up the FIFO
//------------------------------------------------------
tempRegister = RtReadPortUchar( ucb->baseAddress + UART_FCR );
tempRegister |= ucb->fifoMask;
RtWritePortUchar(ucb->baseAddress + UART_FCR, tempRegister );
//-------------------------------------------------------
//complete by setting up the Modem Control Register and
//enabling interrupts
//--------------------------------------------------------
if ( ucb->flowControl )
{
RtWritePortUchar(ucb->baseAddress + UART_MCR, MCR_OUT2 | MCR_RTS | MCR_DTR );
}
else
{
RtWritePortUchar(ucb->baseAddress + UART_MCR, MCR_OUT2 );
}
RtWritePortUchar(ucb->baseAddress + UART_IER, IER_RECEIVE_DATA | IER_TRANSMIT_DATA );
//ReadPic(); //debug
return( COM_NORMAL );
}
WORD RtConfigComPort (BYTE port, COM_DCB * dcb )
//------------------------------------------------------------------------
// function: RtConfigComPort
//
// description: Configure a comport using the parameters contained
// in a dcb. We transfer non-zero parameters to the ucb
// and call the port initialize function.
//
//-------------------------------------------------------------------------
{
UCB *ucb;
ucb = &ucbList[port];
if ( !ucb->state )
{
return (COM_PORT_NOT_OPEN );
}
if( dcb->fifoSize > COM_FIFO_14 )
{
return ( COM_INVALID_PARAMETER );
}
else
{
ucb->fifoSize = fifoTable[dcb->fifoSize].size;
ucb->fifoMask = fifoTable[dcb->fifoSize].mask;
}
ucb->parity = dcb->parity;
ucb->stopBits = dcb->stopBits;
ucb->wordSize = dcb->wordSize;
ucb->baudRate = dcb->baudRate;
ucb->flowControl = dcb->flowControl;
return InitializePort ( ucb ); //**rl001
}
WORD RtComStats( BYTE port, BYTE command )
//-------------------------------------------------------------------
// function: RtComStats
//
// description: The ComStats command will start, stop. and print
// port statistics.
//
//--------------------------------------------------------------------
{
UCB *thisUcb;
COMSTATS *thisCsb;
RINGBUFFER *rb;
if ( (port != COM1) && (port != COM2 ))
{
return ( COM_INVALID_DEVICE );
}
//--------------------------------------
// map data structures for this device
//--------------------------------------
thisUcb = &ucbList[port];
thisCsb = &csb[port];
switch( command )
{
case COM_STATS_START:
memset( thisCsb,0, sizeof(COMSTATS) );
thisUcb->statsActive = TRUE;
break;
case COM_STATS_STOP:
memset( thisCsb,0, sizeof(COMSTATS) );
thisUcb->statsActive = FALSE;
break;
case COM_STATS_PRINT:
printf(" ***** Com Stats *****\n");
printf(" Bytes sent: %d\n",thisCsb->bytesWritten);
printf(" Bytes received %d\n",thisCsb->bytesRead);
printf(" Write requestes %d\n",thisCsb->writeRequests);
printf(" Read Requests: %d\n",thisCsb->readRequests);
printf(" Receive Ints: %d\n",thisCsb->rcvInts);
printf(" Transmit Ints: %d\n",thisCsb->xmtInts);
printf(" Secondary Ints: %d\n",thisCsb->secondaryInts);
//----------------------------------
// output the ringbuffer stats
//----------------------------------
rb = thisUcb->outBuffer;
printf("----output ring buffer----\n");
printf(" Buffer Count: %d\n",rb->count );
printf(" Next Output Slot: %d\n",rb->nextSlotOut);
printf(" Next Input Slot: %d\n",rb->nextSlotIn);
rb = thisUcb->inBuffer;
printf("----input ring buffer----\n");
printf(" Buffer Count: %d\n",rb->count );
printf(" Next Output Slot: %d\n",rb->nextSlotOut);
printf(" Next Input Slot: %d\n",rb->nextSlotIn);
ReadPic();
break;
default:
return( COM_INVALID_COMMAND );
break;
}
return ( COM_NORMAL );
}
#ifdef TIMER_CODE
WORD RtSetComTimer( BYTE port, DWORD quantum )
//------------------------------------------------------------------------
// function: RtSetComTimer
//
// description: Sets an interval timer for time delimited received
// packets. The timer works for two timer granularites,
// uSecond and mSecond. The uSecond times works for the
// following intervals: 100, 200, 500 and 1000 uSeconds.
// The mSecond timer work for any millesecond value.
//
// prototypye: RtSetComTimer( BYTE port, DWORD quantum )
//
// port = COM1 or COM2
// quantum = timer interval in microseconds
//
// Note: if the interval value is less than 1 millisecond,
// the following values must be used: 100, 200, 500, 1000.
//
//
//-------------------------------------------------------------------------
{
UCB *ucb;
DWORD temp;
WORD timerType;
ucb = &ucbList[port];
if ( !ucb->state )
{
return (COM_PORT_NOT_OPEN );
}
if( hTimer )
{
return( COM_TIMER_ACTIVE );
}
if( !hTimer )
{
return( COM_CANNOT_CREATE_TIMER );
}
//--------------------------------------
// the timer quantum should be in
// microsececonds. if its greater than
// 1000, its a millisecond timer. if its
// less, we need to validate a proper
// microsecond interval.
//-----------------------------------
if( quantum > 1000 )
{
timerType = CLOCK_1; //system clock
}
else
{
timerType = CLOCK_2; //HAL realtime clock
if((quantum != 100)||(quantum != 200)||(quantum != 500)||(quantum != 1000))
{
return( COM_INVALID_TIMER INTERVAL );
}
}
timerPeriod.QuadPart = quantum * 10; //in 100nS increments
hTimer = RtCreateTimer ( NULL,0,TimerHandler,NULL,RT_PRIORITY_MAX,timerType );
ucb->timeDelimitedRcv = TRUE;
return( COM_NORMAL );
}
WORD RtClearComTimer( BYTE port )
//---------------------------------------------------------------------
// function: RtClearComTimer
//
// description: clear the receive timer
//
//---------------------------------------------------------------------
{
UCB *ucb;
ucb = &ucbList[port];
if ( !ucb->state )
{
return (COM_PORT_NOT_OPEN );
}
if( !hTimer )
{
return( COM_TIMER_NOT_ACTIVE );
}
RtDeleteTime( hTimer );
hTime = NULL;
timerPeriod.QuadPart = 0;
ucb->timeDelimitedRcv = FALSE;
return( COM_NORMAL );
}
#endif
void DumpUcb(char *s, UCB *ucb )
//----------------------------------------------------
// a formatted dump of ucb for debugging
//----------------------------------------------------
{
printf("*** UCB Dump from %s ***\n\n",s );
printf (" port: %d\n", ucb->port );
printf (" baseAddress: %x\n", ucb->baseAddress );
printf (" isrHandle: %x\n", ucb->isrHandle );
printf (" fifoSize: %x\n", ucb->fifoSize );
printf (" parity: %d\n", ucb->parity );
printf (" stopBits: %d\n", ucb->stopBits );
printf (" wordSize: %d\n", ucb->wordSize );
printf (" baudRate: %d\n", ucb->baudRate );
printf (" state: %d\n", ucb->state );
}
VOID ReadPic( void )
//---------------------------------------------------------------
// debug function to read the Programmable Interrupt Controller
//---------------------------------------------------------------
{
BYTE pic;
BYTE irqMask;
RtEnablePortIo ( (PUCHAR)0x20, 2);
pic = RtReadPortUchar( (PUCHAR)0x20 );
irqMask = RtReadPortUchar( (PUCHAR)0x21 );
printf( " PIC = %x IRQMask = %x\n",pic, irqMask );
RtDisablePortIo ( (PUCHAR)0x20, 2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -