?? llserial.c
字號:
//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// llSerial.c
//
// Serial Port Driver
//
// Author: Michael A. Denio
// Copyright 2001, 2003 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "llserial.h"
//--------------------------------------------------------------------
// PUBLIC FUNCTIONS USED FOR INTIALIZATION AND EVENTS
//--------------------------------------------------------------------
#define MAX_INSTANCE 1
static uint SerDevCount = 0; // Number of Devices
static SDINFO sdi[MAX_INSTANCE]; // Private Info about devices
//--------------------------------------------------------------------
// PUBLIC FUNCTIONS USED BY NETCTRL
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// _llSerialInit()
//
// Opens the serial driver environment and enumerates devices
//--------------------------------------------------------------------
uint _llSerialInit(STKEVENT_Handle hEvent)
{
int i;
//
// Initialize the serial driver(s)
//
SerDevCount = HwSerInit();
if( SerDevCount > MAX_INSTANCE )
SerDevCount = MAX_INSTANCE;
//
// Initialize SDINFO for each driver instance
//
for(i=0; i<SerDevCount; i++)
{
mmZeroInit( &sdi[i], sizeof( SDINFO ) );
// Set physical index
sdi[i].PhysIdx = i;
// Set event object handle
sdi[i].hEvent = hEvent;
// Set a default operating mode
sdi[i].Baud = 9600;
sdi[i].Mode = HAL_SERIAL_MODE_8N1;
sdi[i].FlowCtrl = HAL_SERIAL_FLOWCTRL_NONE;
}
return( SerDevCount );
}
//--------------------------------------------------------------------
// _llSerialShutdown()
//
// Called to shutdown serial driver environment
//--------------------------------------------------------------------
void _llSerialShutdown()
{
uint dev;
llEnter();
// To be safe, close all open devices
for( dev=0; dev<SerDevCount; dev++ )
{
// Zap the HDLC handle
sdi[dev].hHDLC = 0;
// Zap callbacks
sdi[dev].cbRx = 0;
sdi[dev].cbTimer = 0;
sdi[dev].cbInput = 0;
// Close the driver if open
if( sdi[dev].Open )
HwSerClose( &sdi[dev] );
}
llExit();
SerDevCount = 0;
HwSerShutdown();
}
//--------------------------------------------------------------------
// _llSerialServiceCheck()
//
// Called to check for HDLC/Charmode activity and
// feed character mode data to application callback
//--------------------------------------------------------------------
void _llSerialServiceCheck( uint fTimerTick )
{
uint dev,mask;
SDINFO *psdi;
UINT8 c;
// Poll devices and callback for character mode
// receive. Then call the HDLC timer callback (if any)
for( dev=0; dev<SerDevCount; dev++ )
{
psdi = &sdi[dev];
// Allow low level driver to poll
_HwSerPoll( psdi, fTimerTick );
// If charmode data available, handle it
while( psdi->CharCount )
{
// Read char from buffer
mask = OEMSysCritOn();
c = psdi->CharBuf[psdi->CharReadIdx++];
if( psdi->CharReadIdx == CHAR_MAX )
psdi->CharReadIdx = 0;
psdi->CharCount--;
OEMSysCritOff(mask);
// Give char to application (if any)
if( psdi->cbRx )
(*psdi->cbRx)( (char) c );
}
// If open in HDLC mode and timer tick, then call the
// timer callback function on one second intervals
if( psdi->cbTimer && fTimerTick && (++psdi->Ticks >= 10) )
{
psdi->Ticks = 0;
llEnter();
(*psdi->cbTimer)( psdi->hHDLC );
llExit();
}
}
}
//--------------------------------------------------------------------
// _llSerialSend( uint dev, UINT8 *pBuf, uint len )
//
// Send a block of data in character mode
//
// Returns the number of characters queued onto the send buffer
//--------------------------------------------------------------------
uint _llSerialSend(uint dev, UINT8 *pBuf, uint len)
{
PBM_Handle hPkt;
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return(0);
// If open in HDLC mode, we can't send any character mode data
if( sdi[dev].hHDLC )
return(0);
// Create a packet for this data
hPkt = PBM_alloc( len );
if( !hPkt )
return(0);
// Copy the data to send
mmCopy( PBM_getDataBuffer(hPkt), pBuf, len );
// Set the length and offset
PBM_setValidLen( hPkt, len );
PBM_setDataOffset( hPkt, 0 );
llEnter();
llSerialSendPkt( dev+1, hPkt );
llExit();
return( len );
}
//--------------------------------------------------------------------
// PUBLIC FUNCTIONS USED BY THE STACK
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// llSerialOpen(uint dev, void (*cbInput)(char c))
//
// Opens the device for charater mode. The device can be
// be open for both character and HDLC mode simultaneously
//--------------------------------------------------------------------
uint llSerialOpen(uint dev, void (*cbInput)(char c))
{
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return(0);
// Init charmode callback
sdi[dev].cbRx = cbInput;
// If already open, just return
if( ++sdi[dev].Open > 1 )
return(1);
// Else call low-level open function if not already open
else
return( (sdi[dev].Open = HwSerOpen(&sdi[dev])) );
}
//--------------------------------------------------------------------
// llSerialClose( uint dev )
//
// Close the device
//--------------------------------------------------------------------
void llSerialClose( uint dev )
{
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return;
// Zap the charmode callback
sdi[dev].cbRx = 0;
// Close the driver
if( sdi[dev].Open && !--sdi[dev].Open )
HwSerClose( &sdi[dev] );
}
//--------------------------------------------------------------------
// llSerialOpenHDLC()
//
// Opens the device for HDLC mode. The device can be
// be open for both character and HDLC mode simultaneously
//--------------------------------------------------------------------
uint llSerialOpenHDLC( uint dev, HANDLE hHDLC,
void (*cbTimer)(HANDLE h),
void (*cbInput)(PBM_Handle hPkt) )
{
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return(0);
// Init Logical Device
sdi[dev].hHDLC = hHDLC;
// Init callbacks
sdi[dev].cbTimer = cbTimer;
sdi[dev].cbInput = cbInput;
// Set the peer map to a safe default
sdi[dev].PeerMap = 0xFFFFFFFF;
// If already open, just return
if( ++sdi[dev].Open > 1 )
return(1);
// Else call low-level open function if not already open
else
return( (sdi[dev].Open = HwSerOpen(&sdi[dev])) );
}
//--------------------------------------------------------------------
// llSerialCloseHDLC()
//
// Close the device for charater mode.
//--------------------------------------------------------------------
void llSerialCloseHDLC( uint dev )
{
PBM_Handle hPkt;
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return;
// Zap the HDLC handle
sdi[dev].hHDLC = 0;
// Zap callbacks
sdi[dev].cbTimer = 0;
sdi[dev].cbInput = 0;
// Flush the RX packet queue
while( (hPkt = PBMQ_deq(&(sdi[dev].PBMQ_rx))) )
PBM_free( hPkt );
// Close the driver
if( sdi[dev].Open && !--sdi[dev].Open )
HwSerClose( &sdi[dev] );
}
//--------------------------------------------------------------------
// llSerialSendPkt()
//
// Called to send data in packet form.
//--------------------------------------------------------------------
void llSerialSendPkt( uint dev, PBM_Handle hPkt )
{
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return;
if( hPkt )
{
PBMQ_enq( &(sdi[dev].PBMQ_tx), hPkt );
if( sdi[dev].TxFree )
HwSerTxNext( &(sdi[dev]) );
}
else
PBM_free( hPkt );
}
//--------------------------------------------------------------------
// llSerialHDLCPeerMap( uint dev, UINT32 peerMap )
//
// Called to update the sending peer map.
//--------------------------------------------------------------------
void llSerialHDLCPeerMap( uint dev, UINT32 peerMap )
{
// Our device index is "1" based to the upper layers
dev--;
if( dev < SerDevCount )
sdi[dev].PeerMap = peerMap;
}
//--------------------------------------------------------------------
// void llSerialService()
//
// Called to pass up HDLC packets to their input callback functions.
//--------------------------------------------------------------------
void llSerialService()
{
uint dev;
PBM_Handle hPkt;
SDINFO *psdi;
// Service all the drivers
for( dev=0; dev<SerDevCount; dev++ )
{
psdi = &sdi[dev];
// Give all queued packets to the callback function
while( (hPkt = PBMQ_deq(&psdi->PBMQ_rx)) )
{
if( psdi->cbInput )
psdi->cbInput( hPkt );
else
PBM_free( hPkt );
}
}
}
//--------------------------------------------------------------------
// llSerialConfig()
//
// Called to configure the serial port baud rate and mode
//--------------------------------------------------------------------
void llSerialConfig( uint dev, uint baud, uint mode, uint flowctrl )
{
// Our device index is "1" based to the upper layers
dev--;
if( dev >= SerDevCount )
return;
// Set baud and mode
sdi[dev].Baud = baud;
sdi[dev].Mode = mode;
sdi[dev].FlowCtrl = flowctrl;
// If the driver is open, update the settings
if( sdi[dev].Open )
HwSerSetConfig( &sdi[dev] );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -