int usbSendBytes(uchar *data,int size) { if(size==0) wait_us(140); // 0byte packet対策. /* Last transmission hasn't finished, abort */ if (countTx) { return 0; } if( GetEPTxStatus(ENDP1) == EP_TX_VALID) return 0; if( size >= MAX_SEND_BYTES_CDC) { size = MAX_SEND_BYTES_CDC; } UserToPMABufferCopy(data, ENDP1_TXADDR, size); SetEPTxCount(ENDP1, size); countTx += size; if(size==0) countTx++; // 0byte packet対策. SetEPTxValid(ENDP1); if(size==0) wait_us(140); // 0byte packet対策. return size; }
/******************************************************************************* * Function Name : Standard_SetEndPointFeature * Description : Set or enable a specific feature of EndPoint * Input : None. * Output : None. * Return : - Return USB_SUCCESS, if the request is performed. * - Return USB_UNSUPPORT, if the request is invalid. *******************************************************************************/ RESULT Standard_SetEndPointFeature(void) { uint32_t wIndex0 = pInformation->USBwIndex0; uint32_t rEP = wIndex0 & ~0x80; uint32_t Related_Endpoint = ENDP0 + rEP; uint32_t Status; if (ValBit(pInformation->USBwIndex0,7)) { // get Status of endpoint & stall the request if the related_ENdpoint is Disabled Status = GetEPTxStatus(Related_Endpoint); } else { Status = GetEPRxStatus(Related_Endpoint); } if (Related_Endpoint >= Device_Table.Total_Endpoint || pInformation->USBwValue != 0 || Status == 0 || pInformation->Current_Configuration == 0) { return USB_UNSUPPORT; } else { if (wIndex0 & 0x80) { // IN endpoint SetEPTxStatus(Related_Endpoint, EP_TX_STALL); } else { // OUT endpoint SetEPRxStatus(Related_Endpoint, EP_RX_STALL); } } pUser_Standard_Requests->User_SetEndPointFeature(); return USB_SUCCESS; }
uint32_t DCD_GetEPStatus(USB_CORE_HANDLE *pdev ,uint8_t epnum) { uint16_t Status=0; USB_EP *ep; if ((0x80 & epnum) == 0x80) { ep = &pdev->dev.in_ep[epnum & 0x7F]; } else { ep = &pdev->dev.out_ep[epnum]; } if (ep->is_in) { Status = GetEPTxStatus(ep->num); } else { Status = GetEPRxStatus(ep->num); } return Status; }
/******************************************************************************* * Function Name : Standard_ClearFeature. * Description : Clear or disable a specific feature. * Input : None. * Output : None. * Return : - Return USB_SUCCESS, if the request is performed. * - Return USB_UNSUPPORT, if the request is invalid. *******************************************************************************/ RESULT Standard_ClearFeature(void) { uint32_t Type_Rec = Type_Recipient; uint32_t Status; if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { // Device Clear Feature ClrBit(pInformation->Current_Feature, 5); return USB_SUCCESS; } else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { // EndPoint Clear Feature DEVICE* pDev; uint32_t Related_Endpoint; uint32_t wIndex0; uint32_t rEP; if ((pInformation->USBwValue != ENDPOINT_STALL) || (pInformation->USBwIndex1 != 0)) { return USB_UNSUPPORT; } pDev = &Device_Table; wIndex0 = pInformation->USBwIndex0; rEP = wIndex0 & ~0x80; Related_Endpoint = ENDP0 + rEP; if (ValBit(pInformation->USBwIndex0, 7)) { // Get Status of endpoint & stall the request if the related_ENdpoint is Disabled Status = GetEPTxStatus(Related_Endpoint); } else { Status = GetEPRxStatus(Related_Endpoint); } if ((rEP >= pDev->Total_Endpoint) || (Status == 0) || (pInformation->Current_Configuration == 0)) { return USB_UNSUPPORT; } if (wIndex0 & 0x80) { // IN endpoint if (GetTxStallStatus(Related_Endpoint )) { ClearDTOG_TX(Related_Endpoint); SetEPTxStatus(Related_Endpoint, EP_TX_VALID); } } else { // OUT endpoint if (GetRxStallStatus(Related_Endpoint)) { if (Related_Endpoint == ENDP0) { // After clear the STALL, enable the default endpoint receiver SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); SetEPRxStatus(Related_Endpoint, EP_RX_VALID); } else { ClearDTOG_RX(Related_Endpoint); SetEPRxStatus(Related_Endpoint, EP_RX_VALID); } } } pUser_Standard_Requests->User_ClearFeature(); return USB_SUCCESS; } return USB_UNSUPPORT; }
void Handle_USBAsynchXfer (void) { if( GetEPTxStatus(ENDP1) == EP_TX_VALID) return; int Recv_Size = USART_RecvData(Recv_Buffer); if( Recv_Size ) { UserToPMABufferCopy(Recv_Buffer, ENDP1_TXADDR, Recv_Size); SetEPTxCount(ENDP1, Recv_Size); SetEPTxValid(ENDP1); } }
void PIOS_USB_RCTX_Update(uint32_t usbrctx_id, const uint16_t channel[], const int16_t channel_min[], const int16_t channel_max[], uint8_t num_channels) { struct pios_usb_rctx_dev *usb_rctx_dev = (struct pios_usb_rctx_dev *)usbrctx_id; bool valid = PIOS_USB_RCTX_validate(usb_rctx_dev); PIOS_Assert(valid); if (!PIOS_USB_CheckAvailable(usb_rctx_dev->lower_id)) { return; } for (uint8_t i = 0; i < PIOS_USB_RCTX_NUM_CHANNELS && i < num_channels; i++) { int16_t min = channel_min[i]; int16_t max = channel_max[i]; uint16_t val = channel[i]; if (channel_min[i] > channel_max[i]) { /* This channel is reversed, flip min and max */ min = channel_max[i]; max = channel_min[i]; /* and flip val to be an offset from the lower end of the range */ val = channel_min[i] - channel[i] + channel_max[i]; } /* Scale channel linearly between min and max */ if (min == max) { val = 0; } else { if (val < min) { val = min; } if (val > max) { val = max; } val = (val - min) * (65535 / (max - min)); } usb_rctx_dev->report.vals[i] = val; } if (GetEPTxStatus(usb_rctx_dev->cfg->data_tx_ep) == EP_TX_VALID) { /* Endpoint is already transmitting */ return; } PIOS_USB_RCTX_SendReport(usb_rctx_dev); }
bool stm32_usbd_ep_is_IN_stall(uint8_t idx) { int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return false; } idx = (uint8_t)index; return (EP_TX_STALL == GetEPTxStatus(idx)); }
static char* parse_command(char *cmd) { int response_size; int pos = 0; do { char *next = (char*)strchr(cmd, '\n'); if (next) next[0] = 0; if (NULL == cmd[0]) break; response_size = parse_command_line(cmd, response); response[response_size] = NULL; /* Write the data to the USB endpoint */ //printf("cmd:%s, response: %s(%d byte)\n", cmd, response, response_size); if (response_size > 128) { //response[0] = '\n'; //response_size = 1; //printf("oops(avg=%d):%s\n", avg_count, response); } while(pos < response_size) { USB_SIL_Write(EP1_IN, (uint8_t*)response + pos, min(response_size - pos, tx_packet_size)); pos += tx_packet_size; #ifndef STM32F10X_CL SetEPTxValid(ENDP1); #endif /* STM32F10X_CL */ while (GetEPTxStatus(ENDP1) == EP_TX_VALID); } if (!next) break; cmd = next+1; }while (1); return cmd; }
// // 仮想COMポートからのデータをPC側に返送する. // void EP1_IN_Callback (void) { #if 0 if( GetEPTxStatus(ENDP1) == EP_TX_VALID) return; int Recv_Size = USART_RecvData(Recv_Buffer); if( Recv_Size ) { UserToPMABufferCopy(Recv_Buffer, ENDP1_TXADDR, Recv_Size); SetEPTxCount(ENDP1, Recv_Size); SetEPTxValid(ENDP1); } #if LED_DEBUG led2_blink(0); #endif #endif countTx = 0; }
static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail) { struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); PIOS_Assert(valid); if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) { return; } if (GetEPTxStatus(usb_cdc_dev->cfg->data_tx_ep) == EP_TX_VALID) { /* Endpoint is already transmitting */ return; } PIOS_USB_CDC_SendData(usb_cdc_dev); }
void usbIface::writeBytes( void ) { uint8_t byte; uint8_t buf[64]; uint8_t cnt = 0; if(!(GetEPTxStatus(ENDP1)==EP_TX_VALID)) { while ( !m_out->isempty() && cnt < 64 ) { m_out->dequeue( &byte ); buf[cnt] = byte; cnt++; } CDC_Send_DATA(buf, cnt); } /* if(!(GetEPTxStatus(ENDP1)==EP_TX_VALID) && !m_out->isempty()) { m_out->dequeue( &byte ); // Not checking for errors this is bad CDC_Send_DATA(&byte, 1); } */ }
/******************************************************************************* * Function Name : Data_Setup0. * Description : Proceed the processing of setup request with data stage. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Data_Setup0(void) { uint8_t *(*CopyRoutine)(uint16_t); RESULT Result; uint32_t Request_No = pInformation->USBbRequest; uint32_t Related_Endpoint, Reserved; uint32_t wOffset, Status; CopyRoutine = NULL; wOffset = 0; /*GET DESCRIPTOR*/ if (Request_No == GET_DESCRIPTOR) { if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { uint8_t wValue1 = pInformation->USBwValue1; if (wValue1 == DEVICE_DESCRIPTOR) { CopyRoutine = pProperty->GetDeviceDescriptor; } else if (wValue1 == CONFIG_DESCRIPTOR) { CopyRoutine = pProperty->GetConfigDescriptor; } else if (wValue1 == STRING_DESCRIPTOR) { CopyRoutine = pProperty->GetStringDescriptor; } /* End of GET_DESCRIPTOR */ } } /*GET STATUS*/ else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) && (pInformation->USBwLength == 0x0002) && (pInformation->USBwIndex1 == 0)) { /* GET STATUS for Device*/ if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) && (pInformation->USBwIndex == 0)) { CopyRoutine = Standard_GetStatus; } /* GET STATUS for Interface*/ else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) { if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) && (pInformation->Current_Configuration != 0)) { CopyRoutine = Standard_GetStatus; } } /* GET STATUS for EndPoint*/ else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); Reserved = pInformation->USBwIndex0 & 0x70; if (ValBit(pInformation->USBwIndex0, 7)) { /*Get Status of endpoint & stall the request if the related_ENdpoint is Disabled*/ Status = GetEPTxStatus(Related_Endpoint); } else { Status = GetEPRxStatus(Related_Endpoint); } if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) && (Status != 0)) { CopyRoutine = Standard_GetStatus; } } } /*GET CONFIGURATION*/ else if (Request_No == GET_CONFIGURATION) { if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { CopyRoutine = Standard_GetConfiguration; } } /*GET INTERFACE*/ else if (Request_No == GET_INTERFACE) { if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) { CopyRoutine = Standard_GetInterface; } } if (CopyRoutine) { pInformation->Ctrl_Info.Usb_wOffset = wOffset; pInformation->Ctrl_Info.CopyData = CopyRoutine; // sb in the original the cast to word was directly // now the cast is made step by step (*CopyRoutine)(0); Result = USB_SUCCESS; } else { Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); if (Result == USB_NOT_READY) { pInformation->ControlState = PAUSE; return; } } if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) { // Data is not ready, wait it pInformation->ControlState = PAUSE; return; } if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) { // Unsupported request pInformation->ControlState = STALLED; return; } if (ValBit(pInformation->USBbmRequestType, 7)) { // Device ==> Host __IO uint32_t wLength = pInformation->USBwLength; // Restrict the data length to be the one host asks for if (pInformation->Ctrl_Info.Usb_wLength > wLength) { pInformation->Ctrl_Info.Usb_wLength = wLength; } else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) { if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) { Data_Mul_MaxPacketSize = FALSE; } else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) { Data_Mul_MaxPacketSize = TRUE; } } pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; DataStageIn(); } else { pInformation->ControlState = OUT_DATA; vSetEPRxStatus(EP_RX_VALID); // enable for next data reception } return; }
/******************************************************************************* * Function Name : GetTxStallStatus * Description : Returns the Stall status of the Tx endpoint. * Input : bEpNum: Endpoint Number. * Output : None. * Return : Tx Stall status. *******************************************************************************/ uint16_t GetTxStallStatus(uint8_t bEpNum) { return GetEPTxStatus(bEpNum) == EP_TX_STALL; }