⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llserial.c

📁 dm642网络传输程序
💻 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    2

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 + -