forked from mfulz_github/qmk_firmware
Added new RNDISHost Host LowLevel demo. Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction. Fixed CDCHost failing on devices with bidirectional endpoints.
This commit is contained in:
parent
c05c7c7df4
commit
8c6c27d88b
|
@ -216,8 +216,9 @@ void CDC_Host_Task(void)
|
|||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and the data IN pipe */
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(CDC_DATAPIPE_IN);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
|
|
|
@ -145,6 +145,10 @@ uint8_t ProcessConfigurationDescriptor(void)
|
|||
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
/* Kill the configured OUT pipe if the data endpoints are bidirectional */
|
||||
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
|
||||
Pipe_DisablePipe();
|
||||
|
||||
/* Configure the data IN pipe */
|
||||
Pipe_ConfigurePipe(CDC_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
|
@ -154,9 +158,13 @@ uint8_t ProcessConfigurationDescriptor(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Configure the data OUT pipe */
|
||||
Pipe_ConfigurePipe(CDC_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
/* Only configure the OUT data pipe if the data endpoints haev not shown to be bidirectional */
|
||||
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress)))
|
||||
{
|
||||
/* Configure the data OUT pipe */
|
||||
Pipe_ConfigurePipe(CDC_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
}
|
||||
|
||||
/* Set the flag indicating that the data OUT pipe has been found */
|
||||
FoundEndpoints |= (1 << CDC_DATAPIPE_OUT);
|
||||
|
|
|
@ -145,6 +145,10 @@ uint8_t ProcessConfigurationDescriptor(void)
|
|||
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
/* Kill the configured OUT pipe if the data endpoints are bidirectional */
|
||||
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
|
||||
Pipe_DisablePipe();
|
||||
|
||||
/* Configure the data IN pipe */
|
||||
Pipe_ConfigurePipe(RNDIS_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
|
@ -154,9 +158,13 @@ uint8_t ProcessConfigurationDescriptor(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Configure the data OUT pipe */
|
||||
Pipe_ConfigurePipe(RNDIS_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
/* Only configure the OUT data pipe if the data endpoints haev not shown to be bidirectional */
|
||||
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress)))
|
||||
{
|
||||
/* Configure the data OUT pipe */
|
||||
Pipe_ConfigurePipe(RNDIS_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
|
||||
}
|
||||
|
||||
/* Set the flag indicating that the data OUT pipe has been found */
|
||||
FoundEndpoints |= (1 << RNDIS_DATAPIPE_OUT);
|
File diff suppressed because it is too large
Load Diff
|
@ -30,14 +30,23 @@
|
|||
|
||||
/** \file
|
||||
*
|
||||
* RNDOS Device commands, to issue RNDIS commands to the device for
|
||||
* RNDIS Device commands, to issue RNDIS commands to the device for
|
||||
* the control and data transfer between the host and RNDIS device.
|
||||
*/
|
||||
|
||||
#include "RNDISCommands.h"
|
||||
|
||||
/** Current RNDIS Request ID, for associating sent commands with received data */
|
||||
uint32_t RequestID = 0;
|
||||
|
||||
|
||||
/** Function to send the given encapsulated RNDIS command to the device.
|
||||
*
|
||||
* \param[in] Buffer Source command data buffer to send to the device
|
||||
* \param[in] Bytes Number of bytes to send
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_SendEncapsulatedCommand(void* Buffer, uint16_t Length)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
|
@ -55,6 +64,13 @@ uint8_t RNDIS_SendEncapsulatedCommand(void* Buffer, uint16_t Length)
|
|||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
/** Function to receive the given encapsulated RNDIS response from the device.
|
||||
*
|
||||
* \param[out] Buffer Destination command data buffer to write read data from the device to
|
||||
* \param[in] Bytes Number of bytes to read
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_GetEncapsulatedResponse(void* Buffer, uint16_t Length)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
|
@ -72,6 +88,11 @@ uint8_t RNDIS_GetEncapsulatedResponse(void* Buffer, uint16_t Length)
|
|||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
/** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods
|
||||
* of long inactivity.
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_SendKeepAlive(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
@ -98,6 +119,13 @@ uint8_t RNDIS_SendKeepAlive(void)
|
|||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
/** Initializes the attached RNDIS device's RNDIS interface.
|
||||
*
|
||||
* \param[in] HostMaxPacketSize Size of the packet buffer on the host
|
||||
* \param[out] DeviceMaxPacketSize Pointer to where the packet buffer size of the device is to be stored
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_InitializeDevice(uint16_t HostMaxPacketSize, uint16_t* DeviceMaxPacketSize)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
@ -133,6 +161,14 @@ uint8_t RNDIS_InitializeDevice(uint16_t HostMaxPacketSize, uint16_t* DeviceMaxPa
|
|||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
/** Sets a given RNDIS property of an attached RNDIS device.
|
||||
*
|
||||
* \param[in] Oid OID number of the parameter to set
|
||||
* \param[in] Buffer Pointer to where the property data is to be sourced from
|
||||
* \param[in] Length Length in bytes of the property data to sent to the device
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_SetRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
@ -174,6 +210,14 @@ uint8_t RNDIS_SetRNDISProperty(uint32_t Oid, void* Buffer, uint16_t Length)
|
|||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
/** Gets a given RNDIS property of an attached RNDIS device.
|
||||
*
|
||||
* \param[in] Oid OID number of the parameter to get
|
||||
* \param[in] Buffer Pointer to where the property data is to be written to
|
||||
* \param[in] MaxLength Length in bytes of the destination buffer size
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_QueryRNDISProperty(uint32_t Oid, void* Buffer, uint16_t MaxLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
@ -215,10 +259,28 @@ uint8_t RNDIS_QueryRNDISProperty(uint32_t Oid, void* Buffer, uint16_t MaxLength)
|
|||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
/** Retrieves the size of a received packet, discarding the remainder of the RNDIS packet header to leave only the
|
||||
* packet contents for processing by the host.
|
||||
*
|
||||
* \param[out] PacketLength Size of the packet currently in the pipe
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
|
||||
*/
|
||||
uint8_t RNDIS_GetPacketLength(uint16_t* PacketLength)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(RNDIS_DATAPIPE_IN);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
*PacketLength = 0;
|
||||
Pipe_Freeze();
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
||||
|
||||
RNDIS_Packet_Message_t DeviceMessage;
|
||||
|
||||
if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t))) != PIPE_RWSTREAM_NoError)
|
||||
|
@ -230,5 +292,7 @@ uint8_t RNDIS_GetPacketLength(uint16_t* PacketLength)
|
|||
|
||||
Pipe_Discard_Stream(DeviceMessage.DataOffset - (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)));
|
||||
|
||||
Pipe_Freeze();
|
||||
|
||||
return PIPE_RWSTREAM_NoError;
|
||||
}
|
|
@ -125,18 +125,7 @@ void PrintIncommingPackets(void)
|
|||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(RNDIS_DATAPIPE_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
{
|
||||
Pipe_Freeze();
|
||||
return;
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("DATA IN\r\n"));
|
||||
|
||||
uint16_t PacketLength;
|
||||
if ((ErrorCode = RNDIS_GetPacketLength(&PacketLength)) != HOST_SENDCONTROL_Successful)
|
||||
|
@ -145,6 +134,11 @@ void PrintIncommingPackets(void)
|
|||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(PacketLength))
|
||||
return;
|
||||
|
||||
Pipe_Unfreeze();
|
||||
|
||||
printf_P(PSTR("***PACKET (Size %d)***\r\n"), PacketLength);
|
||||
|
||||
|
@ -163,12 +157,12 @@ void PrintIncommingPackets(void)
|
|||
printf("%02x ", PacketBuffer[i]);
|
||||
}
|
||||
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
|
||||
printf("\r\n\r\n");
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
Pipe_ClearIN();
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
|
@ -246,25 +240,7 @@ void RNDIS_Host_Task(void)
|
|||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t RetrievedPacketFilter;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&RetrievedPacketFilter, sizeof(RetrievedPacketFilter))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Getting 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;
|
||||
}
|
||||
|
||||
if (RetrievedPacketFilter != PacketFilter)
|
||||
printf("ERROR: Retrieved Packet Filter 0x%08lx != Set Packet Filter 0x%08lx!\r\n", RetrievedPacketFilter, PacketFilter);
|
||||
|
||||
uint32_t VendorID;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
|
|
@ -0,0 +1,62 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage RNDIS Host Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Host</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Remote NDIS (Microsoft Proprietary CDC Class Networking Standard)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>Microsoft RNDIS Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* RNDIS host demonstration application. This gives a simple reference
|
||||
* application for implementing a RNDIS Ethernet host, for USB devices such as
|
||||
* modems.
|
||||
*
|
||||
* This demo will enumerate an attached USB RNDIS device, print out its vendor ID
|
||||
* and any received packets in raw form through the serial USART.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
|
@ -78,7 +78,10 @@ void SImage_SendBlockHeader(void)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Function to receive a PIMA event container from the attached still image device. */
|
||||
/** Function to receive a PIMA event container from the attached still image device.
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
|
||||
/
|
||||
uint8_t SImage_ReceiveEventHeader(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
@ -99,7 +102,10 @@ uint8_t SImage_ReceiveEventHeader(void)
|
|||
return ErrorCode;
|
||||
}
|
||||
|
||||
/** Function to receive a PIMA response container from the attached still image device. */
|
||||
/** Function to receive a PIMA response container from the attached still image device.
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
|
||||
*/
|
||||
uint8_t SImage_ReceiveBlockHeader(void)
|
||||
{
|
||||
uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;
|
||||
|
@ -189,6 +195,8 @@ uint8_t SImage_ReceiveBlockHeader(void)
|
|||
*
|
||||
* \param[in] Buffer Source data buffer to send to the device
|
||||
* \param[in] Bytes Number of bytes to send
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
|
||||
*/
|
||||
uint8_t SImage_SendData(void* Buffer, uint16_t Bytes)
|
||||
{
|
||||
|
|
|
@ -15,34 +15,37 @@
|
|||
|
||||
all:
|
||||
make -C CDCHost clean
|
||||
make -C CDCHost all
|
||||
make -C CDCHost all
|
||||
|
||||
make -C GenericHIDHost clean
|
||||
make -C GenericHIDHost all
|
||||
make -C GenericHIDHost all
|
||||
|
||||
make -C JoystickHostWithParser clean
|
||||
make -C JoystickHostWithParser all
|
||||
make -C JoystickHostWithParser all
|
||||
|
||||
make -C KeyboardHost clean
|
||||
make -C KeyboardHost all
|
||||
make -C KeyboardHost all
|
||||
|
||||
make -C MassStorageHost clean
|
||||
make -C MassStorageHost all
|
||||
make -C MassStorageHost all
|
||||
|
||||
make -C MIDIHost clean
|
||||
make -C MIDIHost all
|
||||
make -C MIDIHost all
|
||||
|
||||
make -C MouseHost clean
|
||||
make -C MouseHost all
|
||||
make -C MouseHost all
|
||||
|
||||
make -C MouseHostWithParser clean
|
||||
make -C MouseHostWithParser all
|
||||
make -C MouseHostWithParser all
|
||||
|
||||
make -C PrinterHost clean
|
||||
make -C PrinterHost all
|
||||
make -C PrinterHost all
|
||||
|
||||
make -C StillImageHost clean
|
||||
make -C StillImageHost all
|
||||
make -C StillImageHost all
|
||||
|
||||
make -C RNDISHost clean
|
||||
make -C RNDISHost all
|
||||
|
||||
%:
|
||||
make -C CDCHost $@
|
||||
|
@ -56,3 +59,4 @@ all:
|
|||
make -C MouseHostWithParser $@
|
||||
make -C PrinterHost $@
|
||||
make -C StillImageHost $@
|
||||
make -C RNDISHost $@
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -95,7 +95,7 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo
|
|||
if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
|
||||
{
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
{
|
||||
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
|
@ -110,18 +110,32 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo
|
|||
{
|
||||
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
|
||||
{
|
||||
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
|
||||
{
|
||||
BidirectionalDataEndpoints = true;
|
||||
Pipe_DisablePipe();
|
||||
}
|
||||
|
||||
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
|
||||
|
||||
FoundEndpoints |= CDC_FOUND_DATAPIPE_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
|
||||
{
|
||||
BidirectionalDataEndpoints = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
|
||||
EndpointData->EndpointAddress, EndpointData->EndpointSize,
|
||||
CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
|
||||
}
|
||||
|
||||
CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
|
||||
|
||||
FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT;
|
||||
|
@ -180,8 +194,7 @@ static uint8_t DComp_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescri
|
|||
|
||||
uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
|
||||
|
||||
if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) &&
|
||||
!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
|
||||
if ((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT))
|
||||
{
|
||||
return DESCRIPTOR_SEARCH_Found;
|
||||
}
|
||||
|
@ -199,7 +212,8 @@ void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
|||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
|
@ -263,10 +277,22 @@ uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ch
|
|||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
|
||||
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
|
||||
{
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
|
||||
}
|
||||
|
||||
Pipe_Unfreeze();
|
||||
ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
|
||||
Pipe_Freeze();
|
||||
|
||||
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
@ -278,7 +304,16 @@ uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, cons
|
|||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
|
||||
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
|
||||
{
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
|
||||
}
|
||||
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (!(Pipe_IsReadWriteAllowed()))
|
||||
|
@ -291,6 +326,9 @@ uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, cons
|
|||
|
||||
Pipe_Write_Byte(Data);
|
||||
Pipe_Freeze();
|
||||
|
||||
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
@ -302,7 +340,8 @@ uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo
|
|||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return BytesInPipe;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if (Pipe_IsINReceived() && !(Pipe_BytesInPipe()))
|
||||
|
@ -321,7 +360,8 @@ uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
|
|||
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
|
||||
return ReceivedByte;
|
||||
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
ReceivedByte = Pipe_Read_Byte();
|
||||
|
|
|
@ -88,6 +88,11 @@
|
|||
uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe */
|
||||
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
|
||||
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification pipe, if used */
|
||||
|
||||
bool BidirectionalDataEndpoints; /**< Indicates if the attached CDC interface uses bidirectional data endpoints,
|
||||
* and this has only the IN pipe configured (with \ref Pipe_SetPipeToken()
|
||||
* used to switch the pipe's direction
|
||||
*/
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
|||
if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_SETUP);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_SETUP);
|
||||
Pipe_ClearErrorFlags();
|
||||
|
||||
Pipe_Unfreeze();
|
||||
|
@ -68,7 +68,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
|||
|
||||
if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)
|
||||
{
|
||||
Pipe_SetToken(PIPE_TOKEN_IN);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
|
||||
if (DataStream != NULL)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
|||
}
|
||||
}
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_OUT);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
|
||||
|
@ -108,7 +108,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
|||
{
|
||||
if (DataStream != NULL)
|
||||
{
|
||||
Pipe_SetToken(PIPE_TOKEN_OUT);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
while (DataLen)
|
||||
|
@ -131,7 +131,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_IN);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)
|
||||
|
|
|
@ -130,7 +130,7 @@ uint8_t Pipe_Discard_Stream(uint16_t Length
|
|||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_IN);
|
||||
Pipe_SetPipeToken(PIPE_TOKEN_IN);
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
|
|
@ -432,7 +432,7 @@
|
|||
|
||||
#define Pipe_GetPipeToken() (UPCFG0X & PIPE_TOKEN_MASK)
|
||||
|
||||
#define Pipe_SetToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | (token)); }MACROE
|
||||
#define Pipe_SetPipeToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | (token)); }MACROE
|
||||
|
||||
#define Pipe_SetInfiniteINRequests() MACROS{ UPCONX |= (1 << INMODE); }MACROE
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, uint16_t Length __CALLB
|
|||
uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
|
||||
uint8_t ErrorCode;
|
||||
|
||||
Pipe_SetToken(TEMPLATE_TOKEN);
|
||||
Pipe_SetPipeToken(TEMPLATE_TOKEN);
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* - Added activity LED indicators to the AVRISP project to indicate when the device is busy processing a command
|
||||
* - The USB target family and allowable USB mode tokens are now public and documented (USB_CAN_BE_*, USB_SERIES_*_AVR)
|
||||
* - Added new XPLAIN serial Bridge project (thanks to John Steggall)
|
||||
* - Added new RNDISHost Host LowLevel demo
|
||||
*
|
||||
* <b>Changed:</b>
|
||||
* - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes
|
||||
|
@ -29,6 +30,8 @@
|
|||
* - Fixed broken USB_GetNextDescriptor() function causing the descriptor to jump ahead double the expected amount
|
||||
* - Fixed Pipe_IsEndpointBound() not masking the given Endpoint Address against PIPE_EPNUM_MASK
|
||||
* - Fixed host state machine not enabling Auto VBUS mode when HOST_DEVICE_SETTLE_DELAY_MS is set to zero
|
||||
* - Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction
|
||||
* - Fixed CDCHost failing on devices with bidirectional endpoints
|
||||
*
|
||||
* \section Sec_ChangeLog091122 Version 091122
|
||||
*
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
* USB HID class
|
||||
* - <b>PrinterHost</b> - Printer host demo, using the low level LUFA APIs to implement the USB Printer class
|
||||
* - <b>StillImageHost</b> - Still Image Camera host demo, using the low level LUFA APIs to implement the USB Still Image class
|
||||
* - <b>RNDISHost</b> - RNDIS Ethernet host demo, using the low level LUFA APIs to implement the RNDIS class
|
||||
* - <b>Incomplete</b>
|
||||
* - <b>BluetoothHost</b> - Incomplete Bluetooth host demo, using the low level LUFA APIs to implement the USB Bluetooth class
|
||||
* - <b>DualRole</b>
|
||||
|
|
|
@ -117,13 +117,17 @@ void SetupHardware(void)
|
|||
|
||||
/* Hardware Initialization */
|
||||
SoftUART_Init();
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
|
||||
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "Lib/SoftUART.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ MCU = at90usb1287
|
|||
# Target board (see library "Board Types" documentation, USER or blank for projects not requiring
|
||||
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
|
||||
# "Board" inside the application directory.
|
||||
BOARD = USER
|
||||
BOARD = XPLAIN
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
|
|
Loading…
Reference in New Issue