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

📄 serialapi.c

📁 完整的RTX串口驱动程序 供大家分享 谢谢
💻 C
📖 第 1 页 / 共 2 页
字号:
   }
   
   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 + -