Example #1
0
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
 *  enumerated by the host and is now ready to be used by the application.
 */
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
	puts_P(PSTR("Getting Config Data.\r\n"));

	uint8_t ErrorCode;

	/* Get and process the configuration descriptor data */
	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
	{
		if (ErrorCode == ControlError)
		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
		else
		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
	{
		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 9600,
	                                    .CharFormat  = CDC_LINEENCODING_OneStopBit,
	                                    .ParityType  = CDC_PARITY_None,
	                                    .DataBits    = 8                            };

	USB_ControlRequest = (USB_Request_Header_t)
	{
		.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
		.bRequest      = CDC_REQ_SetLineEncoding,
		.wValue        = 0,
		.wIndex        = 0,
		.wLength       = sizeof(LineEncoding),
	};

	/* Set the Line Encoding of the CDC interface within the device, so that it is ready to accept data */
	Pipe_SelectPipe(PIPE_CONTROLPIPE);
	if (USB_Host_SendControlRequest(&LineEncoding) != HOST_SENDCONTROL_Successful)
	{
		printf_P(PSTR(ESC_FG_RED "Control Error (Set Line Encoding).\r\n"
		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;	
	}

	puts_P(PSTR("CDC Device Enumerated.\r\n"));
	LEDs_SetAllLEDs(LEDMASK_USB_READY);
}

/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
	USB_Disable();

	printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
	                         " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);

	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
	for(;;);
}

/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
 *  enumerating an attached USB device.
 */
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
                                            const uint8_t SubErrorCode)
{
	printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
	                         " -- Error Code %d\r\n"
	                         " -- Sub Error Code %d\r\n"
	                         " -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);

	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
 *  data received from the attached RNDIS device and print it to the serial port.
 */
void RNDIS_Host_Task(void)
{
	uint8_t ErrorCode;

	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));
		
			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
				else
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
				
				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			uint16_t DeviceMaxPacketSize;
			if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;			
			}
			
			printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
			
			/* We set the default filter to only receive packets we would be interested in */
			uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
			if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
			                                        &PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			uint32_t VendorID;
			if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
			                                          &VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
			
			puts_P(PSTR("RNDIS Device Enumerated.\r\n"));

			USB_HostState = HOST_STATE_Configured;
			break;
		case HOST_STATE_Configured:
			PrintIncommingPackets();
		
			break;
	}
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
 *  enumerated by the host and is now ready to be used by the application.
 */
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
	puts_P(PSTR("Getting Device Data.\r\n"));

	/* Get and process the configuration descriptor data */
	uint8_t ErrorCode = ProcessDeviceDescriptor();

	bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice);

	/* Error out if the device is not an Android device or an error occurred */
	if ((ErrorCode != AccessoryModeAndroidDevice) && (ErrorCode != NonAccessoryModeAndroidDevice))
	{
		if (ErrorCode == ControlError)
		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
		else
		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : ""));

	/* Check if a valid Android device was attached, but it is not current in Accessory mode */
	if (RequiresModeSwitch)
	{
		uint16_t AndroidProtocol;

		/* Fetch the version of the Android Accessory Protocol supported by the device */
		if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful)
		{
			printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n"
			                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			return;
		}

		/* Validate the returned protocol version */
		if (AndroidProtocol != AOA_PROTOCOL_AccessoryV1)
		{
			puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported."));

			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			return;
		}

		/* Send the device strings and start the Android Accessory Mode */
		Android_SendString(AOA_STRING_Manufacturer, "Dean Camera");
		Android_SendString(AOA_STRING_Model,        "LUFA Android Demo");
		Android_SendString(AOA_STRING_Description,  "LUFA Android Demo");
		Android_SendString(AOA_STRING_Version,      "1.0");
		Android_SendString(AOA_STRING_URI,          "http://www.lufa-lib.org");
		Android_SendString(AOA_STRING_Serial,       "0000000012345678");

		Android_StartAccessoryMode();
		return;
	}

	puts_P(PSTR("Getting Config Data.\r\n"));

	/* Get and process the configuration descriptor data */
	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
	{
		if (ErrorCode == ControlError)
		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
		else
		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
	{
		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	puts_P(PSTR("Accessory Mode Android Enumerated.\r\n"));
	LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
Example #4
0
/** Task to set the configuration of the attached device after it has been enumerated, and to print device information
 *  through the serial port.
 */
void StillImage_Task(void)
{
	uint8_t ErrorCode;

	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));
		
			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
				else
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
				
				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error via status LEDs */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
				
			puts_P(PSTR("Still Image Device Enumerated.\r\n"));
			USB_HostState = HOST_STATE_Configured;
			break;
		case HOST_STATE_Configured:
			/* Indicate device busy via the status LEDs */
			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
			
			puts_P(PSTR("Retrieving Device Info...\r\n"));
			
			PIMA_SendBlock = (PIMA_Container_t)
				{
					.DataLength    = PIMA_COMMAND_SIZE(0),
					.Type          = CType_CommandBlock,
					.Code          = PIMA_OPERATION_GETDEVICEINFO,
					.TransactionID = 0x00000000,
					.Params        = {},
				};
			
			/* Send the GETDEVICEINFO block */
			SImage_SendBlockHeader();
			
			/* Receive the response data block */
			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
			{
				ShowCommandError(ErrorCode, false);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			/* Calculate the size of the returned device info data structure */
			uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
			
			/* Create a buffer large enough to hold the entire device info */
			uint8_t DeviceInfo[DeviceInfoSize];

			/* Read in the data block data (containing device info) */
			SImage_ReadData(DeviceInfo, DeviceInfoSize);
			
			/* Once all the data has been read, the pipe must be cleared before the response can be sent */
			Pipe_ClearIN();
			
			/* Create a pointer for walking through the info dataset */
			uint8_t* DeviceInfoPos = DeviceInfo;
			
			/* Skip over the data before the unicode device information strings */
			DeviceInfoPos +=  8;                                          // Skip to VendorExtensionDesc String
			DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
			DeviceInfoPos +=  2;                                          // Skip over FunctionalMode
			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Operations Array
			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Events Array
			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Device Properties Array
			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Capture Formats Array
			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Image Formats Array
			
			/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
			char Manufacturer[*DeviceInfoPos];
			UnicodeToASCII(DeviceInfoPos, Manufacturer);
			printf_P(PSTR("   Manufacturer: %s\r\n"), Manufacturer);

			DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Manufacturer String

			/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
			char Model[*DeviceInfoPos];
			UnicodeToASCII(DeviceInfoPos, Model);
			printf_P(PSTR("   Model: %s\r\n"), Model);

			DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Model String

			/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
			char DeviceVersion[*DeviceInfoPos];
			UnicodeToASCII(DeviceInfoPos, DeviceVersion);
			printf_P(PSTR("   Device Version: %s\r\n"), DeviceVersion);

			/* Receive the final response block from the device */
			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
			{
				ShowCommandError(ErrorCode, false);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			/* Verify that the command completed successfully */
			if ((PIMA_ReceivedBlock.Type != CType_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
			{
				ShowCommandError(PIMA_ReceivedBlock.Code, true);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			puts_P(PSTR("Opening Session...\r\n"));
			
			PIMA_SendBlock = (PIMA_Container_t)
				{
					.DataLength    = PIMA_COMMAND_SIZE(1),
					.Type          = CType_CommandBlock,
					.Code          = PIMA_OPERATION_OPENSESSION,
					.TransactionID = 0x00000000,
					.Params        = {0x00000001},
				};
			
			/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
			SImage_SendBlockHeader();
			
			/* Receive the response block from the device */
			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
			{
				ShowCommandError(ErrorCode, false);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}
			
			/* Verify that the command completed successfully */
			if ((PIMA_ReceivedBlock.Type != CType_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
			{
				ShowCommandError(PIMA_ReceivedBlock.Code, true);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			puts_P(PSTR("Closing Session...\r\n"));

			PIMA_SendBlock = (PIMA_Container_t)
				{
					.DataLength    = PIMA_COMMAND_SIZE(1),
					.Type          = CType_CommandBlock,
					.Code          = PIMA_OPERATION_CLOSESESSION,
					.TransactionID = 0x00000001,
					.Params        = {0x00000001},
				};
			
			/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
			SImage_SendBlockHeader();
			
			/* Receive the response block from the device */
			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
			{
				ShowCommandError(ErrorCode, false);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* Verify that the command completed successfully */
			if ((PIMA_ReceivedBlock.Type != CType_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
			{
				ShowCommandError(PIMA_ReceivedBlock.Code, true);
				
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			puts_P(PSTR("Done.\r\n"));

			/* Indicate device no longer busy */
			LEDs_SetAllLEDs(LEDMASK_USB_READY);
			
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			break;
	}
}

/** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode
 *  strings which contain ASCII printable characters only.
 *
 *  \param[in] UnicodeString  Pointer to a Unicode encoded input string
 *  \param[out] Buffer        Pointer to a buffer where the converted ASCII string should be stored
 */
void UnicodeToASCII(uint8_t* UnicodeString,
                    char* Buffer)
{
	/* Get the number of characters in the string, skip to the start of the string data */
	uint8_t CharactersRemaining = *(UnicodeString++);
	
	/* Loop through the entire unicode string */
	while (CharactersRemaining--)
	{
		/* Load in the next unicode character (only the lower byte, as only Unicode coded ASCII is supported) */
		*(Buffer++) = *UnicodeString;
		
		/* Jump to the next unicode character */
		UnicodeString += 2;
	}
	
	/* Null terminate the string */
	*Buffer = 0;
}

/** Displays a PIMA command error via the device's serial port.
 *
 *  \param[in] ErrorCode          Error code of the function which failed to complete successfully
 *  \param[in] ResponseCodeError  Indicates if the error is due to a command failed indication from the device, or a communication failure
 */
void ShowCommandError(uint8_t ErrorCode,
                      bool ResponseCodeError)
{
	char* FailureType = ((ResponseCodeError) ? PSTR("Response Code != OK") : PSTR("Transaction Fail"));

	printf_P(PSTR(ESC_FG_RED "Command Error (%S).\r\n"
	                         " -- Error Code %d\r\n" ESC_FG_WHITE), FailureType, ErrorCode);
			
	/* Indicate error via status LEDs */
	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
void Camera_Capture(void)
{
	if (USB_HostState != HOST_STATE_Configured)
	  return;

	uint8_t ErrorCode;

	puts_P(PSTR("Taking picture...\r\n"));
	_delay_ms(50);

	PIMA_SendBlock = (PIMA_Container_t)
		{
			.DataLength    = PIMA_COMMAND_SIZE(0),
			.Type          = PIMA_CONTAINER_CommandBlock,
			.Code          = EOS_OC_CAPTURE,
			.TransactionID = 0x00000001,
			.Params        = {},
		};

	/* Send the GETDEVICEINFO block */
	SImage_SendBlockHeader();

	/* Receive the response data block */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 8\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	return;
}


void Camera_SetParam(uint32_t param, uint32_t val)
{
	if (USB_HostState != HOST_STATE_Configured)
	  return;

	uint8_t ErrorCode;

	puts_P(PSTR("Changing ISO...\r\n"));
	_delay_ms(50);

	PIMA_SendBlock = (PIMA_Container_t)
		{
			.DataLength    = PIMA_COMMAND_SIZE(1)+2,
			.Type          = PIMA_CONTAINER_CommandBlock,
			.Code          = EOS_OC_PROPERTY_SET,
			.TransactionID = 0x00000001,
			.Params        = {param},
		};

	/* Send the GETDEVICEINFO block */
	SImage_SendBlockHeader();

	uint8_t		*SendData = ((uint8_t*)((void*)(&val)));

	/* Receive the response data block */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 9\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	SImage_SendData(SendData, 2);

	/* Receive the response data block */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 12\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	return;
}

void Camera_GetModel(void)
{
	if (USB_HostState != HOST_STATE_Configured)
	  return;

	uint8_t ErrorCode;

	PIMA_SendBlock = (PIMA_Container_t)
		{
			.DataLength    = PIMA_COMMAND_SIZE(0),
			.Type          = PIMA_CONTAINER_CommandBlock,
			.Code          = PIMA_OPERATION_GETDEVICEINFO,
			.TransactionID = 0x00000000,
			.Params        = {},
		};

	/* Send the GETDEVICEINFO block */
	SImage_SendBlockHeader();

	/* Receive the response data block */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 1\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	/* Calculate the size of the returned device info data structure */
	uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));

	/* Create a buffer large enough to hold the entire device info */
	uint8_t DeviceInfo[DeviceInfoSize];

	/* Read in the data block data (containing device info) */
	SImage_ReadData(DeviceInfo, DeviceInfoSize);

	/* Once all the data has been read, the pipe must be cleared before the response can be sent */
	Pipe_ClearIN();

	/* Create a pointer for walking through the info dataset */
	uint8_t* DeviceInfoPos = DeviceInfo;

	/* Skip over the data before the unicode device information strings */
	DeviceInfoPos +=  8;                                          // Skip to VendorExtensionDesc String
	DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
	DeviceInfoPos +=  2;                                          // Skip over FunctionalMode
	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Operations Array
	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Events Array
	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Device Properties Array
	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Capture Formats Array
	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Image Formats Array

	/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
	char Manufacturer[*DeviceInfoPos];
	UnicodeToASCII(DeviceInfoPos, Manufacturer);
	printf_P(PSTR("   Manufacturer: %s\r\n"), Manufacturer);
	_delay_ms(50);

	DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Manufacturer String

	/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
	char Model[*DeviceInfoPos];
	UnicodeToASCII(DeviceInfoPos, Model);
	printf_P(PSTR("   Model: %s\r\n"), Model);
	_delay_ms(50);

	DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Model String

	/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
	char DeviceVersion[*DeviceInfoPos];
	UnicodeToASCII(DeviceInfoPos, DeviceVersion);
	printf_P(PSTR("   Device Version: %s\r\n\r\n"), DeviceVersion);
	_delay_ms(50);

	/* Receive the final response block from the device */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 2\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	/* Verify that the command completed successfully */
/*	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
	{
		puts_P(PSTR("Error 3\r\n"));
		ShowCommandError(PIMA_ReceivedBlock.Code, true);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}
*/
	return;
}

/** Task to print device information through the serial port, and open/close a test PIMA session with the
 *  attached Still Image device.
 */
void Camera_Task(void)
{
	if (USB_HostState != HOST_STATE_Configured)
	  return;

	uint8_t ErrorCode;

	/* Indicate device busy via the status LEDs */
//	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);

	puts_P(PSTR("Retrieving Device Info...\r\n"));
	_delay_ms(50);

	Camera_GetModel();

	puts_P(PSTR("Opening Session...\r\n"));
	_delay_ms(50);

	PIMA_SendBlock = (PIMA_Container_t)
		{
			.DataLength    = PIMA_COMMAND_SIZE(1),
			.Type          = PIMA_CONTAINER_CommandBlock,
			.Code          = PIMA_OPERATION_OPENSESSION,
			.TransactionID = 0x00000000,
			.Params        = {0x00000001},
		};

	/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
	SImage_SendBlockHeader();

	/* Receive the response block from the device */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 4\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	/* Verify that the command completed successfully */
/*	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
	{
		puts_P(PSTR("Error 5\r\n"));
		ShowCommandError(PIMA_ReceivedBlock.Code, true);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}
*/

//	Camera_SetParam(EOS_DPC_ISO, EOS_DVC_ISO_1250);
	Camera_Capture();
	Camera_Close();

}

void Camera_Close(void)
{
	puts_P(PSTR("Closing Session...\r\n"));
	_delay_ms(50);

	uint8_t ErrorCode;


	PIMA_SendBlock = (PIMA_Container_t)
		{
			.DataLength    = PIMA_COMMAND_SIZE(1),
			.Type          = PIMA_CONTAINER_CommandBlock,
			.Code          = PIMA_OPERATION_CLOSESESSION,
			.TransactionID = 0x00000001,
			.Params        = {0x00000001},
		};

	/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
	SImage_SendBlockHeader();

	/* Receive the response block from the device */
	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
	{
		puts_P(PSTR("Error 6\r\n"));
		ShowCommandError(ErrorCode, false);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	/* Verify that the command completed successfully */
/*	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
	{
		puts_P(PSTR("Error 7\r\n"));
		ShowCommandError(PIMA_ReceivedBlock.Code, true);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}
*/
	puts_P(PSTR("Done.\r\n"));
	_delay_ms(50);

	/* Indicate device no longer busy */
//	LEDs_SetAllLEDs(LEDMASK_USB_READY);
	USB_Host_SetDeviceConfiguration(0);
	return;	
}

/** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode
 *  strings which contain ASCII printable characters only.
 *
 *  \param[in] UnicodeString  Pointer to a Unicode encoded input string
 *  \param[out] Buffer        Pointer to a buffer where the converted ASCII string should be stored
 */
void UnicodeToASCII(uint8_t* UnicodeString,
                    char* Buffer)
{
	/* Get the number of characters in the string, skip to the start of the string data */
	uint8_t CharactersRemaining = *(UnicodeString++);

	/* Loop through the entire unicode string */
	while (CharactersRemaining--)
	{
		/* Load in the next unicode character (only the lower byte, as only Unicode coded ASCII is supported) */
		*(Buffer++) = *UnicodeString;

		/* Jump to the next unicode character */
		UnicodeString += 2;
	}

	/* Null terminate the string */
	*Buffer = 0;
}

/** Displays a PIMA command error via the device's serial port.
 *
 *  \param[in] ErrorCode          Error code of the function which failed to complete successfully
 *  \param[in] ResponseCodeError  Indicates if the error is due to a command failed indication from the device, or a communication failure
 */
void ShowCommandError(uint8_t ErrorCode,
                      bool ResponseCodeError)
{
	const char* FailureType = ((ResponseCodeError) ? PSTR("Response Code != OK") : PSTR("Transaction Fail"));

	printf_P(PSTR( "Command Error (%S).\r\n"
	                         " -- Error Code %d\r\n" ), FailureType, ErrorCode);
	_delay_ms(50);

	/* Indicate error via status LEDs */
//	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
Example #6
0
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
 *  HID reports from the device and display the results onto the board LEDs.
 */
void Mouse_HID_Task(void)
{
	uint8_t ErrorCode;

	/* Switch to determine what user-application handled host state the host state machine is in */
	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));

			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
				else
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* HID class request to set the mouse protocol to the Boot Protocol */
			USB_ControlRequest = (USB_Request_Header_t)
				{
					.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
					.bRequest      = HID_REQ_SetProtocol,
					.wValue        = 0,
					.wIndex        = 0,
					.wLength       = 0,
				};

			/* Select the control pipe for the request transfer */
			Pipe_SelectPipe(PIPE_CONTROLPIPE);

			/* Send the request, display error and wait for device detach if request fails */
			if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			puts_P(PSTR("Mouse Enumerated.\r\n"));

			USB_HostState = HOST_STATE_Configured;
			break;
		case HOST_STATE_Configured:
			/* If a report has been received, read and process it */
			ReadNextReport();

			break;
	}
}
Example #7
0
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
 *  enumerated by the host and is now ready to be used by the application.
 */
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
	puts_P(PSTR("Getting Config Data.\r\n"));

	uint8_t ErrorCode;

	/* Get and process the configuration descriptor data */
	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
	{
		if (ErrorCode == ControlError)
		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
		else
		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

		printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
	{
		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		return;
	}

	/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
	 * request to switch to the interface alternate setting with the Bidirectional protocol */
	if (PrinterAltSetting)
	{
		if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
		{
			printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
			                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_Host_SetDeviceConfiguration(0);
			return;
		}
	}

	puts_P(PSTR("Retrieving Device ID...\r\n"));

	char DeviceIDString[300];
	if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
	{
		printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		USB_Host_SetDeviceConfiguration(0);
		return;
	}

	printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);

	puts_P(PSTR("Printer Enumerated.\r\n"));
	LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
Example #8
0
void DiskHost_USBTask(void)
{
	if (USB_HostState == HOST_STATE_Addressed)
	{
		LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
	
		uint16_t ConfigDescriptorSize;
		uint8_t  ConfigDescriptorData[512];

		if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
											   sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}

		if (MS_Host_ConfigurePipes(&DiskHost_MS_Interface,
		                           ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}
		
		if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}
		
		uint8_t MaxLUNIndex;
		if (MS_Host_GetMaxLUN(&DiskHost_MS_Interface, &MaxLUNIndex))
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}
		
		if (MS_Host_ResetMSInterface(&DiskHost_MS_Interface))
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}
		
		USB_HostState = HOST_STATE_Configured;
		
		/* Note: For the RequestSense call to work, the host state machine must be in the 
		 *       Configured state, or the call will be aborted */
		SCSI_Request_Sense_Response_t SenseData;
		if (MS_Host_RequestSense(&DiskHost_MS_Interface, 0, &SenseData) != 0)
		{
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
			return;
		}
		
		pf_mount(&DiskFATState);
		
		LEDs_SetAllLEDs(LEDMASK_USB_READY);
	}

	MS_Host_USBTask(&DiskHost_MS_Interface);		
}
Example #9
0
/** Writes a report to the attached device.
 *
 *  \param[in] ReportOUTData  Buffer containing the report to send to the device
 *  \param[in] ReportIndex    Index of the report in the device (zero if the device does not use multiple reports)
 *  \param[in] ReportType     Type of report to send, either REPORT_TYPE_OUT or REPORT_TYPE_FEATURE
 *  \param[in] ReportLength   Length of the report to send
 */
void WriteNextReport(uint8_t* ReportOUTData,
                     const uint8_t ReportIndex,
                     const uint8_t ReportType,
                     uint16_t ReportLength)
{
	/* Select the HID data OUT pipe */
	Pipe_SelectPipe(HID_DATA_OUT_PIPE);

	/* Not all HID devices have an OUT endpoint (some require OUT reports to be sent over the
	 * control endpoint instead) - check to see if the OUT endpoint has been initialized */
	if (Pipe_IsConfigured() && (ReportType == REPORT_TYPE_OUT))
	{
		Pipe_Unfreeze();

		/* Ensure pipe is ready to be written to before continuing */
		if (!(Pipe_IsOUTReady()))
		{
			/* Refreeze the data OUT pipe */
			Pipe_Freeze();

			return;
		}

		/* If the report index is used, send it before the report data */
		if (ReportIndex)
		  Pipe_Write_Byte(ReportIndex);

		/* Write out HID report data */
		Pipe_Write_Stream_LE(ReportOUTData, ReportLength);

		/* Clear the OUT endpoint, send last data packet */
		Pipe_ClearOUT();

		/* Refreeze the data OUT pipe */
		Pipe_Freeze();
	}
	else
	{
		/* Class specific request to send a HID report to the device */
		USB_ControlRequest = (USB_Request_Header_t)
			{
				.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
				.bRequest      = REQ_SetReport,
				.wValue        = ((ReportType << 8) | ReportIndex),
				.wIndex        = 0,
				.wLength       = ReportLength,
			};

		/* Select the control pipe for the request transfer */
		Pipe_SelectPipe(PIPE_CONTROLPIPE);

		/* Send the request to the device */
		USB_Host_SendControlRequest(ReportOUTData);
	}
}

/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
 *  HID reports from the device and to send reports if desired.
 */
void HID_Host_Task(void)
{
	uint8_t ErrorCode;

	/* Switch to determine what user-application handled host state the host state machine is in */
	switch (USB_HostState)
	{
		case HOST_STATE_Addressed:
			puts_P(PSTR("Getting Config Data.\r\n"));

			/* Get and process the configuration descriptor data */
			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
			{
				if (ErrorCode == ControlError)
				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
				else
				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));

				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
			{
				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);

				/* Indicate error status */
				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);

				/* Wait until USB device disconnected */
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
			}

			puts_P(PSTR("HID Device Enumerated.\r\n"));

			USB_HostState = HOST_STATE_Configured;
			break;
		case HOST_STATE_Configured:
			ReadNextReport();

			break;
	}
}
Example #10
0
/** Main program entry point. This routine configures the hardware required by the application, then
 *  enters a loop to run the application tasks in sequence.
 */
int main(void)
{
	SetupHardware();

	puts_P(PSTR(ESC_FG_CYAN "Still Image Host Demo running.\r\n" ESC_FG_WHITE));

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	sei();

	for (;;)
	{
		switch (USB_HostState)
		{
			case HOST_STATE_Addressed:
				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
			
				uint16_t ConfigDescriptorSize;
				uint8_t  ConfigDescriptorData[512];

				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
				{
					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (SImage_Host_ConfigurePipes(&DigitalCamera_SI_Interface,
				                               ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError)
				{
					puts_P(PSTR("Attached Device Not a Valid Still Image Class Device.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}
				
				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
				{
					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}
				
				puts_P(PSTR("Still Image Device Enumerated.\r\n"));
				LEDs_SetAllLEDs(LEDMASK_USB_READY);
				USB_HostState = HOST_STATE_Configured;
				break;
			case HOST_STATE_Configured:
				puts_P(PSTR("Opening Session...\r\n"));
				
				if (SImage_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
				{
					puts_P(PSTR("Could not open PIMA session.\r\n"));
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				puts_P(PSTR("Turning off Device...\r\n"));

				SImage_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL);
				if (SImage_Host_ReceiveResponse(&DigitalCamera_SI_Interface))
				{
					puts_P(PSTR("Could not turn off device.\r\n"));
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;					
				}

				puts_P(PSTR("Device Off.\r\n"));

				puts_P(PSTR("Closing Session...\r\n"));

				if (SImage_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
				{
					puts_P(PSTR("Could not close PIMA session.\r\n"));
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}
				
				LEDs_SetAllLEDs(LEDMASK_USB_READY);
				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
				break;
		}
	
		SImage_Host_USBTask(&DigitalCamera_SI_Interface);
		USB_USBTask();
	}
}
Example #11
0
/** Main program entry point. This routine configures the hardware required by the application, then
 *  enters a loop to run the application tasks in sequence.
 */
int main(void)
{
	SetupHardware();

	puts_P(PSTR(ESC_FG_CYAN "CDC Host Demo running.\r\n" ESC_FG_WHITE));

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	sei();

	for (;;)
	{
		switch (USB_HostState)
		{
			case HOST_STATE_Addressed:
				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);

				uint16_t ConfigDescriptorSize;
				uint8_t  ConfigDescriptorData[512];

				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
				{
					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface,
				                            ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError)
				{
					puts_P(PSTR("Attached Device Not a Valid CDC Class Device.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
				{
					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				puts_P(PSTR("CDC Device Enumerated.\r\n"));
				LEDs_SetAllLEDs(LEDMASK_USB_READY);
				USB_HostState = HOST_STATE_Configured;
				break;
			case HOST_STATE_Configured:
				if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface))
				{
					/* Echo received bytes from the attached device through the USART */
					int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface);
					if (!(ReceivedByte < 0))
					  putchar(ReceivedByte);
				}

				break;
		}

		CDC_Host_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
Example #12
0
/** Main program entry point. This routine configures the hardware required by the application, then
 *  enters a loop to run the application tasks in sequence.
 */
int main(void)
{
	SetupHardware();

	puts_P(PSTR(ESC_FG_CYAN "Mouse Host Demo running.\r\n" ESC_FG_WHITE));
	sei();

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);

	for (;;)
	{
		switch (USB_HostState)
		{
			case HOST_STATE_Addressed:
				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);

				uint16_t ConfigDescriptorSize;
				uint8_t  ConfigDescriptorData[512];

				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
				{
					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
				{
					puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
				{
					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0)
				{
					puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n"));
					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
					break;
				}

				puts_P(PSTR("Mouse Enumerated.\r\n"));
				LEDs_SetAllLEDs(LEDMASK_USB_READY);
				USB_HostState = HOST_STATE_Configured;
				break;
			case HOST_STATE_Configured:
				if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
				{
					uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize];
					HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);

					uint8_t LEDMask = LEDS_NO_LEDS;

					for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
					{
						HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];

						/* Update the report item value if it is contained within the current report */
						if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
						  continue;

						/* Determine what report item is being tested, process updated value as needed */
						if ((ReportItem->Attributes.Usage.Page        == USAGE_PAGE_BUTTON) &&
							(ReportItem->ItemType                     == HID_REPORT_ITEM_In))
						{
							if (ReportItem->Value)
							  LEDMask = LEDS_ALL_LEDS;
						}
						else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
								 (ReportItem->Attributes.Usage.Usage  == USAGE_SCROLL_WHEEL)       &&
								 (ReportItem->ItemType                == HID_REPORT_ITEM_In))
						{
							int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);

							if (WheelDelta)
							  LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
						}
						else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
								 ((ReportItem->Attributes.Usage.Usage == USAGE_X)                  ||
								  (ReportItem->Attributes.Usage.Usage == USAGE_Y))                 &&
								 (ReportItem->ItemType                == HID_REPORT_ITEM_In))
						{
							int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);

							if (DeltaMovement)
							{
								if (ReportItem->Attributes.Usage.Usage == USAGE_X)
								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
								else
								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
							}
						}
					}

					LEDs_SetAllLEDs(LEDMask);
				}

				break;
		}

		HID_Host_USBTask(&Mouse_HID_Interface);
		USB_USBTask();
	}
}