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

📄 16950pci.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  
  //
  // Switch to receive
  //
  #ifdef AUTOMATIC_RX
    // Disable automatic DTR control
    u950pci_acr_write( DevExt, U950PCI_RX_ACR( DevExt) );
  #else
    u950pci_outb( DevExt->port, UART_MCR, U950PCI_RX_MCR( DevExt ) & 3 );
  #endif
  
  u950pci_inb( DevExt->port, UART_IIR ); /* flush irq */
  u950pci_inb( DevExt->port, UART_LSR ); /* flush irq */
  return TRUE;
};



//*****************************************************************************
//** 16950pci initialize ports (2nd part)
//**
//*****************************************************************************

int u950pci_pinit( PPROFIM_DEVICE_EXTENSION DevExt )
{
  unsigned u;
  int baud  = DevExt->baud_val;
  int SC;
  int DIV;
  int CPR;
  
  /* Switch to enhanced mode */
  u950pci_outb( DevExt->port, UART_LCR, U950PCI_LCR_EFR );
  u950pci_outb( DevExt->port, UART_EFR, UART_EFR_ECB );
  u950pci_outb( DevExt->port, UART_LCR, U950PCI_LCR_UL );
  /* Disable transmitter output */
  u950pci_outb( DevExt->port, UART_MCR, U950PCI_RX_MCR( DevExt ) & 3 );
  /* Set up ACR and state */
  u950pci_acr_write( DevExt, U950PCI_RX_ACR( DevExt ) );
  DevExt->U950PCI_STATE = U950PCI_STATE_FLUSH;

  DevExt->chip_buff[0] = 0;
  
  //
  // setup baud rate
  //  
  if ( !baud )
    baud = 19200;
  u950pci_GetBaudRateParameters( DevExt, DevExt->baud_base, baud,
                                 &SC, &DIV, &CPR );                                  
  u950pci_SetBaudRate( DevExt, SC, DIV, CPR );
  
  DbgPrint ( "ProfiM u950pci : Baud rate setup SC=%d DIV=%d CPR=%d\n",
             SC,
             DIV,
             CPR );             
  DbgPrint ( "ProfiM u950pci : Skutecny Baudrate = %ldbaud\n",
             8 * DevExt->baud_base / ( SC * DIV * CPR ) );
             
  
        
  /* setup initial FIFO levels */
  u950pci_outb( DevExt->port, UART_IER, 0 );  /* disable interrupt sources */
  u950pci_outb( DevExt->port,
                UART_FCR,
                UART_FCR_ENABLE_FIFO |
                UART_FCR_CLEAR_RCVR |
                UART_FCR_CLEAR_XMIT ); /* enable and clear FIFOs */
                
  u950pci_icr_write( DevExt, UART_TTL, 0 ); /* transmittion FIFO treshold */
  
  #ifdef AUTOMATIC_RX
    u950pci_RxTreshold( DevExt, 127 ); /* set maximum FIFO treshold */    
  #else  
    u950pci_RxTreshold( DevExt, 1 ); /* receive FIFO treshold */  
  #endif

  
  /* reset errors */
  u950pci_inb( DevExt->port, UART_LSR );  
  /* and other irq */
  u950pci_inb( DevExt->port, UART_RX ); 
  /* Enable interrupts */
  u950pci_outb( DevExt->port, UART_MCR, U950PCI_RX_MCR( DevExt ) );   
  /* enable interrupt sources */  
  u950pci_outb( DevExt->port, UART_IER, 
                UART_IER_RDI | UART_IER_THRI | UART_IER_RLSI );   // UART_IER_RLSI zatim navic - pro time-out ???
    
  //DbgPrint ( "ProfiM u950pci : Last MCR value=%2x\n", 
  //             UART_MCR, U950PCI_RX_MCR( DevExt ) );
  //DbgPrint ( "Profim u950pci : ACR = %x", 
  //             u950pci_icr_read( DevExt, UART_ACR ) );
  
  return TRUE;
};



//*****************************************************************************
//** Set transmittion FIFO treshold
//**
//*****************************************************************************

void u950pci_TxTreshold( PPROFIM_DEVICE_EXTENSION DevExt, int Treshold )        
{
    u950pci_icr_write( DevExt, UART_TTL, Treshold );
}



//*****************************************************************************
//** Set receive FIFO treshold
//**
//*****************************************************************************

void u950pci_RxTreshold( PPROFIM_DEVICE_EXTENSION DevExt, int Treshold )        
{
    DevExt->RTL = Treshold;
    u950pci_icr_write( DevExt, UART_RTL, Treshold );
}



//*****************************************************************************
//** Checks for waitting data if receiver FIFO
//**
//*****************************************************************************

BOOLEAN u950pci_RxDataReady( PPROFIM_DEVICE_EXTENSION DevExt )        
{
  return ( u950pci_xfl_read( DevExt, UART_RFL ) > 0 ); 
}



//*****************************************************************************
//** Set baud rate
//**
//** Vysledny baud rate je dan jako:
//** BR = 8 * XTALFrequency / ( SC * DIV * CPR )
//**
//*****************************************************************************

