static void SideShow_GetApplicationOrder(SideShow_PacketHeader_t* const PacketHeader)
{
	uint8_t  TotalApplications = 0;

	Endpoint_ClearOUT();

	for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)
	{
		if (InstalledApplications[App].InUse)
		  TotalApplications++;
	}

	PacketHeader->Length = sizeof(SideShow_PacketHeader_t) +
	                       sizeof(uint32_t) + (TotalApplications * sizeof(GUID_t));

	Endpoint_SelectEndpoint(SIDESHOW_IN_EPNUM);
	Endpoint_Write_Stream_LE(PacketHeader, sizeof(SideShow_PacketHeader_t), NULL);
	Endpoint_Write_32_LE(TotalApplications);

	for (uint8_t App = 0; App < MAX_APPLICATIONS; App++)
	{
		if (InstalledApplications[App].InUse)
		  Endpoint_Write_Stream_LE(&InstalledApplications[App].ApplicationID, sizeof(GUID_t), NULL);
	}

	Endpoint_ClearIN();
}
Beispiel #2
0
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
 *  the SCSI device, as well as the device's Write Protect status.
 *
 *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with
 *
 *  \return Boolean \c true if the command completed successfully, \c false otherwise.
 */
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
	/* Send an empty header response indicating Write Protect flag is off */
	Endpoint_Write_32_LE(0);
	Endpoint_ClearIN();

	/* Update the bytes transferred counter and succeed the command */
	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4;

	return true;
}
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
 *  the device from the USB host before passing along unhandled control requests to the library for processing
 *  internally.
 */
void EVENT_USB_Device_ControlRequest(void)
{
	uint8_t TMCRequestStatus = TMC_STATUS_SUCCESS;

	/* Process TMC specific control requests */
	switch (USB_ControlRequest.bRequest)
	{
		case Req_InitiateAbortBulkOut:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				/* Check that no split transaction is already in progress and the data transfer tag is valid */
				if (RequestInProgress != 0)
				{
					TMCRequestStatus = TMC_STATUS_SPLIT_IN_PROGRESS;
				}
				else if (USB_ControlRequest.wValue != CurrentTransferTag)
				{
					TMCRequestStatus = TMC_STATUS_TRANSFER_NOT_IN_PROGRESS;
				}
				else
				{
					/* Indicate that all in-progress/pending data OUT requests should be aborted */
					IsTMCBulkOUTReset = true;

					/* Save the split request for later checking when a new request is received */
					RequestInProgress = Req_InitiateAbortBulkOut;
				}

				Endpoint_ClearSETUP();

				/* Write the request response byte */
				Endpoint_Write_8(TMCRequestStatus);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_CheckAbortBulkOutStatus:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				/* Check that an ABORT BULK OUT transaction has been requested and that the request has completed */
				if (RequestInProgress != Req_InitiateAbortBulkOut)
				  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
				else if (IsTMCBulkOUTReset)
				  TMCRequestStatus = TMC_STATUS_PENDING;
				else
				  RequestInProgress = 0;

				Endpoint_ClearSETUP();

				/* Write the request response bytes */
				Endpoint_Write_8(TMCRequestStatus);
				Endpoint_Write_16_LE(0);
				Endpoint_Write_32_LE(LastTransferLength);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_InitiateAbortBulkIn:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				/* Check that no split transaction is already in progress and the data transfer tag is valid */
				if (RequestInProgress != 0)
				{
					TMCRequestStatus = TMC_STATUS_SPLIT_IN_PROGRESS;
				}
				else if (USB_ControlRequest.wValue != CurrentTransferTag)
				{
					TMCRequestStatus = TMC_STATUS_TRANSFER_NOT_IN_PROGRESS;
				}
				else
				{
					/* Indicate that all in-progress/pending data IN requests should be aborted */
					IsTMCBulkINReset = true;

					/* Save the split request for later checking when a new request is received */
					RequestInProgress = Req_InitiateAbortBulkIn;
				}

				Endpoint_ClearSETUP();

				/* Write the request response bytes */
				Endpoint_Write_8(TMCRequestStatus);
				Endpoint_Write_8(CurrentTransferTag);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_CheckAbortBulkInStatus:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				/* Check that an ABORT BULK IN transaction has been requested and that the request has completed */
				if (RequestInProgress != Req_InitiateAbortBulkIn)
				  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
				else if (IsTMCBulkINReset)
				  TMCRequestStatus = TMC_STATUS_PENDING;
				else
				  RequestInProgress = 0;

				Endpoint_ClearSETUP();

				/* Write the request response bytes */
				Endpoint_Write_8(TMCRequestStatus);
				Endpoint_Write_16_LE(0);
				Endpoint_Write_32_LE(LastTransferLength);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_InitiateClear:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				/* Check that no split transaction is already in progress */
				if (RequestInProgress != 0)
				{
					Endpoint_Write_8(TMC_STATUS_SPLIT_IN_PROGRESS);
				}
				else
				{
					/* Indicate that all in-progress/pending data IN and OUT requests should be aborted */
					IsTMCBulkINReset  = true;
					IsTMCBulkOUTReset = true;

					/* Save the split request for later checking when a new request is received */
					RequestInProgress = Req_InitiateClear;
				}

				Endpoint_ClearSETUP();

				/* Write the request response byte */
				Endpoint_Write_8(TMCRequestStatus);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_CheckClearStatus:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				/* Check that a CLEAR transaction has been requested and that the request has completed */
				if (RequestInProgress != Req_InitiateClear)
				  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
				else if (IsTMCBulkINReset || IsTMCBulkOUTReset)
				  TMCRequestStatus = TMC_STATUS_PENDING;
				else
				  RequestInProgress = 0;

				Endpoint_ClearSETUP();

				/* Write the request response bytes */
				Endpoint_Write_8(TMCRequestStatus);
				Endpoint_Write_8(0);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case Req_GetCapabilities:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();

				/* Write the device capabilities to the control endpoint */
				Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t));
				Endpoint_ClearOUT();
			}

			break;
	}
}
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
	if (!(Endpoint_IsSETUPReceived()))
	  return;

	if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
	  return;

	switch (USB_ControlRequest.bRequest)
	{
		case CDC_REQ_GetLineEncoding:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();

				while (!(Endpoint_IsINReady()));

				Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat);
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType);
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits);

				Endpoint_ClearIN();
				Endpoint_ClearStatusStage();
			}

			break;
		case CDC_REQ_SetLineEncoding:
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();

				while (!(Endpoint_IsOUTReceived()))
				{
					if (USB_DeviceState == DEVICE_STATE_Unattached)
						return;
				}

				CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
				CDCInterfaceInfo->State.LineEncoding.CharFormat  = Endpoint_Read_8();
				CDCInterfaceInfo->State.LineEncoding.ParityType  = Endpoint_Read_8();
				CDCInterfaceInfo->State.LineEncoding.DataBits    = Endpoint_Read_8();

				Endpoint_ClearOUT();
				Endpoint_ClearStatusStage();

				EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
			}

			break;
		case CDC_REQ_SetControlLineState:
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();
				Endpoint_ClearStatusStage();

				CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;

				EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
			}

			break;
		case CDC_REQ_SendBreak:
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();
				Endpoint_ClearStatusStage();

				EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
			}

			break;
	}
}