예제 #1
0
/** 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),
	                          StreamCallback_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_ClearIN();
}
예제 #2
0
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);

	while (Endpoint_IsStalled())
	{
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
		USB_USBTask();
		#endif

		if (MSInterfaceInfo->State.IsMassStoreReset)
		  return;
	}

	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);

	while (Endpoint_IsStalled())
	{
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
		USB_USBTask();
		#endif
		
		if (MSInterfaceInfo->State.IsMassStoreReset)
		  return;
	}
	
	CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
	if (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, sizeof(MS_CommandStatusWrapper_t),
	                             StreamCallback_MS_Device_AbortOnMassStoreReset))
	{
		return;
	}

	Endpoint_ClearIN();
}
예제 #3
0
uint8_t Endpoint_WaitUntilReady(void)
{
	#if (USB_STREAM_TIMEOUT_MS < 0xFF)
	uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;	
	#else
	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
	#endif

	for (;;)
	{
		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
		{
			if (Endpoint_IsINReady())
			  return ENDPOINT_READYWAIT_NoError;
		}
		else
		{
			if (Endpoint_IsOUTReceived())
			  return ENDPOINT_READYWAIT_NoError;		
		}
		
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return ENDPOINT_READYWAIT_DeviceDisconnected;
		else if (Endpoint_IsStalled())
		  return ENDPOINT_READYWAIT_EndpointStalled;
			  
		if (USB_INT_HasOccurred(USB_INT_SOFI))
		{
			USB_INT_Clear(USB_INT_SOFI);

			if (!(TimeoutMSRem--))
			  return ENDPOINT_READYWAIT_Timeout;
		}
	}
}
예제 #4
0
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);

	while (Endpoint_IsStalled())
	{
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
		USB_USBTask();
		#endif

		if (MSInterfaceInfo->State.IsMassStoreReset)
		  return;
	}

	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);

	while (Endpoint_IsStalled())
	{
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
		USB_USBTask();
		#endif

		if (MSInterfaceInfo->State.IsMassStoreReset)
		  return;
	}

	uint16_t BytesProcessed = 0;
	while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus,
	                                sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) ==
	                                ENDPOINT_RWSTREAM_IncompleteTransfer)
	{
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
		USB_USBTask();
		#endif

		if (MSInterfaceInfo->State.IsMassStoreReset)
		  return;
	}

	Endpoint_ClearIN();
}
예제 #5
0
/** 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)
{
    uint16_t BytesTransferred;

    /* Select the Data Out endpoint */
    Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPADDR);

    /* 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_EPADDR);

    /* 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 */
    BytesTransferred = 0;
    while (Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus),
                                    &BytesTransferred) == ENDPOINT_RWSTREAM_IncompleteTransfer)
    {
        /* Check if the current command is being aborted by the host */
        if (IsMassStoreReset)
            return;
    }

    /* Finalize the stream transfer to send the last packet */
    Endpoint_ClearIN();
}
uint8_t Endpoint_WaitUntilReady(void)
{
	#if (USB_STREAM_TIMEOUT_MS < 0xFF)
	uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
	#else
	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
	#endif

	uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber();

	for (;;)
	{
		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
		{
			if (Endpoint_IsINReady())
			  return ENDPOINT_READYWAIT_NoError;
		}
		else
		{
			if (Endpoint_IsOUTReceived())
			  return ENDPOINT_READYWAIT_NoError;
		}

		uint8_t USB_DeviceState_LCL = USB_DeviceState;

		if (USB_DeviceState_LCL == DEVICE_STATE_Unattached)
		  return ENDPOINT_READYWAIT_DeviceDisconnected;
		else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended)
		  return ENDPOINT_READYWAIT_BusSuspended;
		else if (Endpoint_IsStalled())
		  return ENDPOINT_READYWAIT_EndpointStalled;

		uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber();

		if (CurrentFrameNumber != PreviousFrameNumber)
		{
			PreviousFrameNumber = CurrentFrameNumber;

			if (!(TimeoutMSRem--))
			  return ENDPOINT_READYWAIT_Timeout;
		}
	}
}
예제 #7
0
파일: main.c 프로젝트: Flaviowebit/openCBM
/*
 * The Linux and OSX call the configuration changed entry each time
 * a transaction is started (e.g., multiple runs of cbmctrl status).
 * We need to reset the endpoints before reconfiguring them, otherwise
 * we get a hang the second time through.
 *
 * We keep the original endpoint selected after returning.
 */
