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

📄 serialapi.c

📁 完整的RTX串口驱动程序 供大家分享 谢谢
💻 C
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------
// Module:        serialAPI
//
// Author:        D.P. De Simone
//
// Date:          December 1998
//
// Description:   This module contains the API interface to RTX
//                serial communications and the UART initialization
//                code.
//
// Change Log:
//    Date     Person     Code     Description
//    ----     -------    ----     -----------
//    4/1/99   R. Lee     rl001     Coded explicit return in gunction
//                                  RtConfigComPort 
//---------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <rtapi.h>

                                 
                                 
#include "..\inc\types.h"
#include "..\inc\serial.h"
#include "..\inc\serialAPI.h"

#include "data.h"          //initialized data


//------------------------------
// global data
//------------------------------

RINGBUFFER     receiveRingBuffer[COM_MAX_PORTS];      //allocate these statically
RINGBUFFER     transmitRingBuffer[COM_MAX_PORTS];     //allocate these statically

LARGE_INTEGER  timerPeroid;                           //alocate a time period
HANDLE         hTimer;                                //a timer handle

//------------------------
// prototypes
//------------------------                

extern void RTFCNDCL COM1Isr( void *junk);
extern void RTFCNDCL COM2Isr( void *junk);

extern   COMSTATS    csb[];
extern   UCB         ucbList[];

WORD		   InitializePort( UCB *ucb );
VOID		   SendNextFIFO ( UCB *ucb );
VOID        DumpUcb( char *s, UCB *ucb );
VOID        ReadPic( void );


WORD RtOpenComPort ( BYTE port, WORD baudRate, BYTE wordSize, 
                     BYTE stopBits, BYTE parity )
//-----------------------------------------------------------------------------
// function:      RtOpenComPort
//
// description:   RtOpenComPort intializes the com port by:
//                - validating the input parameters
//                - updating and initalizing the COM port UCB
//                - calling RTX to allow access to I/O data space
//                - initalizing the COM port
//                - initializing the COM port interrupt vector
//
// inputs:        port        -  Com port identifier { COM1 | COM2 }
//                baudeRate   -  baud rate, default 9600
//                wordSize    -  size of a transfer entity { 5 | 6 | 7 | 8 }
//                               bits. Default = 8
//                stopBits    -  default = 2
//                parity      -  { PARITY_NONE | PARITY_ODD | PARITY_EVEN |
//                                 PARITY_HIGH | PARITY_LOW }
//
//------------------------------------------------------------------------------
{
   UCB   *thisUcb;
   WORD  return_code;
   WORD  isrArg;
   
   
   if ( (port != COM1) && (port != COM2 ))
   {
      return ( COM_INVALID_DEVICE );
   }
   
   //----------------------------------------
   // its a valid port, now map the UCB and
   // transfer the parameters, using the UCB
   // defaults for null parameters
   //----------------------------------------
   
   thisUcb  =  (UCB *) &ucbList[port];
   //DumpUcb( "Driver:Open",thisUcb );
   
   if ( thisUcb->state )                  //is this port already active
   {
      return ( COM_DEVICE_OPEN );         //--yes, cannot open
   }
   
   if ( parity )
   {      
      thisUcb->parity = parity;           //tranfer the parity
   }
   
   if ( stopBits )
   {
      thisUcb->stopBits = stopBits;          //transfer number of stop bits    
   }

   if ( baudRate )
   {
      thisUcb->baudRate = (BYTE)baudRate;    //transfer baud rate
   }

   if ( wordSize )
   {
      thisUcb->wordSize = wordSize;          //transfer word size
   }

   //-------------------------------------------
   // now we start setting up the hardware. But
   // first we need access to the I/O space
   //-------------------------------------------
   
   if ( !RtEnablePortIo ( thisUcb->baseAddress, COM_IO_RANGE ) )
   {
      return ( COM_PORT_IO_FAILURE );
   }  
   
   //---------------------------------------------------------
   // the com port is configured, now initialize the hardware
   // setup the interrupt vector and the ring buffers
   // note: 
   //    for now we'll use statically alllocated ring buffers
   //----------------------------------------------------------
    
   thisUcb->inBuffer = (RINGBUFFER *)&receiveRingBuffer[port];  
   thisUcb->outBuffer = (RINGBUFFER *)&transmitRingBuffer[port];
  
  //----------------------------------------------------------
  // now setup the interrupt vector. later, we'll create
  // a table of ISRs, but for now,we'll do it the easy way.
  //----------------------------------------------------------
   if ( port == COM1 )
   { 
      thisUcb->isrHandle = RtAttachInterruptVector
                           (
                              NULL,0,COM1Isr,(void *)&isrArg,
                              RT_PRIORITY_MAX, Isa,0,
                              thisUcb->irq, thisUcb->irq
                           );
   }
   else
   {
      thisUcb->isrHandle = RtAttachInterruptVector
                           (
                              NULL,0,COM2Isr,(void *)&isrArg,
                              RT_PRIORITY_MAX, Isa,0,
                              thisUcb->irq, thisUcb->irq 
                           );
   }                           
   
   if ( !thisUcb->isrHandle )
   {
      printf("Connect to int failed. error =%d\n",GetLastError());

      return( COM_CONNECT_INTERRUPT_FAILED );
   }   
   
   if ( (return_code = InitializePort( thisUcb )) )
   {
      return ( return_code );
   }

   thisUcb->state = COM_STATE_OPEN;


   return( COM_NORMAL );
   
}   

