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

📄 profim.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// $Id: ProfiM.c,v 1.0.0                                            2004/01/13
//-----------------------------------------------------------------------------
//
//      ProfiM - PROFIBUS MASTER DRIVER FOR WINDOWS NT/2000
//
// Author:  
//      Pavel Trnka, CTU FEE
//      trnkap@seznam.cz
// With help and advices from:
//      Ing. Petr Smolik, CTU FEE
//      Ing. Pavel Pisa, CTU FEE
//      Ing. Pavel Burget, CTU FEE
//
//---------------------------------------------------------------------------
//
// Popis:
// ------
//   Nejnizsi vrstva ProfiMu. Zajistuje start ovladace (DriverEntry) a jeho
// rozhrani pro spolupraci se systemem. Pro vyssi vrstvy ProfiMu umoznuje vy-
// silani ramcu na sbernici a predevsim zajisteni rychleho casovani, ktere je
// nezbytne pro dodrzeni casovych intervalu specifikace Profibusu.
//   Nastavenim falesneho makra "PnP" v headru vardef.h je ovladac prelozen
// s podporou Plug and Play a muze tak byt pouzivan v systemu Windows 2000.
// Jinak je ovladac prelozen pro system Windows NT.
//
// Funkce volane z vnejsku:
// ------------------------
//
//   DriverEntry     - pozadavek systemu na spusteni ovladace
//   ProfiM_Isr      - obsluha preruseni
//   DispatchRoutine - komunikace s aplikacni vrstvou
//
//   ProfiM_SendOut  - pozadavek vyssi vrstvy na vysilani (casovacich,
//                     synchronizacnich nebo datovych znaku)

//   ProfiM_ClearTimingChars - zastavi odpocet time-outu 
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
//
// Include files 
//

#include "NTDDK.H"
#include "COM8250.H"
#include "Profibus.h"
#include "PROFIM.H"
#include "ProfiMIOC.H"

//---------------------------------------------------------------------------
//
// Define the driver names
// 
#define NT_DEVICE_NAME      L"\\Device\\ProfiM"
#define DOS_DEVICE_NAME     L"\\DosDevices\\ProfiM"



//-----------------------------------------------------------------------------
//
// Declare forward function references
//

NTSTATUS  DispatchRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );

VOID      UnloadDriver( IN PDRIVER_OBJECT DriverObject );

BOOLEAN   ReportUsage( IN PDRIVER_OBJECT DriverObject,
                       IN PDEVICE_OBJECT DeviceObject,
                       IN PHYSICAL_ADDRESS PortAddress,
                       IN BOOLEAN *ConflictDetected );

BOOLEAN   ProfiM_Isr( IN PKINTERRUPT Interrupt, IN OUT PVOID Context );

VOID ProfiM_CompleteDPC( IN PKDPC Dpc, IN PVOID DeferredContext,
                         IN PVOID SystemArgument1, IN PVOID SystemArgument2 );
                         
BOOLEAN ProfiM_CompleteDPC_Synch( IN PPROFIM_DEVICE_EXTENSION  DeviceExtension );


VOID      ProfiM_Dpc_Routine( IN PKDPC Dpc,
                              IN PDEVICE_OBJECT DeviceObject,
                              IN PIRP Irp,
                              IN PVOID Context );

NTSTATUS  GetConfiguration( IN PPROFIM_DEVICE_EXTENSION DeviceExtension,
                            IN PUNICODE_STRING RegistryPath );
                            
NTSTATUS  GetPnPConfiguration( IN PPROFIM_DEVICE_EXTENSION DeviceExtension);                            

NTSTATUS  Initialize_ProfiM( IN PPROFIM_DEVICE_EXTENSION DeviceExtension,
                             int chip_options );

/*NTSTATUS  ProfiM_Write( IN PPROFIM_DEVICE_EXTENSION  DeviceExtension,
                        IN PIRP Irp );*/
BOOLEAN   ProfiM_Write( IN PPROFIM_DEVICE_EXTENSION  DeviceExtension );                        

/*NTSTATUS  ProfiM_Read( IN PPROFIM_DEVICE_EXTENSION  deviceExtension,
                       IN PIRP Irp );*/
BOOLEAN   ProfiM_Read( IN PPROFIM_DEVICE_EXTENSION  DeviceExtension );                                               


void      FillTxBuffer( PPROFIM_DEVICE_EXTENSION  DeviceExtension );
void      Jam_First_Out( PPROFIM_DEVICE_EXTENSION  DeviceExtension );
BOOLEAN   AllSent( PPROFIM_DEVICE_EXTENSION  DeviceExtension );
BOOLEAN   LastOfSameType( PPROFIM_DEVICE_EXTENSION DeviceExtension );
BOOLEAN   LastToSend( PPROFIM_DEVICE_EXTENSION DeviceExtension );

