vsf_err_t stm32_usbd_ep_set_OUT_dbuffer(uint8_t idx) { uint16_t epsize = stm32_usbd_ep_get_OUT_epsize(idx); int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return VSFERR_FAIL; } idx = (uint8_t)index; if ((EP_Cfg_Ptr - epsize) < STM32_USBD_EP_NUM * 8) { return VSFERR_NOT_ENOUGH_RESOURCES; } EP_Cfg_Ptr -= epsize; SetEPDoubleBuff(idx); SetEPDblBuffAddr(idx, GetEPRxAddr(idx), EP_Cfg_Ptr); SetEPDblBuffCount(idx, EP_DBUF_OUT, epsize); ClearDTOG_RX(idx); ClearDTOG_TX(idx); ToggleDTOG_TX(idx); SetEPRxStatus(idx, EP_RX_VALID); SetEPTxStatus(idx, EP_TX_DIS); stm32_usbd_OUT_dbuffer[idx] = true; return VSFERR_NONE; }
vsf_err_t stm32_usbd_ep_read_OUT_buffer(uint8_t idx, uint8_t *buffer, uint16_t size) { int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return VSFERR_FAIL; } idx = (uint8_t)index; if (stm32_usbd_OUT_dbuffer[idx]) { if(GetENDPOINT(idx) & EP_DTOG_TX) { PMAToUserBufferCopy(buffer, GetEPDblBuf1Addr(idx), size); } else { PMAToUserBufferCopy(buffer, GetEPDblBuf0Addr(idx), size); } } else { PMAToUserBufferCopy(buffer, GetEPRxAddr(idx), size); } return VSFERR_NONE; }
/******************************************************************************* * Function Name : USB_SIL_Read * Description : Write a buffer of data to a selected endpoint. * Input : - bEpAddr: The address of the non control endpoint. * - pBufferPointer: The pointer to which will be saved the * received data buffer. * Output : None. * Return : Number of received data (in Bytes). *******************************************************************************/ uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer) { uint32_t DataLength = 0; #ifndef STM32F10X_CL /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); #else USB_OTG_EP *ep; /* Get the structure pointer of the selected Endpoint */ ep = PCD_GetOutEP(bEpAddr); /* Get the number of received data */ DataLength = ep->xfer_len; /* Use the PCD interface layer function to read the selected endpoint */ PCD_EP_Read (bEpAddr, pBufferPointer, DataLength); #endif /* STM32F10X_CL */ /* Return the number of received data */ return DataLength; }
/******************************************************************************* * Function Name : DataStageOut. * Description : Data stage of a Control Write Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageOut(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_rLength; save_rLength = pEPinfo->Usb_rLength; if (pEPinfo->CopyData && save_rLength) { uint8_t *Buffer; uint32_t Length; Length = pEPinfo->PacketSize; if (Length > save_rLength) Length = save_rLength; Buffer = (*pEPinfo->CopyData)(Length); pEPinfo->Usb_rLength -= Length; pEPinfo->Usb_rOffset += Length; PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); } if (pEPinfo->Usb_rLength != 0) { vSetEPRxStatus(EP_RX_VALID); // re-enable for next data reception SetEPTxCount(ENDP0, 0); vSetEPTxStatus(EP_TX_VALID); // Expect the host to abort the data OUT stage } // Set the next State if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) { pInformation->ControlState = OUT_DATA; } else { if (pEPinfo->Usb_rLength > 0) { pInformation->ControlState = LAST_OUT_DATA; } else if (pEPinfo->Usb_rLength == 0) { pInformation->ControlState = WAIT_STATUS_IN; USB_StatusIn(); } } }
/******************************************************************************* * Function Name : Setup0_Process * Description : Get the device request data and dispatch to individual process. * Input : None. * Output : None. * Return : Post0_Process. *******************************************************************************/ uint8_t Setup0_Process(void) { union { uint8_t* b; uint16_t* w; } pBuf; uint16_t offset = 1; pBuf.b = USB_PMAADDR + (uint8_t *)(GetEPRxAddr(ENDP0) * 2); // *2 for 32 bits addr if (pInformation->ControlState != PAUSE) { pInformation->USBbmRequestType = *pBuf.b++; // bmRequestType pInformation->USBbRequest = *pBuf.b++; // bRequest pBuf.w += offset; // word not accessed because of 32 bits addressing pInformation->USBwValue = ByteSwap(*pBuf.w++); // wValue pBuf.w += offset; // word not accessed because of 32 bits addressing pInformation->USBwIndex = ByteSwap(*pBuf.w++); // wIndex pBuf.w += offset; // word not accessed because of 32 bits addressing pInformation->USBwLength = *pBuf.w; // wLength } pInformation->ControlState = SETTING_UP; if (pInformation->USBwLength == 0) { // Setup with no data stage NoData_Setup0(); } else { // Setup with data stage Data_Setup0(); } return Post0_Process(); }
static void PIOS_USB_CDC_DATA_EP_OUT_Callback(void) { struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id; bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); PIOS_Assert(valid); uint32_t DataLength; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(usb_cdc_dev->cfg->data_rx_ep); if (DataLength > sizeof(usb_cdc_dev->rx_packet_buffer)) { usb_cdc_dev->rx_oversize++; DataLength = sizeof(usb_cdc_dev->rx_packet_buffer); } /* Use the memory interface function to read from the selected endpoint */ PMAToUserBufferCopy((uint8_t *) usb_cdc_dev->rx_packet_buffer, GetEPRxAddr(usb_cdc_dev->cfg->data_rx_ep), DataLength); if (!usb_cdc_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK); return; } uint16_t headroom; bool need_yield = false; uint16_t rc; rc = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context, usb_cdc_dev->rx_packet_buffer, DataLength, &headroom, &need_yield); if (rc < DataLength) { /* Lost bytes on rx */ usb_cdc_dev->rx_dropped += (DataLength - rc); } if (headroom >= sizeof(usb_cdc_dev->rx_packet_buffer)) { /* We have room for a maximum length message */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID); } else { /* Not enough room left for a message, apply backpressure */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK); } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
/******************************************************************************* * Function Name : DataStageOut. * Description : Data stage of a Control Write Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageOut(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_rLength; save_rLength = pEPinfo->Usb_rLength; if (pEPinfo->CopyDataOut && save_rLength) { uint8_t *Buffer; uint32_t Length; Length = pEPinfo->PacketSize; if (Length > save_rLength) { Length = save_rLength; } Buffer = (*pEPinfo->CopyDataOut)(Length); pEPinfo->Usb_rLength -= Length; pEPinfo->Usb_rOffset += Length; #ifdef STM32F10X_CL PCD_EP_Read(ENDP0, Buffer, Length); #else PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); #endif /* STM32F10X_CL */ } if (pEPinfo->Usb_rLength != 0) { vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ SetEPTxCount(ENDP0, 0); vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ } /* Set the next State*/ if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) { pInformation->ControlState = OUT_DATA; } else { if (pEPinfo->Usb_rLength > 0) { pInformation->ControlState = LAST_OUT_DATA; } else if (pEPinfo->Usb_rLength == 0) { pInformation->ControlState = WAIT_STATUS_IN; USB_StatusIn(); } } }
/******************************************************************************* * Function Name : USB_SIL_Read * Description : Write a buffer of data to a selected endpoint. * Input : - bEpAddr: The address of the non control endpoint. * - pBufferPointer: The pointer to which will be saved the * received data buffer. * Output : None. * Return : Number of received data (in Bytes). *******************************************************************************/ uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer) { uint32_t DataLength = 0; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); /* Return the number of received data */ return DataLength; }
PUBLIC uint32 HW_USB_Read(uint8 bEpAddr, uint8* pBufferPointer, bool SetValid) { uint32 DataLength = 0; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ HwUsbPMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); if(SetValid) SetEPRxValid(bEpAddr & 0x0F); return DataLength; }
/******************************************************************************* * Function Name : Setup0_Process * Description : Get the device request data and dispatch to individual process. * Input : None. * Output : None. * Return : Post0_Process. *******************************************************************************/ uint8_t Setup0_Process(void) { union { uint8_t* b; uint16_t* w; } pBuf; uint16_t offset = 1; pBuf.b = PMAAddr + (uint8_t *)(GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ if (pInformation->ControlState != PAUSE) { pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ pInformation->USBbRequest = *pBuf.b++; /* bRequest */ pBuf.w += offset; /* word not accessed because of 32 bits addressing */ pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ pBuf.w += offset; /* word not accessed because of 32 bits addressing */ pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ pBuf.w += offset; /* word not accessed because of 32 bits addressing */ pInformation->USBwLength = *pBuf.w; /* wLength */ } pInformation->ControlState = SETTING_UP; if (pInformation->USBwLength == 0) { /* Setup with no data stage */ NoData_Setup0(); } else { /* Setup with data stage */ Data_Setup0(); } return Post0_Process(); }
/** * EP1 OUT Callback Routine */ static void PIOS_USB_HID_EP_OUT_Callback(void) { struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id; bool valid = PIOS_USB_HID_validate(usb_hid_dev); PIOS_Assert(valid); uint32_t DataLength; /* Read received data (63 bytes) */ /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep); if (DataLength > sizeof(usb_hid_dev->rx_packet_buffer)) { DataLength = sizeof(usb_hid_dev->rx_packet_buffer); } /* Use the memory interface function to read from the selected endpoint */ PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer, GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep), DataLength); if (!usb_hid_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); return; } /* The first byte is report ID (not checked), the second byte is the valid data length */ uint16_t headroom; bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[1], sizeof(usb_hid_dev->rx_packet_buffer)-1, &headroom, &need_yield); #else (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[2], usb_hid_dev->rx_packet_buffer[1], &headroom, &need_yield); #endif #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1; #else uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2; #endif if (headroom >= max_payload_length) { /* We have room for a maximum length message */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID); } else { /* Not enough room left for a message, apply backpressure */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }