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

📄 16950pci.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// $Id: 16950pci.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:
// ------
//   Funkce pro praci s obvodem 16PCI954. Zajisteni pristupu do rozsirenych
// registru obvodu (Specific Registers a Indexed Control Register Set).
//   Funkce pro inicializaci obvodu a nastaveni pozadovaneho rezimu.
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

#include "serial_reg.h"
#include "vardef.h"

#define u950pci_inb(base,port)      READ_PORT_UCHAR( (PUCHAR) ((base)+(port)) )
#define u950pci_outb(base,port,val) WRITE_PORT_UCHAR( (PUCHAR) ((base)+(port)), (UCHAR) (val) )

//#define u950pci_inb(base,port)      DbgPrint( "READ_PORT_UCHAR from port %d\n",( (int) ((base)+(port)) ) )
//#define u950pci_outb(base,port,val) DbgPrint( "WRITE_PORT_UCHAR %d to port %d\n", (int) (val), (int) ((base)+(port)) )


#ifdef AUTOMATIC_RX
  #define U950PCI_MCR_IE  0x88  // receive/transmit MCR without change  
  #define U950PCI_MCR_OE  0x88  
#else
  #define U950PCI_MCR_IE  0x88  // receive  0x09 for Advantech +Prescaler Enabled
  #define U950PCI_MCR_OE  0x89  // transmit 0x08 for Advantech +Prescaler Enabled
#endif  
  #define U950PCI_MCR_TXDTRPOL 0x01

#define U950PCI_LCR_UL  0x1B  /* receive/transmit */ // SET PARAMETERS HERE
#define U950PCI_LCR_ULB 0x5B  /* transmit line break */
#define U950PCI_LCR_EFR 0xBF  /* enable access to EFR, XONx */

#define U950PCI_LSR_C 0x04  /* controll character received */
#define U950PCI_LSR_ERR 0x1A  /* error in receiver */

#define U950PCI_NMR_EN  0x03  /* 9-bit communication settings */

#define U950PCI_IIR_ID  0x3f  /* more IRQ levels */

#define U950pci_MSR_RxD UART_MSR_RI /* Pin for RxD level sense */

/* flags of chip options used in u950pci_init */
/* unfortunate random DTR polarity over different vendors  !!! */
#define U950PCI_CHOPT_TXDTRNEG 1  /* negated polarity (Advantech) */
#define U950PCI_CHOPT_HSPDOSC  2  /* oscilator 14.7456MHz/1.8432MHz */
#define U950PCI_CHOPT_RXDONRI  4  /* RxD signal connected to RI */

#define U950PCI_ACR_VAL chip_buff[2] /* shaddow buffer of ACR */
/* default ACR value : DTR=1 when Tx, 950 trigger levels enable  */
#ifdef AUTOMATIC_RX
  #define U950PCI_ACR_UL  (UART_ACR_TLENB)
  #define U950PCI_ACR_ULTX (U950PCI_ACR_UL|0x10) // 0x18 - automatic DTR control
  #define U950PCI_ACR_TXDTRPOL 0x08 /* ^- 0x18 for Advantech */
#else
  #define U950PCI_ACR_UL  (UART_ACR_TLENB)
  #define U950PCI_ACR_ULTX (U950PCI_ACR_UL|0x10|UART_ACR_RXDIS)/**/   // 0x10 ??? - not used in this mode
  #define U950PCI_ACR_TXDTRPOL 0x08 /* ^- 0x18 for Advantech */
#endif  

#define U950PCI_STATE chip_buff[3] /* chip state information */
#define U950PCI_STATE_TX    1
#define U950PCI_STATE_FLUSH 2

#define U950PCI_RX_ACRMCR chip_buff[4] /* set this for RX - LSB=ACR, MSB=MCR */
#define U950PCI_RX_ACR(udrv) (udrv->U950PCI_RX_ACRMCR)
#define U950PCI_RX_MCR(udrv) ((udrv->U950PCI_RX_ACRMCR>>8))
#define U950PCI_TX_ACRMCR chip_buff[5] /* set this for TX - LSB=ACR, MSB=MCR */
#define U950PCI_TX_ACR(udrv) (udrv->U950PCI_TX_ACRMCR)
#define U950PCI_TX_MCR(udrv) ((udrv->U950PCI_TX_ACRMCR>>8))


//*****************************************************************************