void
USB_ResetConfig()
{
    static uint8_t endpoints[] = {
        XUM_BULK_IN_ENDPOINT, XUM_BULK_OUT_ENDPOINT, 0,
    };
    uint8_t lastEndpoint, *endp;

    lastEndpoint = Endpoint_GetCurrentEndpoint();

    for (endp = endpoints; *endp != 0; endp++) {
        Endpoint_SelectEndpoint(*endp);
        Endpoint_ResetFIFO(*endp);
        Endpoint_ResetDataToggle();
        if (Endpoint_IsStalled())
            Endpoint_ClearStall();
    }

    Endpoint_SelectEndpoint(lastEndpoint);
}
static void USB_Device_GetStatus(void)
{
	uint8_t CurrentStatus = 0;

	switch (USB_ControlRequest.bmRequestType)
	{
		#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
			#if !defined(NO_DEVICE_SELF_POWER)
			if (USB_Device_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
			#endif

			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
			if (USB_Device_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
			#endif
			break;
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);

			CurrentStatus = Endpoint_IsStalled();

			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

			break;
		#endif
		default:
			return;
	}

	Endpoint_ClearSETUP();

	Endpoint_Write_16_LE(CurrentStatus);
	Endpoint_ClearIN();

	Endpoint_ClearStatusStage();
}
예제 #9
0
uint8_t Endpoint_WaitUntilReady(void)
{
	uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;

	USB_INT_Clear(USB_INT_SOFI);

	while (!(Endpoint_ReadWriteAllowed()))
	{
		if (!(USB_IsConnected))
		  return ENDPOINT_READYWAIT_DeviceDisconnected;
		else if (Endpoint_IsStalled())
		  return ENDPOINT_READYWAIT_EndpointStalled;
			  
		if (USB_INT_HasOccurred(USB_INT_SOFI))
		{
			USB_INT_Clear(USB_INT_SOFI);

			if (!(TimeoutMSRem--))
			  return ENDPOINT_READYWAIT_Timeout;
		}
	}
	
	return ENDPOINT_READYWAIT_NoError;
}
예제 #10
0
파일: main.c 프로젝트: Flaviowebit/openCBM
static bool
USB_BulkWorker()
{
    uint8_t cmdBuf[XUM_CMDBUF_SIZE], statusBuf[XUM_STATUSBUF_SIZE];
    int8_t status;

    /*
     * If we are not connected to the host or a command has not yet
     * been sent, no more processing is required.
     */
    if (USB_DeviceState != DEVICE_STATE_Configured)
        return false;
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    if (!Endpoint_IsReadWriteAllowed())
        return false;

#ifdef DEBUG
    // Dump the status of both endpoints before getting the command
    Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT);
    DEBUGF(DBG_INFO, "bsti %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    DEBUGF(DBG_INFO, "bsto %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
#endif

    // Read in the command from the host now that one is ready.
    if (!USB_ReadBlock(cmdBuf, sizeof(cmdBuf))) {
        board_set_status(STATUS_ERROR);
        return false;
    }

    // Allow commands to leave the extended status untouched
    memset(statusBuf, 0, sizeof(statusBuf));

    /*
     * Decode and process the command.
     * usbHandleBulk() stores its extended result in the output buffer,
     * up to XUM_STATUSBUF_SIZE.
     *
     * Return values:
     *   >0: completed ok, send the return value and extended status
     *    0: completed ok, don't send any status
     *   -1: error, no status
     */
    status = usbHandleBulk(cmdBuf, statusBuf);
    if (status > 0) {
        statusBuf[0] = status;
        USB_WriteBlock(statusBuf, sizeof(statusBuf));
    } else if (status < 0) {
        DEBUGF(DBG_ERROR, "usbblk err\n");
        board_set_status(STATUS_ERROR);
        Endpoint_StallTransaction();
        return false;
    }

    return true;
}