void u950pci_SetBaudRate( PPROFIM_DEVICE_EXTENSION DevExt, 
                          int SC,
                          int DIV,
                          int CPR )        
{ 
  //
  // prescaler 1 to 31.875 step 0.125
  // prescaler=CPR/8
  //
  u950pci_icr_write( DevExt, UART_CPR, CPR ); 
  
  //
  // 4 to 16 times per clock
  //
  if (SC>=4 && SC<=15)
    u950pci_icr_write( DevExt, UART_TCR, SC ); 
  else
    u950pci_icr_write( DevExt, UART_TCR, 0x00 );   
  
  //    
  // divisor 1 to 2^16
  //
  u950pci_outb( DevExt->port, UART_LCR, UART_LCR_DLAB );
  u950pci_outb( DevExt->port, UART_DLL, DIV & 0x00FF );
  u950pci_outb( DevExt->port, UART_DLM, ( DIV >> 8 ) );
  u950pci_outb( DevExt->port, UART_LCR, U950PCI_LCR_UL );   
}



//*****************************************************************************
//**   Get baud rate parameters
//** Pro zname hodnoty frekvenci krystalu vraci parametry pro nastaveni rych-
//** losti UARTu. Vracene parametry jsou nejlepsi mozne pro dany krystal a
//** pozadovany baud rate - skutecny baud rate ma minimalni odchylku.
//** Pro potreby Profibusu je normou stanovena maximalni tolerance +/- 0.3 %.
//** Takze pro krystal 1.8432Mhz je nejvyssi rychlost v norme 45.45kbps
//** (prakticky funguje az po 187.5kbps.
//** Pro krystal 14.7456Mhz je nejvyssi rychlost v norme 500kbps.
//**
//** Vysledny baud rate je dan jako:
//** BR = 8 * XTALFrequency / ( SC * DIV * CPR )
//**
//** Vztah mezi hodnotami Prescaler a CPR:
//** Prescaler = CPR / 8
//**
//*****************************************************************************

void u950pci_GetBaudRateParameters( PPROFIM_DEVICE_EXTENSION DevExt, 
                          LONG XTALFrequency,
                          LONG BaudRate,
                          int *SC,
                          int *DIV,
                          int *CPR )        
{ 
  
  switch (XTALFrequency)
  {
    case 1843200:
        switch (BaudRate)
        {
          case 9600:    *SC=16; *DIV=12; *CPR=8;
                        break; 
          case 19200:   *SC=16; *DIV=6;  *CPR=8;
                        break;
          case 45450:   *SC=12; *DIV=3;  *CPR=9;
                        break;                
          case 93750:   *SC=13; *DIV=1;  *CPR=12;   // chyba presahuje 0.3%
                        break;                                
          case 187500:  *SC=6;  *DIV=1;  *CPR=13;   // chyba presahuje 0.3%
                        break;                  
          case 375000:  *SC=5;  *DIV=1;  *CPR=8;    // chyba presahuje 0.3%
                        break;                              
          default:      *SC=16; *DIV=12; *CPR=8;    // chyba presahuje 0.3%
                        break;                      
        }
        break;
    
    case 14745600: 
        switch (BaudRate)
        {
          case 9600:    *SC=16; *DIV=96; *CPR=8;
                        break; 
          case 19200:   *SC=16; *DIV=48; *CPR=8;
                        break;
          case 45450:   *SC=15; *DIV=1;  *CPR=173;
                        break;                
          case 93750:   *SC=14; *DIV=10; *CPR=9;
                        break;                                
          case 187500:  *SC=14; *DIV=5;  *CPR=9;
                        break;                  
          case 375000:  *SC=7;  *DIV=5;  *CPR=9;
                        break;                              
          case 500000:  *SC=4;  *DIV=1;  *CPR=59;
                        break;                  
          case 750000:  *SC=13; *DIV=1;  *CPR=12;   // chyba presahuje 0.3%
                        break;                                                      
          case 1500000: *SC=6;  *DIV=1;  *CPR=13;   // chyba presahuje 0.3%
                        break;                                                                              
          default:      *SC=16; *DIV=96; *CPR=8;
                        break;                      
        }    
        break;                
      
    case 24073420:
        switch (BaudRate)
        {
          case 9600:    *SC=10; *DIV=118; *CPR=17;
                        break; 
          case 19200:   *SC=10; *DIV=59;  *CPR=17;
                        break;
          case 45450:   *SC=13; *DIV=2;   *CPR=163;
                        break;                
          case 93750:   *SC=13; *DIV=2;   *CPR=79;
                        break;                                
          case 187500:  *SC=13; *DIV=1;   *CPR=79;
                        break;                  
          case 375000:  *SC=9;  *DIV=3;   *CPR=19;
                        break;                              
          case 500000:  *SC=7;  *DIV=5;   *CPR=11;
                        break;                  
          case 750000:  *SC=16; *DIV=2;   *CPR=8;  // chyba 0.3%
                        break;                                                      
          case 1500000: *SC=16; *DIV=1;   *CPR=8;  // chyba 0.3%
                        break;                  
          case 3000000: *SC=8;  *DIV=1;   *CPR=8;  // chyba 0.3%
                        break;                  
          case 6000000: *SC=4;  *DIV=1;   *CPR=8;  // chyba 0.3%
                        break;                                                                                                                             
          default:      *SC=10; *DIV=118; *CPR=17;
                        break;                      
        }        
        break;
        
    default:
        //
        // Pokud frekvence krystalu nepatri k predpocitanym  jsou parametry
        // vypocitany, avsak pouze pro pevne hodnoty Prescaler=1 a SC=4
        // tzn. muze existovat jina kombinace Prescaler, SC a Divider, ktera
        // dosahne pro pozadovany baud rate vetsi presnosti.
        //
        *CPR=8; // odpovida Prescaler=1
        *SC=4;
        *DIV=XTALFrequency / ( 4 * BaudRate );
        break;
  }
  
}






⌨️ 快捷键说明

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