void u950pci_SetBaudRate( PPROFIM_DEVICE_EXTENSION DevExt, 
                          int SC,
                          int DIV,
                          int CPR );
                          
void u950pci_GetBaudRateParameters( PPROFIM_DEVICE_EXTENSION DevExt, 
                          LONG XTALFrequency,
                          LONG BaudRate,
                          int *SC,
                          int *DIV,
                          int *CPR );
void u950pci_RxTreshold( PPROFIM_DEVICE_EXTENSION DevExt, int Treshold );


//*****************************************************************************
//** Funkce umoznujici zapis do registru v Indexed Control Registr Set.
//** Jde o registry ACR, CPR, TCR CKS, TTL, RTL, FCL, FCH, IDx, REV, CSR, NMR,
//** MDM, RFC, GDS.
//** 
//** Parametry:
//**   index - adresa ciloveho registru ( UART_ACR=0x00 ... UART_GDS=0x10 )
//**   val   - zapisovana hodnota
//**
//*****************************************************************************

INLINE void u950pci_icr_write( PPROFIM_DEVICE_EXTENSION DevExt,
                               int index,
                               int val )
{
  u950pci_outb( DevExt->port, UART_SCR, index );
  u950pci_outb( DevExt->port, UART_ICR, val );
}



//*****************************************************************************
//** Funkce umoznujici cteni z registru v Indexed Control Registr Set.
//** Jde o registry ACR, CPR, TCR CKS, TTL, RTL, FCL, FCH, IDx, REV, CSR, NMR,
//** MDM, RFC, GDS.
//** 
//** Parametry:
//**   index - adresa ciloveho registru ( UART_ACR=0x00 ... UART_GDS=0x10 )
//**
//*****************************************************************************

unsigned u950pci_icr_read( PPROFIM_DEVICE_EXTENSION DevExt, int index )
{
  unsigned val;
  u950pci_icr_write( DevExt,
                     UART_ACR,
                     DevExt->U950PCI_ACR_VAL | UART_ACR_ICRRD );
  u950pci_outb( DevExt->port, UART_SCR, index );
  val = u950pci_inb( DevExt->port, UART_ICR );
  u950pci_icr_write( DevExt, UART_ACR, DevExt->U950PCI_ACR_VAL );
  return val;
}



//*****************************************************************************
//** Funkce umoznujici cteni registru udavajicich pocet znaku ve vyrovnavacich
//** pametech FIFO. Cteny mohou byt registry:
//**
//** RFL (Number of characters in the receiver FIFO)     reg = UART_RFL
//** TFL (Number of characters in the transfimer FIFO)   reg = UART_TFL
//**
//*****************************************************************************

unsigned u950pci_xfl_read( PPROFIM_DEVICE_EXTENSION DevExt, int reg )
{
  unsigned val;
  u950pci_icr_write( DevExt,
                     UART_ACR,
                     DevExt->U950PCI_ACR_VAL | UART_ACR_ASREN );
  val = u950pci_inb( DevExt->port, reg );
  /* no need to set ACR index - SCR not changed */
  u950pci_outb( DevExt->port, UART_ICR, DevExt->U950PCI_ACR_VAL );
  return val;
}



//*****************************************************************************
//** Zapis do registru ACR
//**
//*****************************************************************************

INLINE void u950pci_acr_write( PPROFIM_DEVICE_EXTENSION DevExt, int val )
{
  DevExt->U950PCI_ACR_VAL = val;
  u950pci_icr_write( DevExt, UART_ACR, val );
}




