void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uintptr_t context) { PIOS_Assert(epnum < NELEMENTS(usb_epout_table)); PIOS_Assert(cb); usb_epout_table[epnum].cb = cb; usb_epout_table[epnum].context = context; usb_epout_table[epnum].max_len = max_len; DCD_EP_Open(&pios_usb_otg_core_handle, epnum, max_len, USB_OTG_EP_INT); /* * FIXME do not hardcode endpoint type */ /* * Make sure we refuse OUT transactions until we explicitly * connect a receive buffer with PIOS_USBHOOK_EndpointRx(). * * Without this, the ST USB code will receive on this endpoint * and blindly write the data to a NULL pointer which will * have the side effect of placing the internal flash into an * errored state. Address 0x0000_0000 is aliased into internal * flash via the "Section 2.4 Boot configuration" BOOT0/1 pins. */ DCD_SetEPStatus(&pios_usb_otg_core_handle, epnum, USB_OTG_EP_RX_NAK); }
/********************************************************************************************************** *函 数 名: Usb_Send *功能说明: USB发送数据 *形 参: 发送数据缓冲区指针 数据长度 *返 回 值: 无 **********************************************************************************************************/ void Usb_Send(uint8_t *dataToSend, uint8_t length) { if(connectFlag) { DCD_EP_Tx(&USB_OTG_dev, 1, dataToSend, length); DCD_SetEPStatus(&USB_OTG_dev,1, USB_OTG_EP_TX_VALID); } errorCheckCnt = 0; }
static inline int usbd_cdc_Start_Rx(void *pdev) { /* USB_Rx_Buffer_length is used here to keep track of * available _contiguous_ buffer space in USB_Rx_Buffer. */ uint32_t USB_Rx_length; if (USB_Rx_Buffer_head >= USB_Rx_Buffer_tail) USB_Rx_Buffer_length = USB_RX_BUFFER_SIZE; USB_Rx_length = ring_space_contig(USB_Rx_Buffer_length, USB_Rx_Buffer_head, USB_Rx_Buffer_tail); if (USB_Rx_length < CDC_DATA_OUT_PACKET_SIZE) { USB_Rx_length = ring_space_wrapped(USB_Rx_Buffer_length, USB_Rx_Buffer_head, USB_Rx_Buffer_tail); if (USB_Rx_length < CDC_DATA_OUT_PACKET_SIZE) { if (USB_Rx_State) { USB_Rx_State = 0; DCD_SetEPStatus(pdev, CDC_OUT_EP, USB_OTG_EP_TX_NAK); } return 0; } USB_Rx_Buffer_length = USB_Rx_Buffer_head; USB_Rx_Buffer_head = 0; if (USB_Rx_Buffer_tail == USB_Rx_Buffer_length) USB_Rx_Buffer_tail = 0; } if (!USB_Rx_State) { USB_Rx_State = 1; DCD_SetEPStatus(pdev, CDC_OUT_EP, USB_OTG_EP_TX_VALID); } DCD_EP_PrepareRx(pdev, CDC_OUT_EP, USB_Rx_Buffer + USB_Rx_Buffer_head, CDC_DATA_OUT_PACKET_SIZE); return 1; }
static uint8_t PIOS_USBHOOK_CLASS_DataOut(void *pdev, uint8_t epnum) { /* Remove the direction bit so we can use this as an index */ uint8_t epnum_idx = epnum & 0x7F; if ((epnum_idx < NELEMENTS(usb_epout_table)) && usb_epout_table[epnum_idx].cb) { struct usb_ep_entry *ep = &(usb_epout_table[epnum_idx]); if (!ep->cb(ep->context, epnum_idx, ep->max_len)) { /* NOTE: use real endpoint number including direction bit */ DCD_SetEPStatus(pdev, epnum, USB_OTG_EP_RX_NAK); } } return USBD_OK; }