/** Returns the filled Command Status Wrapper back to the host via the bulk data IN endpoint, waiting for the host to clear any * stalled data endpoints as needed. */ static void ReturnCommandStatus(void) { /* Select the Data Out endpoint */ Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); /* While data pipe is stalled, wait until the host issues a control request to clear the stall */ while (Endpoint_IsStalled()) { /* Check if the current command is being aborted by the host */ if (IsMassStoreReset) return; } /* Select the Data In endpoint */ Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); /* While data pipe is stalled, wait until the host issues a control request to clear the stall */ while (Endpoint_IsStalled()) { /* Check if the current command is being aborted by the host */ if (IsMassStoreReset) return; } /* Write the CSW to the endpoint */ Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus), AbortOnMassStoreReset); /* Check if the current command is being aborted by the host */ if (IsMassStoreReset) return; /* Finalize the stream transfer to send the last packet */ Endpoint_ClearCurrentBank(); }
uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1); uint8_t ErrorCode; if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; while (Length--) { if (!(Endpoint_ReadWriteAllowed())) { Endpoint_ClearCurrentBank(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return ENDPOINT_RWSTREAM_ERROR_CallbackAborted; #endif if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; } *(DataStream--) = Endpoint_Read_Byte(); } return ENDPOINT_RWSTREAM_ERROR_NoError; }
uint8_t Endpoint_Discard_Stream(uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t ErrorCode; while (Length) { if (!(Endpoint_ReadWriteAllowed())) { Endpoint_ClearCurrentBank(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return ENDPOINT_RWSTREAM_ERROR_CallbackAborted; #endif if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; } Endpoint_Discard_Byte(); Length--; if (!(USB_IsConnected)) return ENDPOINT_RWSTREAM_ERROR_DeviceDisconnected; } return ENDPOINT_RWSTREAM_ERROR_NoError; }
/** Task to manage the sending and receiving of encapsulated RNDIS data and notifications. This removes the RNDIS * wrapper from recieved Ethernet frames and places them in the FrameIN global buffer, or adds the RNDIS wrapper * to a frame in the FrameOUT global before sending the buffer contents to the host. */ void RNDIS_Notification(void) { /* Select the notification endpoint */ Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM); /* Check if a message response is ready for the host */ if (Endpoint_ReadWriteAllowed() && ResponseReady) { USB_Notification_t Notification = (USB_Notification_t) { bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), bNotification: NOTIF_RESPONSE_AVAILABLE, wValue: 0, wIndex: 0, wLength: 0, }; /* Indicate that a message response is ready for the host */ Endpoint_Write_Stream_LE(&Notification, sizeof(Notification)); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearCurrentBank(); /* Indicate a response is no longer ready */ ResponseReady = false; }
void cdc_flush() { #ifndef ARM Endpoint_SelectEndpoint(CDC_TX_EPNUM); Endpoint_ClearCurrentBank(); #endif }
/** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block * if one has been issued, and performs validation to ensure that the block command is valid. * * \return Boolean true if a valid command block has been read in from the endpoint, false otherwise */ static bool ReadInCommandBlock(void) { /* Select the Data Out endpoint */ Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM); /* Read in command block header */ Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)), AbortOnMassStoreReset); /* Check if the current command is being aborted by the host */ if (IsMassStoreReset) return false; /* Verify the command block - abort if invalid */ if ((CommandBlock.Signature != CBW_SIGNATURE) || (CommandBlock.LUN >= TOTAL_LUNS) || (CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH)) { /* Stall both data pipes until reset by host */ Endpoint_StallTransaction(); Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM); Endpoint_StallTransaction(); return false; } /* Read in command block command data */ Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData, CommandBlock.SCSICommandLength, AbortOnMassStoreReset); /* Check if the current command is being aborted by the host */ if (IsMassStoreReset) return false; /* Finalize the stream transfer to send the last packet */ Endpoint_ClearCurrentBank(); return true; }
//////////////////// // Fill data from USB to the RingBuffer and vice-versa void CDC_Task(void) { static char inCDC_TASK = 0; if(!USB_IsConnected) return; #ifdef ARM if(!inCDC_TASK){ // USB -> RingBuffer inCDC_TASK = 1; output_flush_func = CDC_Task; input_handle_func(DISPLAY_USB); inCDC_TASK = 0; } if(TTY_Tx_Buffer.nbytes) { uint16_t i=0; while(TTY_Tx_Buffer.nbytes && i<DATABUFFERSIZEOUT) { usbBufferOut[i++]=rb_get(&TTY_Tx_Buffer); } while (CDCDSerialDriver_Write(usbBufferOut,i, 0, 0) != USBD_STATUS_SUCCESS); } #else Endpoint_SelectEndpoint(CDC_RX_EPNUM); // First data in if(!inCDC_TASK && Endpoint_ReadWriteAllowed()){ // USB -> RingBuffer while (Endpoint_BytesInEndpoint()) { // Discard data on buffer full rb_put(&TTY_Rx_Buffer, Endpoint_Read_Byte()); } Endpoint_ClearCurrentBank(); inCDC_TASK = 1; output_flush_func = CDC_Task; input_handle_func(DISPLAY_USB); inCDC_TASK = 0; } Endpoint_SelectEndpoint(CDC_TX_EPNUM); // Then data out if(TTY_Tx_Buffer.nbytes && Endpoint_ReadWriteAllowed()) { cli(); while(TTY_Tx_Buffer.nbytes && (Endpoint_BytesInEndpoint() < USB_BUFSIZE)) Endpoint_Write_Byte(rb_get(&TTY_Tx_Buffer)); sei(); Endpoint_ClearCurrentBank(); // Send the data } #endif }