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

📄 ul_cps1.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_cps1.c	- chip driver for USB2uLan device developed                  by Petr Smolik  (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. *******************************************************************//*******************************************************************//* usb2ulan device requests */#define U2U_PKT_BUF_SIZE       32     /* driver maximal supported packed size */#define U2U_MAX_MSG_INPR        4     /* maximal number of messages in progress */#define VENDOR_START_ULAN       0     /* Inform converter about uLan driver ready */#define VENDOR_STOP_ULAN        1     /* Inform about uLan driver stopping  */#define VENDOR_IS_RUNNING_ULAN  2#define VENDOR_ARC_ON_ULAN      3     /* Set promiscuous monitoring mode */#define VENDOR_ARC_OFF_ULAN     4     /* Return to std. adress recognition mode */#define U2UBFL_NORE     0x040         /* Do not try to repeat if error occurs */ #define U2UBFL_TAIL     0x020         /* Message has tail frame */#define U2UBFL_REC      0x010         /* Request receiption of block */#define U2UBFL_FAIL     0x008         /* Message cannot be send - error */#define U2UBFL_PROC	0x004         /* Message succesfull send */#define U2UBFL_AAP	0x003         /* Request imediate proccessing of frame by receiver station with acknowledge */#define U2UBFL_PRQ	0x002         /* Request imediate proccessing of frame by receiver station */#define U2UBFL_ARQ	0x001         /* Request imediate acknowledge by receiving station *//* Definition of chip_buff usage */#define ul_usb_in_urb_st chip_buff[0] /* completion status of  ?_complete_in */#define ul_usb_max_pkt_size chip_buff[1] /* maximal USB packet size */#define ul_usb_max_msg_inpr chip_buff[2] /* maximal number of messages in progress */#define ul_usb_outpipe_nr   chip_buff[3] /* OUT pipe number */#define ul_usb_inpipe_nr    chip_buff[4] /* IN pipe number */#ifdef FOR_LINUX_KERNEL#if (LINUX_VERSION_CODE <= VERSION(2,4,10))  #define usb_fill_bulk_urb FILL_BULK_URB#endif#if (LINUX_VERSION_CODE < VERSION(2,5,0))  #define kc_usb_alloc_urb(urb, gfp) usb_alloc_urb(urb)   #define kc_usb_submit_urb(urb, gfp) usb_submit_urb(urb) #else  #define kc_usb_alloc_urb usb_alloc_urb  #define kc_usb_submit_urb usb_submit_urb#endif#endif /*FOR_LINUX_KERNEL*/#ifdef _WIN32int ul_usb_msg_inpr=0;	/* number of concurrent messages sent over USB */#elseextern int ul_usb_msg_inpr;	/* number of concurrent messages sent over USB */#endif /* _WIN32 *//* Support for multiple submitted messages */typedef struct ul_usb_tx_fifo_slot{  ul_mem_blk    *msg;  unsigned char ustamp;}ul_usb_tx_fifo_slot;typedef struct ul_usb_tx_fifo{  ul_usb_tx_fifo_slot slot[U2U_MAX_MSG_INPR];  int size;  int used;  int idxin;  int idxout;}ul_usb_tx_fifo;static int ul_usb_tx_fifo_empty(const ul_usb_tx_fifo *fifo){  return fifo->slot[fifo->idxout].msg==NULL;}static int ul_usb_tx_fifo_full(const ul_usb_tx_fifo *fifo){  return fifo->slot[fifo->idxin].msg!=NULL;}static int ul_usb_tx_fifo_incidx(const ul_usb_tx_fifo *fifo, int idx){  if(++idx>=fifo->size) idx=0;  return idx;}static void ul_usb_tx_fifo_print(const ul_usb_tx_fifo *fifo){  int i;  LOG_MESSAGES("ul_usb: tx_fifo: idxin=%d idxout=%d [",            fifo->idxin,fifo->idxout);  for(i=0;i<fifo->size;i++){    if(i) LOG_MESSAGES(",");    if(!fifo->slot[i].msg){      LOG_MESSAGES("Empty");    }else{      LOG_MESSAGES("%d",fifo->slot[i].ustamp);    }  }  LOG_MESSAGES("]\n");}/*** Input completion for Petr Smolik's USB2uLan converter ***/#ifdef FOR_LINUX_KERNEL#if (LINUX_VERSION_CODE >= VERSION(2,6,0))  void ul_usb_ps1_complete_in(struct urb *urb,struct pt_regs *regs)#else  void ul_usb_ps1_complete_in(struct urb *urb)#endif#else /*FOR_LINUX_KERNEL*/  NTSTATUS ul_usb_ps1_complete_in( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)#endif /*FOR_LINUX_KERNEL*/{  ul_drv *udrv;  int st;    #ifdef FOR_LINUX_KERNEL    udrv=urb->context;  #else /*FOR_LINUX_KERNEL*/    udrv=(ul_drv*)Context;  #endif /*FOR_LINUX_KERNEL*/  if(udrv->magic!=UL_DRV_MAGIC){    LOG_FATAL(KERN_CRIT "ul_usb_ps1_complete_in: Wrong uLan MAGIC number!!!\n");    #ifdef _WIN32      return STATUS_INVALID_PARAMETER;    #else /* _WIN32 */      return;    #endif /* _WIN32 */  }  #ifdef FOR_LINUX_KERNEL  if(urb->status<0)     st=16-urb->status;   else st=2;  #else    st=2;  #endif  LOG_IRQ(KERN_CRIT "ul_usb_ps1_complete_in\n");  UL_MB();  udrv->ul_usb_in_urb_st=st;  uld_kwt_wake(udrv);    #ifdef _WIN32      return STATUS_SUCCESS;  #endif /* _WIN32 */}/*** Send one frame to USB2uLan converter ***/int ul_usb_ps1_send_frame(ul_drv *udrv, ul_mem_blk *frame,                           unsigned char ustamp){  unsigned char buf[U2U_PKT_BUF_SIZE];  int i, len, ret;  ul_data_it di;  struct usb_device *dev=(struct usb_device *)udrv->dev;    int max_pkt=udrv->ul_usb_max_pkt_size;  buf[0]=UL_BLK_HEAD(frame).dadr;  buf[1]=UL_BLK_HEAD(frame).sadr;  buf[2]=UL_BLK_HEAD(frame).cmd;  i=UL_BLK_HEAD(frame).flg; buf[3]=0;  if(i&UL_BFL_ARQ) buf[3]|=U2UBFL_ARQ;  if(i&UL_BFL_PRQ) buf[3]|=U2UBFL_PRQ;  if(i&UL_BFL_NORE) buf[3]|=U2UBFL_NORE;  if(i&UL_BFL_TAIL) buf[3]|=U2UBFL_TAIL;  if(i&UL_BFL_REC) buf[3]|=U2UBFL_REC;  buf[4]=ustamp;  buf[5]=0;  len=UL_BLK_HEAD(frame).len;  if(i&UL_BFL_REC){	/* Placeholder message for receive does not */    len=0;		/* need data, but should check UL_BFL_LNMM !!! */  }  buf[6]=(unsigned char)len; buf[7]=(unsigned char)(len/0x100);  LOG_IRQ(KERN_CRIT "ul_usb : sending head URB (d:%d,s:%d,c:%X,f:%X,l:%d) stmp %d\n",               buf[0],buf[1],buf[2],buf[3],               buf[6]+0x100*buf[7],buf[4]);  ret=usb_bulk_msg(dev, usb_sndbulkpipe(dev, udrv->ul_usb_outpipe_nr), buf, 8, &i, ULD_HZ);  if(ret<0) {    LOG_FATAL(KERN_CRIT "ul_usb_ps1_send_frame: usb_bulk_write head error %d returned\n",ret);    return ret;  }  ul_di_init(&di,frame);  while(len>0) {    i=len<max_pkt?len:max_pkt; len-=i;    ul_di_read(&di, buf, i);    ret=usb_bulk_msg(dev, usb_sndbulkpipe(dev, udrv->ul_usb_outpipe_nr), buf, i, &i, ULD_HZ);    if(ret<0) {      LOG_FATAL(KERN_CRIT "ul_usb_ps1_send_frame: usb_bulk_write data error %d returned\n",ret);      return ret;    }  }  return di.pos;}/*** Receive data of one frame from USB2uLan converter ***/int ul_usb_ps1_receive_data(ul_drv *udrv, ul_mem_blk *frame, int len){  unsigned char buf[U2U_PKT_BUF_SIZE];  int i, ret;  ul_data_it di;  struct usb_device *dev=(struct usb_device *)udrv->dev;  int max_pkt=udrv->ul_usb_max_pkt_size;    ul_di_init(&di,frame);  while(len>0) {    i=len<max_pkt?len:max_pkt; len-=i;    ret=usb_bulk_msg(dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr), buf, i, &i, ULD_HZ);    if(ret<0) {      LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: usb_bulk_read data error %d returned\n",ret);      return ret;      break;    } else {      if(i!=ul_di_write(&di, buf, i)){        #ifdef FOR_LINUX_KERNEL	  return -EIO;        #else          return -1;        #endif /* FOR_LINUX_KERNEL */      }    }  }  return di.pos;}/*** Worker thread for Petr Smolik's USB2uLan converter ***/int ul_usb_ps1_thread(void *ptr){  ul_drv *udrv=(ul_drv *)ptr;  struct usb_device *dev;  int ret;  int i, len;  int fatal_err=0;  volatile unsigned char in_buf[8];  unsigned char u2u_ret[2];  unsigned char ustamp=0;  ul_mem_blk *tx_mes=NULL;  ul_mem_blk *rx_mes=NULL;  ul_mem_blk *frame;  ul_mem_blk *tail_frame=NULL;  long tx_sta_time;  ul_usb_tx_fifo tx_fifo;  #ifdef FOR_LINUX_KERNEL    struct urb *in_urb;  #else    PURB in_urb=NULL;    PIRP in_irp=NULL;  #endif /* FOR_LINUX_KERNEL */  volatile unsigned in_urb_st;  if(udrv->magic!=UL_DRV_MAGIC)  {    LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: Wrong uLan MAGIC number!!!\n");    uld_kwt_set_stopped(udrv);    return -ENODEV;  }  dev=(struct usb_device *)udrv->dev;  if(udrv->ul_usb_max_pkt_size>U2U_PKT_BUF_SIZE)    udrv->ul_usb_max_pkt_size=U2U_PKT_BUF_SIZE;  if(udrv->ul_usb_max_msg_inpr>U2U_MAX_MSG_INPR)    udrv->ul_usb_max_msg_inpr=U2U_MAX_MSG_INPR;  memset(&tx_fifo,0,sizeof(tx_fifo));  tx_fifo.size=udrv->ul_usb_max_msg_inpr;#ifdef FOR_LINUX_KERNEL#if (LINUX_VERSION_CODE >= VERSION(2,6,0))  daemonize("kulusbps1d");  /*allow_signal(SIGKILL);*/#else /* <2.6.0 */  lock_kernel();  daemonize(); #if (LINUX_VERSION_CODE >= VERSION(2,4,10))  exit_files(current);  current->files = init_task.files;  atomic_inc(&current->files->count);  daemonize();  reparent_to_init(); #endif /* >=2.4.10 */  /* avoid getting signals */  spin_lock_irq(&current->sigmask_lock);  flush_signals(current);  sigfillset(&current->blocked);  recalc_sigpending(current);  spin_unlock_irq(&current->sigmask_lock);  set_fs(KERNEL_DS);  strcpy(current->comm, "kulusbps1d");  unlock_kernel();#endif /* <2.6.0 */#endif /*FOR_LINUX_KERNEL*/  if(udrv->baud_val)    udrv->baud_div=(udrv->baud_base+udrv->baud_val/2)/udrv->baud_val;  /* Set converter parameters */  ret=usb_control_msg(dev, usb_rcvctrlpipe(dev,0),                       VENDOR_START_ULAN, USB_TYPE_VENDOR,                      /*value*/ (short)udrv->baud_val, /*index*/ (short)udrv->my_adr, u2u_ret, 1, 2*ULD_HZ);    if(ret<0) {    LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: KWT usb_control_msg error %d returned\n",ret);    fatal_err=1;  }  if(!u2u_ret[0]) {    LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: not supported baudrate (%d)\n",udrv->baud_val);    fatal_err=1;  }   #ifdef FOR_LINUX_KERNEL    if((in_urb=kc_usb_alloc_urb(0, GFP_KERNEL))) {      /* URB allocated OK */    }else{      LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: KWT cannot alloc in_urb\n");      fatal_err=1;    }  #else    in_urb = MALLOC(sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));    if ( !in_urb) {      LOG_FATAL(KERN_CRIT "ul_usb_ps1_thread: KWT cannot alloc in_urb\n");      fatal_err=1;    }  #endif /* FOR_LINUX_KERNEL */  usb_clear_halt(dev, usb_sndbulkpipe(dev, udrv->ul_usb_outpipe_nr));  usb_clear_halt(dev, usb_rcvbulkpipe(dev, udrv->ul_usb_inpipe_nr));  udrv->ul_usb_in_urb_st=0;

⌨️ 快捷键说明

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