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

📄 ul_c950pci.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
 udrv->wait_time=((udrv->my_adr-u-1)&0xF)+4;  if(((u&0x180)!=0x180)||    (u==0x1FF)) udrv->wait_time+=0x10; udrv->last_ctrl=0; udrv->char_buff=0; udrv->chip_temp=(udrv->my_adr&0x3F)|0x40; UL_FCALL2(*udrv->fnc_wait,u950pci_connect_1); return UL_RC_PROC;};int u950pci_connect_1(ul_drv *udrv, int ret_code){  if(ret_code!=UL_RC_ETIMEOUT)    { UL_FRET; return UL_RC_EARBIT;}  if(u950pci_rxd_cs(udrv)|| /* check for possible collision */     (u950pci_inb(udrv->port,UART_LSR)&UART_LSR_DR))  { UL_FRET;    LOG_CHIO(" EARBIT!");    return UL_RC_EARBIT;  }  udrv->U950PCI_STATE|=U950PCI_STATE_TX;  u950pci_acr_write(udrv,U950PCI_TX_ACR(udrv));  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_ULB);  u950pci_outb(udrv->port,UART_MCR,U950PCI_TX_MCR(udrv));  UL_FNEXT(u950pci_connect_2);  /* wait to end of transfer */  u950pci_icr_write(udrv,UART_TTL,0);	/* wait for TEMT */  u950pci_outb(udrv->port,UART_TX,0);  u950pci_outb(udrv->port,UART_IER,UART_IER_THRI|UART_IER_RDI);  return UL_RC_WIRQ;};int u950pci_connect_2(ul_drv *udrv, int ret_code){  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL);  u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv));  udrv->U950PCI_STATE&=~U950PCI_STATE_TX;  u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv));  if(u950pci_xfl_read(udrv,UART_RFL)>0)  { UL_FRET;    LOG_CHIO(" EARBIT1!");    return UL_RC_EARBIT;  }  if(udrv->chip_temp==1)  { LOG_CHIO(" Connected");    UL_FRET;  }else{     udrv->wait_time=(udrv->chip_temp&3)+1;    udrv->chip_temp>>=2;    UL_FCALL2(*udrv->fnc_wait,u950pci_connect_1);  }  return UL_RC_PROC;};/* UL_FNEXT(u950pci_recch); UL_FCALL(u950pci_recch); UL_FCALL2(u950pci_recch,u950pci_recch); UL_FRET;*/static char *u950pci_port_name="ulan_u950pci";/*** 16950pci initialize ports ***/int u950pci_pinit(ul_drv *udrv){  unsigned u;  int baud=udrv->baud_val;  int cpr, tcr, dl;  if (UL_REQ_IOS(udrv->port,8,u950pci_port_name)<0)   { LOG_FATAL(KERN_CRIT "uLan u950pci_pinit : cannot reguest ports !\n");    return UL_RC_EPORT;  }  /* Switch to enhanced mode */  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_EFR);  u950pci_outb(udrv->port,UART_EFR,UART_EFR_ECB);  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL);  /* Disable transmitter output  */  u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)&3);  /* Set up ACR and state */  u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv));  udrv->U950PCI_STATE=U950PCI_STATE_FLUSH;  #if 0  /* Read chip ID */  chip_id=u950pci_icr_read(udrv,UART_ID1)<<16;  chip_id|=u950pci_icr_read(udrv,UART_ID2)<<8;  chip_id|=u950pci_icr_read(udrv,UART_ID3);  chip_rev=u950pci_icr_read(udrv,UART_REV);  LOG_PORTS(KERN_INFO "uLan u950pci : chip ID %06X. rev %02x\n",chip_id,chip_rev);  #endif  udrv->chip_buff[0]=0;  /* setup baud rate */  if(!baud) baud=19200;  u=(udrv->baud_base*8+baud/2)/baud;  if (u>0xFFFFFFF) u=0xFFFFFFF;  udrv->baud_div=u;  /*{long e, tcr_err=0xFFFFFFF;    int i;    tcr=-1;    for(i=16;i>=4;i--){      if(i*0xFFFFFF<u) break;      e=u%i;      if(e<tcr_err){tcr=i;tcr_err=e;}    }  }*/  tcr=16; cpr=8;  dl=(udrv->baud_div+(cpr*tcr)/2)/(cpr*tcr);  /*LOG_PORTS*/  UL_PRINTF(KERN_INFO "uLan u950pci : baud setup TCR=%d CPR=%d DL=%d baud=%ld\n",            tcr,cpr,dl,udrv->baud_base*8/(tcr*cpr*dl));  UL_PRINTF(KERN_INFO "uLan u950pci : baud=%d baud_base=%ld baud_div=%d\n",            baud,udrv->baud_base,udrv->baud_div);  u950pci_icr_write(udrv,UART_CPR,cpr);	/* prescaller 1 to 31.875 step 0.125*/  u950pci_icr_write(udrv,UART_TCR,tcr);	/* 4 to 16 times per clock */  u950pci_outb(udrv->port,UART_LCR,UART_LCR_DLAB);  u950pci_outb(udrv->port,(uchar)UART_DLL,(uchar)dl);  u950pci_outb(udrv->port,(uchar)UART_DLM,(uchar)(dl>>8));  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL);  /* setup initial FIFO levels */  u950pci_icr_write(udrv,UART_NMR,U950PCI_NMR_EN); /* 9-bit mode enable */  u950pci_outb(udrv->port,UART_IER,0);	/* disable interrupt sources */  u950pci_outb(udrv->port,UART_FCR,UART_FCR_ENABLE_FIFO|	 UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT); /* enable and clear FIFOs */  u950pci_icr_write(udrv,UART_TTL,1);	/* transmittion FIFO treshold */  u950pci_icr_write(udrv,UART_RTL,1);	/* receive FIFO treshold */  u950pci_inb(udrv->port,UART_LSR);	/* reset errors */  u950pci_inb(udrv->port,UART_RX);	/* and other irq */  u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)); /* Enable interrupts */  return UL_RC_PROC;};/*** 16950pci deinitialize ports ***/int u950pci_pdone(ul_drv *udrv){  u950pci_outb(udrv->port,UART_IER, 0);	/* disable interrupts */  /* Switch enhanced mode off */  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_EFR);  u950pci_outb(udrv->port,UART_EFR,0);  u950pci_outb(udrv->port,UART_LCR,U950PCI_LCR_UL);  /* clean up */  u950pci_outb(udrv->port,UART_IER,0);	/* disable interrupts */  u950pci_outb(udrv->port,UART_MCR,U950PCI_RX_MCR(udrv)&3); /* transmitter off */  u950pci_inb(udrv->port,UART_IIR);	/* flush irq */  u950pci_inb(udrv->port,UART_LSR);	/* flush irq */  UL_REL_IOS(udrv->port,8);  return UL_RC_PROC;};/*** 16950pci generate irq for irq_probe */int u950pci_genirq(ul_drv *udrv,int param){  if(param){    u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); /* transmitter off */    u950pci_outb(udrv->port,UART_IER, UART_IER_MSI);	/* enable interrupts */    u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_ULB);	/* trig break */  }else{    u950pci_outb(udrv->port,UART_IER, 0);		/* disable interrupts */    u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)&3); /* transmitter off */    u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL); /* no break */    u950pci_inb(udrv->port,UART_MSR);		/* flush irq */  }  return UL_RC_PROC;};#if 0/*** 16950pci request IRQ handling */int u950pci_rqirq(ul_drv *udrv,int param){  return UL_RC_PROC;};/*** 16950pci release IRQ handling */int u950pci_freeirq(ul_drv *udrv,int param){  if(uldrv->irq)    free_irq(udrv->irq, udrv);  return UL_RC_PROC;};#endif/* support for hardware tests */int u950pci_hwtest(ul_drv *udrv,int param){  unsigned char uc;  switch(param)  {    case 0x10:    case 0x11:	  u950pci_outb(udrv->port,UART_IER, 0); /* disable interrupts */	  u950pci_outb(udrv->port,UART_MCR, U950PCI_TX_MCR(udrv)); /* transmitter on */	  u950pci_outb(udrv->port,UART_LCR, param&1?	               U950PCI_LCR_UL:U950PCI_LCR_ULB); /* set TD lines */    case 0x12:	  uc=u950pci_inb(udrv->port,UART_MSR);	  return u950pci_inb(udrv->port,UART_LSR)|(uc<<8)|		 (uc&(U950pci_MSR_RxD)?0:0x10000);    case 0x13:	  u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); /* transmitter off */	  uc=u950pci_inb(udrv->port,UART_MSR);	  return u950pci_inb(udrv->port,UART_LSR)|(uc<<8)|		 (uc&(U950pci_MSR_RxD)?0:0x10000);  }  return UL_RC_ENOFNC;};/*** Control functions of chip driver  ***/int u950pci_cctrl(ul_drv *udrv, int ctrl_fnc, int param){  switch (ctrl_fnc)  {    case UL_CC_DIN:	/* switch off line transmitter */	  u950pci_outb(udrv->port,UART_MCR, U950PCI_RX_MCR(udrv)); 	  u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL);	  u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv));	  return UL_RC_PROC;    case UL_CC_DOUT:	/* switch on line transmitter */	  u950pci_outb(udrv->port,UART_MCR, U950PCI_TX_MCR(udrv));	  u950pci_outb(udrv->port,UART_LCR, U950PCI_LCR_UL);	  u950pci_acr_write(udrv,U950PCI_RX_ACR(udrv));	  return UL_RC_PROC;    case UL_CC_PINIT:	/* initialize ports (parameter baud)*/  	  return u950pci_pinit(udrv);    case UL_CC_PDONE:	/* deinitialize ports */  	  return u950pci_pdone(udrv);    case UL_CC_GENIRQ:	/* generate irq for irq_probe */  	  return u950pci_genirq(udrv,param);   #if 0    case UL_CC_RQIRQ:	/* request IRQ handling */  	  return u950pci_rqirq(udrv,param);    case UL_CC_FREEIRQ:	/* release IRQ handling */  	  return u950pci_freeirq(udrv,param);   #endif    case UL_CC_HWTEST:	/* support for hardware testing */  	  return u950pci_hwtest(udrv,param);  };  return UL_RC_ENOFNC;};/*** 16950pci chip driver initialize ***/int u950pci_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options){  unsigned u;  unsigned old_mcr, mcr_ie;  unsigned chip_id, chip_rev;  if(!irq||!port){    LOG_FATAL(KERN_CRIT "uLan u950pci_init : port or irq unknown\n");    return UL_RC_EPORT;  }  UL_PRINTF(KERN_INFO "uLan u950pci_init : irq %d port 0x%x\n",irq,port);  if (UL_REQ_IOS(port,8,u950pci_port_name)<0)   { LOG_FATAL(KERN_CRIT "uLan u950pci_init : cannot reguest ports !\n");    return UL_RC_EPORT;  }  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);  LOG_PORTS(KERN_INFO "uLan u950pci : 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);  { LOG_PORTS(KERN_INFO "uLan u950pci_init : init OK\n");    udrv->chip_options=options;    udrv->baud_base=baudbase;    /* setup configurations for RX/TX */    udrv->U950PCI_RX_ACRMCR=U950PCI_ACR_UL|(U950PCI_MCR_IE<<8);    udrv->U950PCI_TX_ACRMCR=U950PCI_ACR_ULTX|(U950PCI_MCR_OE<<8);    if(udrv->chip_options&U950PCI_CHOPT_TXDTRNEG){      udrv->U950PCI_RX_ACRMCR^=U950PCI_MCR_TXDTRPOL<<8;      udrv->U950PCI_TX_ACRMCR^=U950PCI_ACR_TXDTRPOL|(U950PCI_MCR_TXDTRPOL<<8);    }    /* check and setup baud base oscilator frequency */    if(!udrv->baud_base){     if(udrv->chip_options&U950PCI_CHOPT_HSPDOSC)       udrv->baud_base=14745600;     else       udrv->baud_base=1843200;    }    if(!baud) baud=19200;    udrv->baud_val=baud;    u=(udrv->baud_base*8+baud/2)/baud;    if (u>0xFFFFFFF) u=0xFFFFFFF;    udrv->baud_div=u;    udrv->port=port;    udrv->irq=irq;     udrv->fnc_recch=&u950pci_recch;    udrv->fnc_sndch=&u950pci_sndch;    udrv->fnc_wait=&u950pci_wait;    udrv->fnc_pool=&u950pci_pool;    udrv->fnc_connect=&u950pci_connect;    udrv->fnc_cctrl=&u950pci_cctrl;    UL_REL_IOS(port,8);    return 0;  }  LOG_PORTS(KERN_ERR "uLan u950pci_init : MCR test Error\n");  UL_REL_IOS(port,8);  return UL_RC_EPORT;};

⌨️ 快捷键说明

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