void      ProfiM_IrpCancel( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );

BOOLEAN   ProfiM_WatchDog_Synch( IN PPROFIM_DEVICE_EXTENSION  DeviceExtension );

//---------------------------------------------------------------------------
//
//  Begin FUNCTIONS
//
//---------------------------------------------------------------------------


/////////////////////////////////////////////////////////////////////////////
//                            16950 SUPPORT
/////////////////////////////////////////////////////////////////////////////
#include "16950pci.c"
/////////////////////////////////////////////////////////////////////////////                                


// Pri prekladu pro Windows NT neobsahuje ovladac podporu PnP
#ifndef PnP
#include "DriverWinNT.c"
#endif


// Podpora PnP pri prekladu ovladace pro systemy Windows 2000 ev. Windows XP
#ifdef PnP
#include "DriverPnP.c"
#endif


//***************************************************************************
// ProfiM_Isr
//
// Description:
//  This is our 'C' Isr routine to handle transmit and recieve
//
// Arguments:
//      Interrupt   - Pointer to our interrupt object
//      Context     - Pointer to our device object
//
// Return Value:
//      TRUE        - If this was our ISR
//
//***************************************************************************
BOOLEAN ProfiM_Isr( IN PKINTERRUPT Interrupt, IN OUT PVOID Context )
{
  PDEVICE_OBJECT            DeviceObject;
  PPROFIM_DEVICE_EXTENSION  DeviceExtension;
  UCHAR                     ch;
  int                       cit;
  int                       pom;  /*DEBUG*/

    
  if ( !Context )
  {
    DbgPrint( "ProfiM: ISR Error - Context is NULL!" );
    return FALSE;
  }

  //
  // Get the Device Object and obtain our Extension
  //    
  DeviceObject = Context;
  DeviceExtension = DeviceObject->DeviceExtension;

  //
  // Check DeviceExtension
  //
  if ( !DeviceExtension )
  {
    DbgPrint( "ProfiM: ISR Error - DeviceExtension is NULL!" );
    return FALSE;
  }        

  if ( DeviceExtension->magic != PROFIM_MAGIC )
  {
    DbgPrint( "ProfiM: ISR Error - Device Extension MAGIC is invalid!" );
    return FALSE;
  }

  //
  // Bump the interrupt count
  //
  //DeviceExtension->InterruptCount++;
  
  //
  // Shozeni priznaku pro WatchDog
  //
  DeviceExtension->WatchDogTrigger = 0;

  
  //*******************************************************  
  //  ISR for 16PCI954
  //*******************************************************    
  if ( CHIP950 )
  {     
    
    ch = u950pci_inb( DeviceExtension->port, UART_IIR );
    
    
    //
    // Je preruseni pro nas?
    //
    if ( ch & UART_IIR_NO_INT )
      return FALSE;    
    
      
    if ( ! DeviceExtension->PB.AllInitialized )
      return TRUE;

                 
    //
    // Probiha-li ukladani dat do vystupniho Tx FIFO je preruseni ignorovano    
    //
    if (DeviceExtension->Buffering)
    {
      //DbgPrint(" ISR: Buffering !!!");    
      return TRUE;
    }
    
    
    /*DEBUG*/
    //u950pci_outb( DeviceExtension->port, UART_IER, 0 ); /* disable interrupts */      
    
    
    if (DeviceExtension->InterruptRunning) /*DEBUG*/
    {
      DeviceExtension->SecondInterrupt = TRUE;
      DbgPrint( "ProfiM: Dve preruseni najednou!!!" );
      /*
      DbgPrint( "ProfiM: Dve preruseni najednou (LastIIR=%d IIR=%d) !?!?!", DeviceExtension->LastIIR, ch);
      DbgPrint( "          LastMasterState = %d    MasterState = %d", DeviceExtension->PB.MasterState, DeviceExtension->PB.LastState );    
      DbgPrint( "          XmitFirst = %d    XmitLast = %d", DeviceExtension->XmitFirst, DeviceExtension->XmitLast );    
      pom=DeviceExtension->XmitFirst--;
      if ( pom<0 ) pom = DeviceExtension->BufferSize - 1;
      DbgPrint( "          Last Transmit Type = %x    Last Transmit Byte = %x", DeviceExtension->XmitTypeBuffer[pom], DeviceExtension->XmitBuffer[pom] );
      */
      return TRUE; //nebo radsi TRUE jako ze preruseni bylo nase???
    }
    DeviceExtension->InterruptRunning = TRUE;         
    DeviceExtension->LastIIR = ch;

    
    //DbgPrint ("ProfiM: ISR( IIR = %d ) !\n",ch);       

    while ( ! ( ch & UART_IIR_NO_INT ) )
    {
      switch ( ch & UART_IIR_ID )
      {
        
        //*********************************************************************                      
        // Receiver - line status interrupt - receive error
        //*********************************************************************                       
        case UART_IIR_RLSI: 
              DbgPrint( "ProfiM: Receiver ERROR !" );                         
          break;
          
        //*********************************************************************          
        // Receiver - data time-out    
        //*********************************************************************                  
        case UART_IIR_TIMEOUT:
        
          #ifdef USE_RX_FIFO 
              DbgPrint( "ProfiM: ISR TIME-OUT!" );                 
              while ( u950pci_RxDataReady( DeviceExtension ) )
              {
                ch = u950pci_inb( DeviceExtension->port, UART_RX );
                PB_RxByte( &( DeviceExtension->PB ), ch );                
              }                  
              DeviceExtension->ContinueFrame = FALSE;              
              #ifndef AUTOMATIC_RX
                u950pci_RxTreshold( DeviceExtension , 1 );
              #endif
          #endif
              
          break;
          
        //*********************************************************************                                      
        // Receiver - data interrupt  
        //*********************************************************************                                      
        case UART_IIR_RDI:  
                
          // automatic receive (direction switching) with full FIFO support
          #ifdef AUTOMATIC_RX       
            cit=300;
            //DbgPrint("ProfiM: Rx INT");
            while ( u950pci_RxDataReady( DeviceExtension ) && cit>0 )
            {
              cit--;
              ch = u950pci_inb( DeviceExtension->port, UART_RX );
              PB_RxByte( &( DeviceExtension->PB ), ch );                
            }           
            if (cit<=0) DbgPrint("ProfiM: RxData - deadlock avoided!!!");
            break;
          #endif
          

          #ifdef USE_RX_FIFO // *************************************
            
            if ( ! DeviceExtension->ContinueFrame )
            {
              switch ( DeviceExtension->RTL ) // Receiver Interrupt Trigger Level
              {
                case 1:
                  ch = u950pci_inb( DeviceExtension->port, UART_RX );
                  PB_RxByte( &( DeviceExtension->PB ), ch );
                  if ( IsStartDelimiterSDx( ch ) )
                  {
                    DeviceExtension->FrameHeader[0] = ch;
                    u950pci_RxTreshold( DeviceExtension, 2 );
                  }
                  return TRUE;
                  break;
                  
                case 3:
                  ch = u950pci_inb( DeviceExtension->port, UART_RX );
                  PB_RxByte( &( DeviceExtension->PB ), ch );
                  DeviceExtension->FrameHeader[0] = ch;                                  
                  if ( ch == DelimiterSC )
                  {
                    //
                    // DelimiterSC je jednoznakovy a tudiz preruseni
                    // nastava time-outem
                    //
                    return TRUE;
                  }
                  // zamerne zde chybi break              
                                  
                case 2:
                  ch = u950pci_inb( DeviceExtension->port, UART_RX );
                  PB_RxByte( &( DeviceExtension->PB ), ch );
                  DeviceExtension->FrameHeader[1] = ch;                
                  ch = u950pci_inb( DeviceExtension->port, UART_RX );
                  PB_RxByte( &( DeviceExtension->PB ), ch );
                  DeviceExtension->FrameHeader[2] = ch;      
                  break;                                                
              }
              
              switch ( DeviceExtension->FrameHeader[0] )
              {
                case DelimiterSD1:  // Frame of fixed Length with no Data Field
                  DeviceExtension->RTL = 3;
                  DeviceExtension->ContinueFrame = TRUE;
                  break;                  
                case DelimiterSD2: // Frame with variable Data Field Length
                  if ( DeviceExtension->FrameHeader[1] == 
                       DeviceExtension->FrameHeader[2] )
                  {
                    DeviceExtension->RTL = DeviceExtension->FrameHeader[1] + 3;
                    DeviceExtension->ContinueFrame = TRUE;                
                  }
                  else
                  {
                    DeviceExtension->RTL = 1;
                    DeviceExtension->ContinueFrame = FALSE;                                   
                  }               
                  break;
                case DelimiterSD3: // Frame of fixed Length with Data Field
                  DeviceExtension->RTL = 11;
                  DeviceExtension->ContinueFrame = TRUE;                                
                  break;
                case DelimiterSD4: // Token Frame
                  DeviceExtension->RTL = 3;
                  DeviceExtension->ContinueFrame = FALSE;                               
                  break;                  
                default:
                  DeviceExtension->RTL = 1;               
                  DeviceExtension->ContinueFrame = FALSE;
                  break;
              }
              
            }
            
            if ( DeviceExtension->ContinueFrame )
            {
              while ( DeviceExtension->RTL && u950pci_RxDataReady( DeviceExtension ) )
              {
                ch = u950pci_inb( DeviceExtension->port, UART_RX );
                PB_RxByte( &( DeviceExtension->PB ), ch );                
                DeviceExtension->RTL--;

⌨️ 快捷键说明

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