?? ti752.c
字號:
}
// Zap any queued transmits
while( PBMQ_count(&pi->PBMQ_tx) )
PBM_free( PBMQ_deq(&pi->PBMQ_tx) );
// Tx not free
pi->TxFree = 0;
}
//--------------------------------------------------------------------
// spWriteFifo()
//
// Writes out TX data to the TX FIFO. This function can be called
// in or out of the ISR.
//
// When the driver is open for HDLC operation, this code also frames,
// escapes, and validates the CRC for HDLC.
//
// Returns 1 if the system needs the TX FIFO Empty interrupt
//--------------------------------------------------------------------
static uint spWriteFifo( SDINFO *pi )
{
uint fifofree;
UINT8 c;
// We can write another FIFO set of bytes (less the ISR threshhold)
fifofree = ACE_FIFO-8;
while( fifofree )
{
// Start a new packet if we need to
if( !pi->hTxPend )
{
pi->hTxPend = PBMQ_deq(&pi->PBMQ_tx);
// If we don't have anything to send here, quit
if( !pi->hTxPend )
{
if( fifofree == ACE_FIFO-8 )
{
pi->TxFree = 1;
return(0);
}
return(1);
}
pi->pTxBuf = PBM_getDataBuffer(pi->hTxPend) +
PBM_getDataOffset(pi->hTxPend);
pi->TxCount = PBM_getValidLen(pi->hTxPend);
// If in HDLC mode, setup for HDLC
if( pi->hHDLC )
{
pi->TxCRC = PPPINITFCS16;
pi->TxFlag = 1;
pi->TxChar = HDLC_FLAGCHAR;
}
else
pi->TxFlag = 0;
}
//
// Continue with pending packet
//
// If inserting a character, do it now, else read from packet
if( pi->TxFlag )
{
c = pi->TxChar;
pi->TxFlag = 0;
}
else
{
c = *pi->pTxBuf++;
pi->TxCount--;
// If in HDLC mode, handle CRC and any "escape"
if( pi->hHDLC )
{
// If we get here, we have a HDLC charater track CRC
// We use 4 bit CRC to save table space
pi->TxCRC ^= c;
pi->TxCRC = (pi->TxCRC >> 4) ^ fcstab[0xF & pi->TxCRC];
pi->TxCRC = (pi->TxCRC >> 4) ^ fcstab[0xF & pi->TxCRC];
// See if we must "escape" this char
if( (c < HDLC_MINCHAR && (pi->PeerMap & (1<<c)))
|| c == HDLC_ESCCHAR || c == HDLC_FLAGCHAR )
{
pi->TxFlag = 1;
pi->TxChar = c ^ HDLC_XORCHAR;
c = HDLC_ESCCHAR;
}
// If count is 2, then we can insert the checksum into
// the packet
if( pi->TxCount == 2 )
{
pi->TxCRC = ~pi->TxCRC;
*pi->pTxBuf = (UINT8)(pi->TxCRC%256);
*(pi->pTxBuf+1) = (UINT8)(pi->TxCRC/256);
}
}
}
// Write the character
SREG(pi,UART_THR) = c;
fifofree--;
// See if we're done
if( !pi->TxFlag && !pi->TxCount )
{
// In HDLC mode we may need to add one more flag byte
if( pi->hHDLC && c != HDLC_FLAGCHAR )
{
pi->TxFlag = 1;
pi->TxChar = HDLC_FLAGCHAR;
}
else
{
// Here were done with the packet
PBM_free(pi->hTxPend);
pi->hTxPend = 0;
}
}
}
return(1);
}
//--------------------------------------------------------------------
// spIsr()
//
// General purpose ISR function. Here we will read data from
// the device, or send more data to it. We also will signal the
// scheduler if ANY charmode data is available, or if a full
// HDLC buffer is ready.
//--------------------------------------------------------------------
static void spIsr( SDINFO *pi )
{
uint itype;
uint fSignal = 0;
uint fEnableTxInt;
register UINT8 c;
// Get this interrupt type
itype = SREG(pi,UART_IIR) & 0xF;
// Disable serial interrupts (this allow edge triggering to
// detect a "stuck" interrupt.
SREG(pi,UART_IER) = 0;
// Check for receive data ready
if( itype == TL16C752_IIR_RDA ||
itype == TL16C752_IIR_TIMEOUT )
{
do
{
// Read the character
c = SREG(pi,UART_RBR);
// If in charmode, write this character to the charmode
// buffer. Otherwise, we write it to the HDLC buffer.
if( !pi->hHDLC )
{
if( pi->CharCount < CHAR_MAX )
{
pi->CharBuf[pi->CharWriteIdx++] = c;
if( pi->CharWriteIdx == CHAR_MAX )
pi->CharWriteIdx = 0;
pi->CharCount++;
fSignal = 1;
}
}
else
{
// If we don't have a packet ready, get one
if( !pi->hRxPend )
{
pi->hRxPend = PBM_alloc(RX_MAX+PKT_PREPAD);
// If we don't get a buffer, toss the character
if( !pi->hRxPend )
continue;
InitRxPacket:
PBM_setDataOffset(pi->hRxPend,PKT_PREPAD);
pi->pRxBuf = PBM_getDataBuffer(pi->hRxPend)+PKT_PREPAD;
pi->RxCount = 0;
pi->RxCRC = PPPINITFCS16;
pi->RxFlag = 0;
}
// If its a marker char, act on it
if( c == HDLC_FLAGCHAR )
{
// If we have some data in our HDLC packet, try and validate
// it. Otherwise, ignore this packet
if( !pi->RxCount )
continue;
// Verify the packet CRC
if( pi->RxCRC != PPPGOODFCS16 )
{
SerRxBadCRC++;
goto InitRxPacket;
}
else
{
// Correct the packet size and offset to give to PPP
SerRxGood++;
PBM_setValidLen(pi->hRxPend,pi->RxCount);
PBM_setIFRx(pi->hRxPend,pi->hHDLC);
PBMQ_enq( &pi->PBMQ_rx, pi->hRxPend );
pi->hRxPend = 0;
fSignal = 1;
}
continue;
}
// If this is an escape char, enter escape mode
if( c == HDLC_ESCCHAR )
{
pi->RxFlag = 1;
continue;
}
// Don't receive too much
if( pi->RxCount == RX_MAX )
continue;
// If we are in the middle of an "escape", then we convert
// this character
if( pi->RxFlag )
{
pi->RxFlag = 0;
c ^= HDLC_XORCHAR;
}
// Track the CRC so we can verify it later
pi->RxCRC ^= c;
pi->RxCRC = (pi->RxCRC >> 4) ^ fcstab[0xF & pi->RxCRC];
pi->RxCRC = (pi->RxCRC >> 4) ^ fcstab[0xF & pi->RxCRC];
*pi->pRxBuf++ = c;
pi->RxCount++;
}
} while( SREG(pi,UART_LSR) & TL16C752_LSR_DR );
}
// Check/Enable transmit FIFO empty int
if( pi->TxFree )
fEnableTxInt = 0;
else if( itype == TL16C752_IIR_THRE )
fEnableTxInt = spWriteFifo( pi );
else
fEnableTxInt = 1;
// Enable serial interrupts
if( fEnableTxInt )
SREG(pi,UART_IER) = TL16C752_IER_RX_AVAIL | TL16C752_IER_TX_READY;
else
SREG(pi,UART_IER) = TL16C752_IER_RX_AVAIL;
if( fSignal )
STKEVENT_signal( pi->hEvent, STKEVENT_SERIAL, 1 );
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -