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

📄 usb-proto.c

📁 伟大的Contiki工程, 短小精悍 的操作系统, 学习编程不可不看
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Enable interrupt for control endpoint */  *AT91C_UDP_IER = AT91C_UDP_EP0;  notify_process(USB_EVENT_RESET);}struct USB_request_st usb_setup_buffer;static voidread_fifo0(unsigned char *buffer, unsigned int length){  unsigned int r;  for (r = 0; r < length; r++) {    *buffer++ = AT91C_UDP_FDR[0];  }}voidusb_ep0_int(){  unsigned int status;  status = AT91C_UDP_CSR[0];#if 0  printf("status: %08x\n", status);#endif  if (status & AT91C_UDP_STALLSENT) {    /* Acknowledge */    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],0, AT91C_UDP_STALLSENT);  }  if (status & AT91C_UDP_RXSETUP) {    usb_ctrl_send_pos = NULL; /* Cancel any pending control data				 transmission */    if (RXBYTECNT(status) == 8) {      read_fifo0((unsigned char*)&usb_setup_buffer, 8);          UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],			    ((usb_setup_buffer.bmRequestType & 0x80)			     ? AT91C_UDP_DIR : 0),			    AT91C_UDP_DIR);      usb_ctrl_data_len = 0;      if ((usb_setup_buffer.bmRequestType & 0x80) != 0	  || usb_setup_buffer.wLength == 0) {	usb_endpoint_events[0] |= USB_EP_EVENT_SETUP;	notify_process(USB_EVENT_EP(0));      } else {	if (usb_setup_buffer.wLength > MAX_CTRL_DATA) {	  /* stall */	  usb_error_stall();	} else {	  usb_flags |= USB_FLAG_RECEIVING_CTRL;	}      }    } else {      usb_error_stall();    }    /* Acknowledge SETUP */    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],0, AT91C_UDP_RXSETUP);  } else if (status & (AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_RX_DATA_BK0)) {    puts("IN");    if (usb_flags & USB_FLAG_RECEIVING_CTRL) {      unsigned int len;      unsigned int left = MAX_CTRL_DATA - usb_ctrl_data_len;      len = RXBYTECNT(status);      if (len > left) {	/* stall */	usb_error_stall();      } else {	unsigned char *buf_tmp = usb_ctrl_data_buffer + usb_ctrl_data_len;	usb_ctrl_data_len += len;	if (usb_ctrl_data_len == usb_setup_buffer.wLength	    || len < CTRL_EP_SIZE) {	  usb_flags &= ~USB_FLAG_RECEIVING_CTRL;	  usb_endpoint_events[0] |= USB_EP_EVENT_SETUP;	  notify_process(USB_EVENT_EP(0));	}	while(len-- > 0) *buf_tmp++ = AT91C_UDP_FDR[0];      }    } else {      if (RXBYTECNT(status) > 0) {	puts("Discarded input");      }    }    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],0,			  AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_RX_DATA_BK0);  }  if (status & AT91C_UDP_TXCOMP) {    /* puts("TX complete"); */    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],0, AT91C_UDP_TXCOMP);    if (usb_flags & USB_FLAG_ADDRESS_PENDING) {      *AT91C_UDP_FADDR = AT91C_UDP_FEN | LOW_BYTE(usb_setup_buffer.wValue);      *AT91C_UDP_GLBSTATE |= AT91C_UDP_FADDEN;      usb_flags &= ~USB_FLAG_ADDRESS_PENDING;      printf("Address changed: %d\n", *AT91C_UDP_FADDR & 0x7f);    } else {      if(usb_ctrl_send_pos) {	write_ctrl();      }    }  }}voidusb_epx_int(){  unsigned int ep_index;  /* Handle enabled interrupts */  unsigned int int_status = *AT91C_UDP_ISR & *AT91C_UDP_IMR;  for (ep_index = 0; ep_index < NUM_EP-1; ep_index++) {    volatile USBEndpoint *ep = &usb_endpoints[ep_index];    unsigned int ep_num = EP_HW_NUM(ep->addr);    unsigned int ep_mask;    if (ep->addr != 0) { /* skip if not configured */      ep_mask = 1<<ep_num;      if (int_status & ep_mask) {	unsigned int status;	status = AT91C_UDP_CSR[ep_num];#if 0	printf("EP %d status: %08x\n", ep->addr, status);#endif	if (status & AT91C_UDP_STALLSENT) {	  /* Acknowledge */	  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ep_num],0, AT91C_UDP_STALLSENT);	}	if (status & AT91C_UDP_TXCOMP) {	  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ep_num],0, AT91C_UDP_TXCOMP);	  ep->flags &= ~USB_EP_FLAGS_TRANSMITTING;	  if (ep->buf_len > 0) {	    write_buffered_endpoint(ep);	    /* Tell the application that there's more room in the buffer */	    usb_endpoint_events[ep_num] |= USB_EP_EVENT_IN;	    notify_process(USB_EVENT_EP(ep_num));	  }	}	if (status & (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1)) {	  unsigned char read_cnt;	  read_cnt = read_buffered_endpoint(ep);	  if (read_cnt == 0) {	    *AT91C_UDP_IDR = 1<<ep_num;	    ep->flags |= USB_EP_FLAGS_RECV_BLOCKED;	  } else {	    if (status & AT91C_UDP_RX_DATA_BK1) {	      /* Ping-pong */	      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ep_num],0,				    (ep->flags & USB_EP_FLAGS_BANK_1_RECV_NEXT)				    ? AT91C_UDP_RX_DATA_BK1				    : AT91C_UDP_RX_DATA_BK0);	      ep->flags ^= USB_EP_FLAGS_BANK_1_RECV_NEXT;	    } else {	      /* Ping-pong or single buffer */	      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ep_num],0,				  AT91C_UDP_RX_DATA_BK0);	      ep->flags |= USB_EP_FLAGS_BANK_1_RECV_NEXT;	    }	  }	  usb_endpoint_events[ep_num] |= USB_EP_EVENT_OUT;	  notify_process(ep_mask);	}      }    }  }}/* Clear usb events from non-interrupt code */voidusb_clear_events(unsigned events){  /* Disable allUSB events */  *AT91C_AIC_IDCR = (1 << AT91C_ID_UDP);  usb_events &= ~events;  /* Reenable interrupt */  *AT91C_AIC_IECR = (1 << AT91C_ID_UDP);}voidusb_clear_ep_events(unsigned int ep, unsigned int events){  /* Disable all USB events */  *AT91C_AIC_IDCR = (1 << AT91C_ID_UDP);  usb_endpoint_events[ep] &= ~events;  /* Reenable interrupt */  *AT91C_AIC_IECR = (1 << AT91C_ID_UDP);}voidusb_set_address(){  usb_flags |= USB_FLAG_ADDRESS_PENDING;  /* The actual setting of the address is done when the status packet     is sent. */}static voidsetup_endpoint(unsigned char addr,	       unsigned char *buffer, unsigned int buf_size,	       unsigned int type) {  volatile USBEndpoint *ep;  /* Check if the address points to an existing endpoint */  if (EP_INDEX(addr) >= (sizeof(usb_endpoints)/sizeof(usb_endpoints[0]))) {    return;  }  ep = &usb_endpoints[EP_INDEX(addr)];  ep->addr = addr;  ep->buf_size_mask = buf_size - 1;  ep->buffer = buffer;  ep->buf_len = 0;  ep->buf_pos = 0;  ep->status = 0;  *AT91C_UDP_IDR = 1<<EP_HW_NUM(addr);  {    unsigned int ep_num = EP_HW_NUM(addr);    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ep_num],			  type | AT91C_UDP_EPEDS,			  AT91C_UDP_EPTYPE | AT91C_UDP_EPEDS);          }  *AT91C_UDP_IER = 1<<EP_HW_NUM(addr);}voidusb_setup_bulk_endpoint(unsigned char addr,			unsigned char *buffer, unsigned int buf_size){  setup_endpoint(addr, buffer, buf_size,		 (addr & 0x80) ? AT91C_UDP_EPTYPE_BULK_IN		 :AT91C_UDP_EPTYPE_BULK_OUT);}voidusb_setup_interrupt_endpoint(unsigned char addr,			     unsigned char *buffer, unsigned int buf_size){  setup_endpoint(addr, buffer, buf_size,		 (addr & 0x80) ? AT91C_UDP_EPTYPE_INT_IN		 :AT91C_UDP_EPTYPE_INT_OUT);}voidusb_disable_endpoint(unsigned char addr){  /* Check if the address points to an existing endpoint */  if (EP_INDEX(addr) >= (sizeof(usb_endpoints)/sizeof(usb_endpoints[0]))) {    return;  }  *AT91C_UDP_IDR = 1<<EP_HW_NUM(addr);  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(addr)], 0, AT91C_UDP_EPEDS);  usb_endpoints[EP_INDEX(addr)].addr = 0;}static voidinit_ep(volatile USBEndpoint *ctxt){  ctxt->addr = 0;  ctxt->buf_size_mask = 0;  ctxt->buf_len = 0;  ctxt->buf_pos = 0;  ctxt->buffer = 0;  ctxt->status = 0;  ctxt->flags = 0;}voidusb_init_endpoints(){  unsigned int i;  for (i = 0; i < NUM_EP-1; i++) {    init_ep(&usb_endpoints[i]);  }}volatile USBEndpoint*usb_find_endpoint(unsigned char epaddr){  if (EP_INDEX(epaddr) >= NUM_EP - 1) return 0;  return &usb_endpoints[EP_INDEX(epaddr)];}voidusb_halt_endpoint(unsigned char ep_addr, unsigned int halt){  *AT91C_UDP_IDR = 1<<EP_HW_NUM(ep_addr);  if (halt) {    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep_addr)],			  AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);    usb_endpoints[EP_INDEX(ep_addr)].status |= 0x01;  } else {    *AT91C_UDP_RSTEP = 1<<EP_HW_NUM(ep_addr);    usb_endpoints[EP_INDEX(ep_addr)].status &= ~0x01;  }  *AT91C_UDP_IER = 1<<EP_HW_NUM(ep_addr);}

⌨️ 快捷键说明

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