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

📄 ul_c450.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_c450.c	- chip driver for 16450  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************//*******************************************************************//* Chip driver for 16450 */#include "serial_reg.h"#define u450_inb(base,port)	 ul_inb(base+port*U450_BYTES_PER_REGS)#define u450_outb(base,port,val) ul_outb(base+port*U450_BYTES_PER_REGS,val)#define U450_MCR_IE_C	0x0D	/* receive */#define U450_MCR_OE_C	0x0E	/* transmit */#define U450_MCR_OEQ_C	0x02	/* transmit ? */#define U450_MSR_RxD_C	UART_MSR_CTS /* RxD line readback */#define U450_MSR_TxD_C	UART_MSR_DSR /* TxD line readback */#define U450_MSR_DTxD_C	UART_MSR_DDSR /* TxD line changed */#define U450_LCR_UL	0x3B	/* receive/transmit */#define U450_LCR_ULC	0x2B	/* transmit control character */#define U450_LCR_ULB	0x7B	/* transmit line break */#define U450_LSR_C	0x04	/* controll character received */#define U450_LSR_ERR	0x1A	/* error in receiver */#ifdef CONFIG_OC_UL_DRV_SYSLESS #define U450_FIX_RDI_GARBAGE(udrv,ret_code) \ do { if(ret_code==5) u450_inb(udrv->port,UART_RX); } while(0) #else /* CONFIG_OC_UL_DRV_SYSLESS */#define U450_FIX_RDI_GARBAGE(udrv,ret_code) do{;}while(0)#endif /* CONFIG_OC_UL_DRV_SYSLESS *//*Definitions to allow support converters with different pins routing*/#ifdef CONFIG_OC_UL_DRV_U450_VARPINS#define U450_CHOPT_MSRSWAP	0x2000#define U450_MCR_CODES chip_buff[4]#define U450_MSR_CODES chip_buff[5]#define U450_MCR_IE(udrv)	((uchar)(udrv->U450_MCR_CODES>>0))#define U450_MCR_OE(udrv)	((uchar)(udrv->U450_MCR_CODES>>8))#define U450_MCR_OEQ(udrv)	((uchar)(udrv->U450_MCR_CODES>>16))#define U450_MSR_RxD(udrv)	((uchar)(udrv->U450_MSR_CODES>>0))#define U450_MSR_TxD(udrv)	((uchar)(udrv->U450_MSR_CODES>>8))#define U450_MSR_DTxD(udrv)	((uchar)(udrv->U450_MSR_CODES>>16))#define U450_SET_MCR_CODES(udrv,ie,oe,oeq) \	(udrv->U450_MCR_CODES=(ie)<<0|(oe)<<8|(oeq)<<16)#define U450_SET_MSR_CODES(udrv,rxd,txd,dtxd) \	(udrv->U450_MSR_CODES=(rxd)<<0|(txd)<<8|(dtxd)<<16)#else /*CONFIG_OC_UL_DRV_U450_VARPINS*/#define U450_MCR_IE(udrv)	U450_MCR_IE_C#define U450_MCR_OE(udrv)	U450_MCR_OE_C#define U450_MCR_OEQ(udrv)	U450_MCR_OEQ_C#define U450_MSR_RxD(udrv)	U450_MSR_RxD_C#define U450_MSR_TxD(udrv)	U450_MSR_TxD_C#define U450_MSR_DTxD(udrv)	U450_MSR_DTxD_C#endif /*CONFIG_OC_UL_DRV_U450_VARPINS*//*** Test interrupt request state ***/int u450_pool(ul_drv *udrv){  unsigned u;  u=u450_inb(udrv->port,UART_IIR);  return (u&UART_IIR_NO_INT)?0:((u&UART_IIR_ID)|1);};/*** Wait end of transmit ***/int u450_weot(ul_drv *udrv, int ret_code){  int ret;  unsigned u;  uchar lsr_val;  uchar uc;  if(!udrv->chip_buff[0]||     !(u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv)))   {    UL_FRET;    u450_outb(udrv->port,UART_LCR,U450_LCR_UL);    return UL_RC_PROC;  };  u450_outb(udrv->port,UART_IER,UART_IER_RDI);  lsr_val=u450_inb(udrv->port,UART_LSR);  ret=UL_RC_WIRQ;  if(!(~lsr_val&(UART_LSR_THRE|UART_LSR_TEMT)))  {    LOG_CHIO(" TMI");//    ret=UL_RC_PROC; /* was commented out */  }  if(lsr_val&U450_LSR_ERR)     ret=UL_RC_EFRAME;	/* frame error */  if(lsr_val&UART_LSR_DR)  {    if((u=udrv->chip_buff[1])) udrv->chip_buff[1]=0;     else if((u=udrv->chip_buff[0])) udrv->chip_buff[0]=0;    uc=u450_inb(udrv->port,UART_RX);    if((u^uc)&0xff||!u)    {      LOG_CHIO(" TE%c!",u?'0':'1');      ret=UL_RC_EBADCHR;    }else{      LOG_CHIO(".");      if(ret>=0&&!udrv->chip_buff[0])	ret=UL_RC_PROC;    };   } else {    U450_FIX_RDI_GARBAGE(udrv,ret_code);  }  if(ret!=UL_RC_WIRQ)  {    u450_outb(udrv->port,UART_LCR,U450_LCR_UL);    UL_FRET;  };  LOG_CHIO(" weot ret %d ",ret);  return ret;};/*** Switch from receive to transmit ***/  int u450_sw_R2T_1(ul_drv *udrv, int ret_code);  int u450_sw_R2T_2(ul_drv *udrv, int ret_code);  int u450_sw_R2T_3(ul_drv *udrv, int ret_code);int u450_sw_R2T(ul_drv *udrv, int ret_code){  udrv->chip_buff[0]=udrv->chip_buff[1]=0; /* A_wait */  UL_FCALL2(u450_weot,u450_sw_R2T_1);  return UL_RC_PROC;};int u450_sw_R2T_1(ul_drv *udrv, int ret_code){  uchar uc;  if(ret_code<0) {UL_FRET;return ret_code;};  u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv));  u450_outb(udrv->port,UART_IER,UART_IER_THRI);  u450_outb(udrv->port,UART_TX,0);  UL_FNEXT(u450_sw_R2T_2);  uc=u450_inb(udrv->port,UART_LSR);  if(uc&UART_LSR_THRE) return UL_RC_PROC;    else return UL_RC_WIRQ;}; int u450_sw_R2T_2(ul_drv *udrv, int ret_code){  uchar uc, uc1; /* A_wait1: */  uc=u450_inb(udrv->port,UART_MSR); /* Need to be disabled for LPC210x */  if(uc&U450_MSR_TxD(udrv))    udrv->chip_temp&=~0x400;  else    udrv->chip_temp|=0x400;  u450_outb(udrv->port,UART_IER,UART_IER_MSI);  uc1=u450_inb(udrv->port,UART_LSR);  if (!(~uc1&(UART_LSR_TEMT|UART_LSR_THRE))) {    UL_FRET;    return UL_RC_PROC;  } #ifdef CONFIG_OC_UL_DRV_SYSLESS  /* The next code seems to be required for LPC2148 UART */  if((!(uc&U450_MSR_TxD(udrv)))&&(uc1&UART_LSR_THRE)) {    UL_FRET;    return UL_RC_PROC;  } #endif /*CONFIG_OC_UL_DRV_SYSLESS*/  UL_FNEXT(u450_sw_R2T_3);  return UL_RC_WIRQ;}; int u450_sw_R2T_3(ul_drv *udrv, int ret_code){  uchar uc; #if 0  static int reported_bad_chip=0; #endif /* A_wait2: */  uc=u450_inb(udrv->port,UART_MSR);  if(uc&U450_MSR_DTxD(udrv))    udrv->chip_temp&=~0x400;  if((uc&U450_MSR_TxD(udrv))&&(udrv->chip_temp&0x400))    return UL_RC_WIRQ; #if 0  while(~u450_inb(udrv->port,UART_LSR)&	(UART_LSR_TEMT|UART_LSR_THRE))   if(!reported_bad_chip++)     LOG_FATAL(KERN_CRIT "uLan u450_sw_R2T_3 : problematic IC => looping in ISR\n"); #endif  UL_FRET;  return UL_RC_PROC;}; /*** Receive character into char_buff ***/  int u450_recch_1(ul_drv *udrv, int ret_code);  int u450_recch_2(ul_drv *udrv, int ret_code);int u450_recch(ul_drv *udrv, int ret_code){  udrv->char_buff=0;  if(u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv))  {    UL_FCALL2(u450_weot,u450_recch_1);    return UL_RC_PROC;  };  UL_FNEXT(u450_recch_2);  return UL_RC_PROC;}; int u450_recch_1(ul_drv *udrv, int ret_code){  u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv));  if(ret_code<0) {UL_FRET;return ret_code;};  UL_FNEXT(u450_recch_2);  return UL_RC_PROC;};INLINE int u450_recch_sub(ul_drv *udrv,int lsr_val,int rec_char){ /* helper function to process received character */  if(lsr_val&U450_LSR_C) udrv->last_ctrl=rec_char|=0x100;    else udrv->last_ctrl&=0x7F;   udrv->char_buff=rec_char;  udrv->xor_sum^=rec_char;udrv->xor_sum++;  if(lsr_val&U450_LSR_ERR)  {    LOG_CHIO(" ER:%03X",udrv->char_buff);    return UL_RC_EFRAME; /* frame error */  };  LOG_CHIO(" R:%03X",udrv->char_buff);  return UL_RC_PROC;}; int u450_recch_2(ul_drv *udrv, int ret_code){  uchar lsr_val;  u450_outb(udrv->port,UART_IER,UART_IER_RDI);  lsr_val=u450_inb(udrv->port,UART_LSR);  if(!(lsr_val&UART_LSR_DR)) {    U450_FIX_RDI_GARBAGE(udrv,ret_code);    return UL_RC_WIRQ;  }   UL_FRET;  return u450_recch_sub(udrv,lsr_val,u450_inb(udrv->port,UART_RX));};/*** Send character from char_buff ***/  int u450_sndch_1(ul_drv *udrv, int ret_code);  int u450_sndch_2(ul_drv *udrv, int ret_code);int u450_sndch(ul_drv *udrv, int ret_code){  uchar uc;  uc=(udrv->char_buff&0x100)?U450_LCR_ULC:U450_LCR_UL;  if(u450_inb(udrv->port,UART_LCR)!=uc)  { /* change between control and data character format */   if((u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv)))   { /* wait to end of transmit */     UL_FCALL2(u450_weot,u450_sndch_1);     return UL_RC_PROC;   }else{ /* direction switch necessary */     udrv->chip_buff[0]=udrv->chip_buff[1]=0;     UL_FCALL2(u450_sw_R2T_1,u450_sndch_1);     UL_FCALL2(u450_weot,u450_sw_R2T_1);     return UL_RC_PROC;   };  };  if(!(u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv)))  { /* direction switch necessary */    udrv->chip_buff[0]=udrv->chip_buff[1]=0;    UL_FCALL2(u450_sw_R2T_1,u450_sndch_1);    UL_FCALL2(u450_weot,u450_sw_R2T_1);  } else UL_FNEXT(u450_sndch_1);  return UL_RC_PROC;};int u450_sndch_1(ul_drv *udrv, int ret_code){  uchar uc;  if(ret_code<0) {UL_FRET;return ret_code;};  u450_outb(udrv->port,UART_MCR,U450_MCR_OE(udrv));  if(udrv->char_buff&0x100)  { /* store last ctrl for connect line busy/ready */    udrv->last_ctrl=udrv->char_buff;    uc=U450_LCR_ULC;  }else{     uc=U450_LCR_UL;  };  udrv->chip_buff[1]=udrv->chip_buff[0];  udrv->chip_buff[0]=udrv->char_buff|0x1000;   udrv->xor_sum^=udrv->char_buff;udrv->xor_sum++;  u450_outb(udrv->port,UART_IER,UART_IER_THRI);  u450_outb(udrv->port,UART_LCR,uc);  /* control/data character */  u450_outb(udrv->port,UART_TX,(uchar)udrv->char_buff);  LOG_CHIO(" T:%03X",udrv->char_buff);  UL_FNEXT(u450_sndch_2);  return UL_RC_WIRQ;}; int u450_sndch_2(ul_drv *udrv, int ret_code){  uchar uc;  unsigned u;  uc=u450_inb(udrv->port,UART_LSR);  UL_FRET;  if(uc&U450_LSR_ERR)      return UL_RC_EFRAME;	/* frame error */  if(!(uc&UART_LSR_DR)) {      U450_FIX_RDI_GARBAGE(udrv,ret_code);      return UL_RC_PROC;		/* no char */   }  if((u=udrv->chip_buff[1])) udrv->chip_buff[1]=0;    else if((u=udrv->chip_buff[0])) udrv->chip_buff[0]=0;      else return UL_RC_PROC;  uc=u450_inb(udrv->port,UART_RX);  if((u^uc)&0xff||!u)  {    LOG_CHIO(" TE%c!",u?'2':'3');    return UL_RC_EBADCHR;  };  LOG_CHIO(".");  return UL_RC_PROC;}; /*** Wait for time or received character ***/  int u450_wait_1(ul_drv *udrv, int ret_code);  int u450_wait_2(ul_drv *udrv, int ret_code);int u450_wait(ul_drv *udrv, int ret_code){  udrv->char_buff=0;

⌨️ 快捷键说明

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