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

📄 ul_c450.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
  if(u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv))  {    UL_FCALL2(u450_weot,u450_wait_1);  } else UL_FNEXT(u450_wait_1);  return UL_RC_PROC;};int u450_wait_1(ul_drv *udrv, int ret_code){ uchar lsr_val; if(ret_code<0) {UL_FRET;return ret_code;}; lsr_val=u450_inb(udrv->port,UART_LSR); u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv)); u450_outb(udrv->port,UART_IER,UART_IER_THRI|UART_IER_RDI); if(lsr_val&UART_LSR_DR) {   UL_FRET;   return u450_recch_sub(udrv,lsr_val,u450_inb(udrv->port,UART_RX)); }; U450_FIX_RDI_GARBAGE(udrv,ret_code); if(!(lsr_val&UART_LSR_THRE)) return UL_RC_WIRQ; if(!udrv->wait_time) {   UL_FRET;   LOG_CHIO(" Timeout!");   return UL_RC_ETIMEOUT; }; UL_FNEXT(u450_wait_2); u450_outb(udrv->port,UART_TX,0); return UL_RC_WIRQ;};int u450_wait_2(ul_drv *udrv, int ret_code){  uchar lsr_val;  lsr_val=u450_inb(udrv->port,UART_LSR);  if(lsr_val&UART_LSR_DR)  {    UL_FRET;    return u450_recch_sub(udrv,lsr_val,u450_inb(udrv->port,UART_RX));  };  U450_FIX_RDI_GARBAGE(udrv,ret_code);  if(!(lsr_val&UART_LSR_THRE)) return UL_RC_WIRQ;  if(!udrv->wait_time--)  {    UL_FRET;    LOG_CHIO(" Timeout!");    return UL_RC_ETIMEOUT;  };  u450_outb(udrv->port,UART_TX,0);  return UL_RC_WIRQ;};/*** Connect to RS485 bus ***/  int u450_connect_1(ul_drv *udrv, int ret_code);  int u450_connect_2(ul_drv *udrv, int ret_code);int u450_connect(ul_drv *udrv, int ret_code){  unsigned u;  LOG_CHIO(" C_0 ");  u=udrv->last_ctrl;  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;  u450_inb(udrv->port,UART_MSR);  UL_FCALL2(*udrv->fnc_wait,u450_connect_1);  return UL_RC_PROC;};int u450_connect_1(ul_drv *udrv, int ret_code){  LOG_CHIO(" C_1 ");  if(ret_code!=UL_RC_ETIMEOUT)  { UL_FRET;    LOG_CHIO(" EARBIT1!");    return UL_RC_EARBIT;  };  /* check for RxD low */  if(u450_inb(udrv->port,UART_MSR)&U450_MSR_RxD(udrv))  { UL_FRET;    LOG_CHIO(" EARBIT2!");    return UL_RC_EARBIT;  };  u450_outb(udrv->port,UART_LCR,U450_LCR_ULB);  u450_inb(udrv->port,UART_LSR);  udrv->chip_temp|=0x300;  u450_outb(udrv->port,UART_IER, (UART_IER_RLSI|UART_IER_RDI));  u450_outb(udrv->port,UART_MCR,U450_MCR_OE(udrv));  UL_FNEXT(u450_connect_2);  /* wait for break condition now */  return UL_RC_WIRQ;};int u450_connect_2(ul_drv *udrv, int ret_code){  uchar lsr_val;  LOG_CHIO(" C_2 ");  lsr_val=u450_inb(udrv->port,UART_LSR);  if(lsr_val&UART_LSR_BI) udrv->chip_temp&=~0x100;  if(lsr_val&UART_LSR_DR) {    udrv->chip_temp&=~0x200;    u450_inb(udrv->port,UART_RX);  }  if (udrv->chip_temp&0x300) {    return UL_RC_WIRQ;  }  u450_outb(udrv->port,UART_LCR,U450_LCR_ULC);  u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv));  u450_inb(udrv->port,UART_LSR);  u450_inb(udrv->port,UART_RX);  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,u450_connect_1);  };  return UL_RC_PROC;};/* UL_FNEXT(u450_recch); UL_FCALL(u450_recch); UL_FCALL2(u450_recch,u450_recch); UL_FRET;*/#ifdef FOR_LINUX_KERNELstatic char *u450_port_name="ulan_u450";#endif/*** 16450 initialize ports ***/int u450_pinit(ul_drv *udrv){  unsigned u;  int baud=udrv->baud_val;  if (UL_REQ_IOS(udrv->port,8,u450_port_name)<0)   { LOG_FATAL(KERN_CRIT "uLan u450_pinit : cannot reguest ports !\n");    return UL_RC_EPORT;  };   if (!baud) baud=19200;  u=(udrv->baud_base+baud/2)/baud;  if (u>0xFFFF) u=0xFFFF;  udrv->baud_div=u;  udrv->chip_buff[0]=udrv->chip_buff[1]=0;  u450_outb(udrv->port,UART_MCR,UART_MCR_OUT1|UART_MCR_DTR);  u450_outb(udrv->port,UART_LCR,UART_LCR_DLAB);  u450_outb(udrv->port,(uchar)UART_DLL,(uchar)udrv->baud_div);  u450_outb(udrv->port,(uchar)UART_DLM,(uchar)(udrv->baud_div>>8));  u450_outb(udrv->port,UART_LCR,U450_LCR_UL);  u450_outb(udrv->port,UART_IER,0);  u450_outb(udrv->port,UART_FCR,0);	/* disable FIFOs */  u450_inb(udrv->port,UART_LSR);		/* reset errors */  u450_inb(udrv->port,UART_RX);		/* and other irq */  u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv)); /* connect irq */  return UL_RC_PROC;};/*** 16450 deinitialize ports ***/int u450_pdone(ul_drv *udrv){  u450_outb(udrv->port,UART_IER, 0);	/* disable interrupts */  u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)&3);  /* transmitter off */  u450_inb(udrv->port,UART_IIR);		/* flush irq */  u450_inb(udrv->port,UART_LSR);		/* flush irq */  UL_REL_IOS(udrv->port,8);  return UL_RC_PROC;};/*** 16450 generate irq for irq_probe */int u450_genirq(ul_drv *udrv,int param){  if(param)   {    u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv));  /* transmitter off */    u450_outb(udrv->port,UART_IER, UART_IER_MSI);	/* enable interrupts */    u450_outb(udrv->port,UART_LCR, U450_LCR_ULB);	/* trig break */  }else{    u450_outb(udrv->port,UART_IER, 0);		/* disable interrupts */    u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv));	/* transmitter off */    u450_inb(udrv->port,UART_MSR);		/* flush irq */  };  return UL_RC_PROC;};/* support for hardware tests */int u450_hwtest(ul_drv *udrv,int param){  unsigned u;  switch(param)  {   case 0x10:   case 0x11:	u450_outb(udrv->port,UART_IER, 0); /* disable interrupts */	u450_outb(udrv->port,UART_MCR, U450_MCR_OE(udrv)); /* transmitter on */	u450_outb(udrv->port,UART_LCR, param&1?	             U450_LCR_UL:U450_LCR_ULB); /* set TD lines */   case 0x12:        u=u450_inb(udrv->port,UART_MSR);	return u450_inb(udrv->port,UART_LSR)|(u<<8)|	                (u&(U450_MSR_TxD(udrv))?0:0x100000)|			(u&(U450_MSR_RxD(udrv))?0:0x10000);   case 0x13:	u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); /* transmitter off */        u=u450_inb(udrv->port,UART_MSR);	return u450_inb(udrv->port,UART_LSR)|(u<<8)|	                (u&(U450_MSR_TxD(udrv))?0:0x100000)|			(u&(U450_MSR_RxD(udrv))?0:0x10000);  }  return UL_RC_ENOFNC;};/*** Control functions of chip driver  ***/int u450_cctrl(ul_drv *udrv, int ctrl_fnc, int param){  switch (ctrl_fnc)  {   case UL_CC_DIN:	/* switch off line transmitter */	{ u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); 	  u450_outb(udrv->port,UART_LCR, U450_LCR_UL); 	  return UL_RC_PROC;	};   case UL_CC_DOUT:	/* switch on line transmitter */	{ u450_outb(udrv->port,UART_MCR, U450_MCR_OE(udrv));	  u450_outb(udrv->port,UART_LCR, U450_LCR_UL); 	  return UL_RC_PROC;	};   case UL_CC_PINIT:	/* initialize ports (parameter baud)*/  	{ return u450_pinit(udrv);  	};   case UL_CC_PDONE:	/* deinitialize ports */  	{ return u450_pdone(udrv);  	};   case UL_CC_GENIRQ:	/* generate irq for irq_probe */  	{return u450_genirq(udrv,param);  	};   case UL_CC_HWTEST:	/* support for hardware testing */  	{return u450_hwtest(udrv,param);  	};  };  return UL_RC_ENOFNC;};/*** 16450 chip driver initialize ***/int u450_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options){  unsigned u;  unsigned old_mcr;  unsigned old_lcr;  if (UL_REQ_IOS(port,8,u450_port_name)<0)  { LOG_FATAL(KERN_CRIT "uLan u450_init : cannot reguest ports !\n");    return UL_RC_EPORT;  };   #ifdef CONFIG_OC_UL_DRV_U450_VARPINS  U450_SET_MCR_CODES(udrv,U450_MCR_IE_C,U450_MCR_OE_C,U450_MCR_OEQ_C);  if(!(options&U450_CHOPT_MSRSWAP))    U450_SET_MSR_CODES(udrv,U450_MSR_RxD_C,U450_MSR_RxD_C,U450_MSR_DTxD_C);  else    U450_SET_MSR_CODES(udrv,UART_MSR_DSR,UART_MSR_CTS,UART_MSR_DCTS); #endif /*CONFIG_OC_UL_DRV_U450_VARPINS*/  LOG_PORTS("uLan u450_init : probe MCR\n");  old_mcr=u450_inb(port,UART_MCR);  LOG_PORTS("uLan u450_init : MCR = 0x%02X\n",old_mcr);  u450_outb(port,UART_MCR,UART_MCR_OUT1|UART_MCR_DTR);  #ifdef FOR_LINUX_KERNEL   set_current_state(TASK_INTERRUPTIBLE);   schedule_timeout(ULD_HZ/10);  #elif defined(_WIN32)   /* !!!!!!!!!!!!!! */   /* KeStallExecutionProcessor(20000); */   { LARGE_INTEGER delay;     delay=RtlConvertLongToLargeInteger(-30*10000);     KeDelayExecutionThread(KernelMode,FALSE,&delay);   }  #else   sleep(1);  #endif  old_lcr=u450_inb(port,UART_LCR);  u450_outb(port,UART_LCR,UART_LCR_SBC);  #ifdef FOR_LINUX_KERNEL   set_current_state(TASK_INTERRUPTIBLE);   schedule_timeout(ULD_HZ/10);  #elif defined(_WIN32)   /* !!!!!!!!!!!!!! */   /* KeStallExecutionProcessor(2000); */   { LARGE_INTEGER delay;     delay=RtlConvertLongToLargeInteger(-10*10000);     KeDelayExecutionThread(KernelMode,FALSE,&delay);   }  #else   sleep(1);  #endif  if(u450_inb(port,UART_MSR)&U450_MSR_TxD(udrv))  { u450_outb(port,UART_LCR,U450_LCR_UL);    LOG_PORTS("uLan u450_init : MCR test 1 OK\n");    #ifdef FOR_LINUX_KERNEL     set_current_state(TASK_INTERRUPTIBLE);     schedule_timeout(ULD_HZ/10);    #elif defined(_WIN32)     /* !!!!!!!!!!!!!! */     /* KeStallExecutionProcessor(2000); */     { LARGE_INTEGER delay;       delay=RtlConvertLongToLargeInteger(-10*10000);       KeDelayExecutionThread(KernelMode,FALSE,&delay);     }    #else     sleep(1);    #endif    if(!(u450_inb(port,UART_MSR)&U450_MSR_TxD(udrv)))    { LOG_PORTS("uLan u450_init : MCR test 2 OK\n");      udrv->chip_options=options;      udrv->baud_base=baudbase;     /* check and setup baud base oscilator frequency */      if(!udrv->baud_base){        udrv->baud_base=U450_BAUD_BASE_DEFAULT;      }      if(!baud) baud=19200;      udrv->baud_val=baud;      u=(udrv->baud_base+baud/2)/baud;      if (u>0xFFFF) u=0xFFFF;      udrv->baud_div=u;      udrv->port=port;      udrv->irq=irq;       udrv->fnc_recch=&u450_recch;      udrv->fnc_sndch=&u450_sndch;      udrv->fnc_wait=&u450_wait;      udrv->fnc_pool=&u450_pool;      udrv->fnc_connect=&u450_connect;      udrv->fnc_cctrl=&u450_cctrl;      UL_REL_IOS(port,8);      return 0;    };    LOG_PORTS("uLan u450_init : MCR test 2 Error\n");  };  u450_outb(port,UART_LCR,(uchar)old_lcr);  u450_outb(port,UART_MCR,(uchar)old_mcr);  LOG_PORTS("uLan u450_init : MCR test Error\n");  UL_REL_IOS(port,8);  return UL_RC_EPORT;};

⌨️ 快捷键说明

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