//*****************************************************************************
//** 16950pci initialize ports (1st part)
//**
//*****************************************************************************
int u950pci_init( PPROFIM_DEVICE_EXTENSION DevExt, 
                  int port, 
                  int irq, 
                  int baud, 
                  int options )
{
  unsigned u;
  unsigned old_mcr, mcr_ie;
  unsigned chip_id, chip_rev;
  if ( !irq || !port )
  {
    DbgPrint( "ProfiM u950pci_init: port or irq unknown\n" );
    return FALSE;
  }
  DbgPrint( "ProfiM u950pci_init: irq %d port 0x%x\n", irq, port );

  old_mcr = u950pci_inb( port, UART_MCR );
  /* find right value for mcr_ie */
  mcr_ie = U950PCI_MCR_IE;
  if ( options & U950PCI_CHOPT_TXDTRNEG )
    mcr_ie ^= U950PCI_MCR_TXDTRPOL;
  /* Disable output buffer */
  u950pci_outb( port, UART_MCR, mcr_ie & 3 );
  /* Switch to enhanced mode */
  u950pci_outb( port, UART_LCR, U950PCI_LCR_EFR );
  u950pci_outb( port, UART_EFR, UART_EFR_ECB );
  u950pci_outb( port, UART_LCR, U950PCI_LCR_UL );
  /* Disable transmitter output  */
  u950pci_outb( port, UART_MCR, mcr_ie & 3 );
  /* Set up ACR and state */
  u950pci_outb( port, UART_SCR, UART_ACR );
  u950pci_outb( port, UART_ICR, U950PCI_ACR_UL | UART_ACR_ICRRD );
  /* Read chip ID */
  u950pci_outb( port, UART_SCR, UART_ID1 );
  chip_id = u950pci_inb( port, UART_ICR ) << 16;
  u950pci_outb( port, UART_SCR, UART_ID2 );
  chip_id |= u950pci_inb( port, UART_ICR ) << 8;
  u950pci_outb( port, UART_SCR, UART_ID3 );
  chip_id |= u950pci_inb( port, UART_ICR );
  u950pci_outb( port, UART_SCR, UART_REV );
  chip_rev = u950pci_inb( port, UART_ICR );
  DbgPrint( "ProfiM u950pci_init: chip ID %06X. rev %02x\n",
            chip_id,
            chip_rev );
  /* Switch enhancements off */
  u950pci_outb( port, UART_LCR, U950PCI_LCR_EFR );
  u950pci_outb( port, UART_EFR, 0 );
  u950pci_outb( port, UART_LCR, U950PCI_LCR_UL );
  {
    DbgPrint( "ProfiM u950pci_init: init OK\n" );
    DevExt->chip_options = options;
    /* setup configurations for RX/TX */
    DevExt->U950PCI_RX_ACRMCR = U950PCI_ACR_UL | ( U950PCI_MCR_IE << 8 );
    DevExt->U950PCI_TX_ACRMCR = U950PCI_ACR_ULTX | ( U950PCI_MCR_OE << 8 );
    if ( DevExt->chip_options & U950PCI_CHOPT_TXDTRNEG )
    {
      DbgPrint( "ProfiM u950pci_init: ADVANTECH !!!\n" ); 
      DevExt->U950PCI_RX_ACRMCR ^= U950PCI_MCR_TXDTRPOL << 8;
      DevExt->U950PCI_TX_ACRMCR ^= U950PCI_ACR_TXDTRPOL |
                                 ( U950PCI_MCR_TXDTRPOL << 8 );
    }
    /* check and setup baud base oscilator frequency */
    if ( !DevExt->baud_base )
    {
      if ( DevExt->chip_options & U950PCI_CHOPT_HSPDOSC )
        DevExt->baud_base = 14745600;
      else
        DevExt->baud_base = 1843200;
        
      // Pro specialni verzi karty pro firmu PiKRON byl na karte vymenen 
      // krystal za rychlejsi na 24.07342Mhz        
      if (DevExt->PiKRON)  
        DevExt->baud_base = 24073420;
      
      DbgPrint( "ProfiM u950pci_init: Oscilator frequency = %ldHz\n", 
                DevExt->baud_base);                            
    }
    
    if ( !baud )
      baud = 9600;
    DevExt->baud_val = baud;
    u = ( DevExt->baud_base * 8 + baud / 2 ) / baud;
    if ( u > 0xFFFFFFF )
      u = 0xFFFFFFF;
    DevExt->baud_div = u;
    DevExt->port = port;
    DevExt->irq = irq; 
   
    return TRUE;
  }
  DbgPrint( "ProfiM u950pci_init: MCR test Error\n" );
  return FALSE;
};



//*****************************************************************************
//** 16950pci deinitialize ports
//**
//*****************************************************************************

int u950pci_pdone( PPROFIM_DEVICE_EXTENSION DevExt )
{
  u950pci_outb( DevExt->port, UART_IER, 0 ); /* disable interrupts */
  /* Switch enhanced mode off */
  u950pci_outb( DevExt->port, UART_LCR, U950PCI_LCR_EFR );
  u950pci_outb( DevExt->port, UART_EFR, 0 );
  u950pci_outb( DevExt->port, UART_LCR, U950PCI_LCR_UL );
  /* clean up */
  u950pci_outb( DevExt->port, UART_IER, 0 );  /* disable interrupts */

⌨️ 快捷键说明

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