WORD  RtReadComPort ( BYTE port, BYTE *buffer, WORD bytesToRead, WORD *bytesRead )
//-----------------------------------------------------------------------------------
// function:      RtReadComPort
//
// description:   Read bytes from COM port for a maximum of 'bytesToRead.' This 
//                function actually read all byted currently in the Ring Buffer, 
//                up to the maximum specified
//
// inputs:         
//                port        - the COM port to read from
//                Buffer      - buffer for read characters
//                bytesToRead - maximum number of bytes to read
//                
// outputs:
//                bytesRead   - actual number of bytes read
//                return code - COM_NORMAL or error code
//-------------------------------------------------------------------------------------
{
   register    idx;
   BYTE        *tBuff;
   UCB         *ucb;
   RINGBUFFER  *rb;
   WORD        count = 0;
      
   //-----------------------------------------
   // map the ucb and validate parameters
   //-----------------------------------------
   
   ucb = &ucbList[port];
   
   if ( !ucb->state )
   {
      return (COM_PORT_NOT_OPEN );
   }
  
   tBuff = buffer;
   *bytesRead = 0;
   rb = ucb->inBuffer;
   
   if (  !rb->count )                  //any characters??
   {
      return( COM_NORMAL );
   }

   if( ucb->statsActive )
   {
      csb[port].readRequests++;
   }
 
   //----------------------------------
   // the ring buffer is a critical 
   // section...block interrupts while
   // accessing it
   //-----------------------------------

   DISABLE_INTERRUPTS;
      for ( idx = 0; idx < bytesToRead; idx++ )
      {
         *tBuff++ = rb->buffer[rb->nextSlotOut++];
         count++;
         if ( rb->nextSlotOut == RING_BUFFER_SIZE )
         {
            rb->nextSlotOut = 0;
         }
         if ( !(--rb->count) )         //no more characters in buffer
         {
            break;
         }
      }
   
   ENABLE_INTERRUPTS;
   
  *bytesRead = count;
                  
   return( COM_NORMAL );
}

WORD  RtWriteComPort ( BYTE port, BYTE *buffer, WORD bytesToWrite, WORD *bytesWritten )
//-----------------------------------------------------------------------------------
// function:      RtReadComPort
//
// description:   Write bytes to COM port for a maximum of 'bytesToWrite.'
//
// inputs:         
//                port           - the COM port to write to
//                Buffer         - buffer of  characters to write
//                bytesToWrite   - count of bytes to write
//                
// outputs:
//                bytesWritten   - actual number of bytes written
//                return code    - COM_NORMAL or error code
//-------------------------------------------------------------------------------------
{
   register    idx;
   BYTE        *tBuff;
   UCB         *ucb;
   RINGBUFFER  *rb;
   WORD			count = 0;
   
   
   //-----------------------------------------
   // map the ucb and validate parameters
   //-----------------------------------------
   
   ucb = &ucbList[port];
   
   if ( !ucb->state )
   {
      return (COM_PORT_NOT_OPEN );
   }
  
   tBuff = buffer;
   *bytesWritten = 0;
   rb = ucb->outBuffer;
   
   if ( (RING_BUFFER_SIZE - rb->count) < bytesToWrite )
   {
      ucb->lastError = COM_TRANSMIT_BUFFER_OVERFLOW;
      ucb->errorCount++;
      return (  COM_TRANSMIT_BUFFER_OVERFLOW );
   }
   
   if( ucb->statsActive )
   {
      csb[port].writeRequests++;
   }
   
   //---------------------------------------------------
   // we have space in the ring buffer, lets pack it
   //---------------------------------------------------
   DISABLE_INTERRUPTS;
   
      for ( idx = 0; idx < bytesToWrite; idx++ )
      {
         rb->buffer[rb->nextSlotIn++] = *tBuff++;
         rb->count++;
         count++;
         if ( rb->nextSlotIn == RING_BUFFER_SIZE )
         {
            rb->nextSlotIn = 0;
         }
      }
   
   ENABLE_INTERRUPTS;
    
      //----------------------------------------------------
      // we've packed the ring buffer.
      // if the transmit side is idle, send the fisrt FIFO
      // and the ISR will send all subsequent FIFOs
      //-----------------------------------------------------

      if ( !ucb->transmitISRActive )
      {
#ifdef ORIGINAL_DENNIS
   		SendNextFIFO ( ucb );
#else
		//kick the TRH interrupt by disabling all, and re-enabling
		//see write.c in the NT driver
		RtWritePortUchar(ucb->baseAddress+UART_IER,0);
		RtWritePortUchar(ucb->baseAddress+UART_IER,IER_RECEIVE_DATA|IER_TRANSMIT_DATA);
#endif
      }
    
   *bytesWritten = count;

   return( COM_NORMAL );
}

WORD  RtGetComStatus ( BYTE port, CSB * csb )
//---------------------------------------------------------------------
// function:      RtGetComStatus
//
// description:   Returns a filled in  COM Status Block
//
//----------------------------------------------------------------------
{
   UCB   *ucb;
   
   ucb = &ucbList[port];
   
   if ( !ucb->state )
   {
      return (COM_PORT_NOT_OPEN );
   }
   csb->state = ucb->state;
   csb->lastError = ucb->lastError;
   csb->errorCount = ucb->errorCount;
   return (COM_NORMAL );
}

WORD  RtGetComBufferCount ( BYTE port )
//----------------------------------------------------------------------
// function:      RtGetCOMBufferCount
//
// description:   Returns the number of character in the imput buffer.
//
//-----------------------------------------------------------------------
{
   UCB         *ucb;
   RINGBUFFER  *rb;
   
   ucb = &ucbList[port];
   
   if ( !ucb->state )
   {
      return (COM_PORT_NOT_OPEN );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -