Fixed CDC and RNDIS host demos and class drivers - bidirectional endpoints should use two seperate pipes, not one half-duplex pipe.

pull/1469/head
Dean Camera 15 years ago
parent 74b6993d66
commit 431db89b00

@ -145,10 +145,6 @@ uint8_t ProcessConfigurationDescriptor(void)
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */ /* Check if the endpoint is a bulk IN or bulk OUT endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) 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 */ /* Configure the data IN pipe */
Pipe_ConfigurePipe(RNDIS_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN, Pipe_ConfigurePipe(RNDIS_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE); EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
@ -158,13 +154,9 @@ uint8_t ProcessConfigurationDescriptor(void)
} }
else else
{ {
/* Only configure the OUT data pipe if the data endpoints have not shown to be bidirectional */ /* Configure the data OUT pipe */
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress))) Pipe_ConfigurePipe(RNDIS_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
{ EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* 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 */ /* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << RNDIS_DATAPIPE_OUT); FoundEndpoints |= (1 << RNDIS_DATAPIPE_OUT);

@ -145,10 +145,6 @@ uint8_t ProcessConfigurationDescriptor(void)
/* Check if the endpoint is a bulk IN or bulk OUT endpoint */ /* Check if the endpoint is a bulk IN or bulk OUT endpoint */
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) 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 */ /* Configure the data IN pipe */
Pipe_ConfigurePipe(CDC_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN, Pipe_ConfigurePipe(CDC_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE); EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
@ -158,13 +154,9 @@ uint8_t ProcessConfigurationDescriptor(void)
} }
else else
{ {
/* Only configure the OUT data pipe if the data endpoints have not shown to be bidirectional */ /* Configure the data OUT pipe */
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress))) Pipe_ConfigurePipe(CDC_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
{ EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
/* 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 */ /* Set the flag indicating that the data OUT pipe has been found */
FoundEndpoints |= (1 << CDC_DATAPIPE_OUT); FoundEndpoints |= (1 << CDC_DATAPIPE_OUT);

@ -218,7 +218,6 @@ void CDC_Host_Task(void)
case HOST_STATE_Configured: case HOST_STATE_Configured:
/* Select the data IN pipe */ /* Select the data IN pipe */
Pipe_SelectPipe(CDC_DATAPIPE_IN); Pipe_SelectPipe(CDC_DATAPIPE_IN);
Pipe_SetPipeToken(PIPE_TOKEN_IN);
Pipe_Unfreeze(); Pipe_Unfreeze();
/* Check to see if a packet has been received */ /* Check to see if a packet has been received */

@ -110,32 +110,20 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo
{ {
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{ {
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
{
CDCInterfaceInfo->State.BidirectionalDataEndpoints = true;
Pipe_DisablePipe();
}
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize; CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_IN; FoundEndpoints |= CDC_FOUND_DATAPIPE_IN;
} }
else else
{ {
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress)) Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
{ EndpointData->EndpointAddress, EndpointData->EndpointSize,
CDCInterfaceInfo->State.BidirectionalDataEndpoints = true; CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
}
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; CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT; FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT;
@ -277,22 +265,11 @@ uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ch
uint8_t ErrorCode; uint8_t ErrorCode;
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints) Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
}
else
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
}
Pipe_Unfreeze(); Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK); ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
Pipe_Freeze(); Pipe_Freeze();
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
Pipe_SetPipeToken(PIPE_TOKEN_IN);
return ErrorCode; return ErrorCode;
} }
@ -304,16 +281,7 @@ uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, cons
uint8_t ErrorCode; uint8_t ErrorCode;
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints) Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
}
else
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
}
Pipe_Unfreeze(); Pipe_Unfreeze();
if (!(Pipe_IsReadWriteAllowed())) if (!(Pipe_IsReadWriteAllowed()))
@ -326,9 +294,6 @@ uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, cons
Pipe_Write_Byte(Data); Pipe_Write_Byte(Data);
Pipe_Freeze(); Pipe_Freeze();
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
Pipe_SetPipeToken(PIPE_TOKEN_IN);
return PIPE_READYWAIT_NoError; return PIPE_READYWAIT_NoError;
} }
@ -381,16 +346,7 @@ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
uint8_t ErrorCode; uint8_t ErrorCode;
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints) Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
}
else
{
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
}
Pipe_Unfreeze(); Pipe_Unfreeze();
if (!(Pipe_BytesInPipe())) if (!(Pipe_BytesInPipe()))
@ -409,9 +365,6 @@ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
} }
Pipe_Freeze(); Pipe_Freeze();
if (CDCInterfaceInfo->State.BidirectionalDataEndpoints)
Pipe_SetPipeToken(PIPE_TOKEN_IN);
return PIPE_READYWAIT_NoError; return PIPE_READYWAIT_NoError;
} }

@ -89,11 +89,6 @@
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT 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 */ 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 struct
{ {
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_* uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*

@ -110,12 +110,6 @@ uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfa
{ {
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{ {
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress))
{
RNDISInterfaceInfo->State.BidirectionalDataEndpoints = true;
Pipe_DisablePipe();
}
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN, Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE); RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
@ -125,17 +119,10 @@ uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfa
} }
else else
{ {
if (Pipe_IsEndpointBound(EndpointData->EndpointAddress)) Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
{ EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->State.BidirectionalDataEndpoints = true; RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
}
else
{
Pipe_ConfigurePipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize,
RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
}
RNDISInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize; RNDISInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
FoundEndpoints |= RNDIS_FOUND_DATAPIPE_OUT; FoundEndpoints |= RNDIS_FOUND_DATAPIPE_OUT;
@ -422,27 +409,11 @@ uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn
RNDIS_Packet_Message_t DeviceMessage; RNDIS_Packet_Message_t DeviceMessage;
if (Pipe_BytesInPipe() < sizeof(RNDIS_Packet_Message_t))
{
printf("*SIZE YARG: %d*\r\n", Pipe_BytesInPipe());
*PacketLength = 0;
Pipe_ClearIN();
return RNDIS_COMMAND_FAILED;
}
if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{ {
return ErrorCode; return ErrorCode;
} }
if (DeviceMessage.MessageType != REMOTE_NDIS_PACKET_MSG)
{
printf("****YARG****\r\n");
*PacketLength = 0;
Pipe_ClearIN();
return RNDIS_COMMAND_FAILED;
}
*PacketLength = (uint16_t)DeviceMessage.DataLength; *PacketLength = (uint16_t)DeviceMessage.DataLength;
@ -466,16 +437,6 @@ uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn
if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected; return PIPE_READYWAIT_DeviceDisconnected;
if (RNDISInterfaceInfo->State.BidirectionalDataEndpoints)
{
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
Pipe_SetPipeToken(PIPE_TOKEN_OUT);
}
else
{
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
}
RNDIS_Packet_Message_t DeviceMessage; RNDIS_Packet_Message_t DeviceMessage;
memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t)); memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
@ -484,14 +445,12 @@ uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn
DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
DeviceMessage.DataLength = PacketLength; DeviceMessage.DataLength = PacketLength;
Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_Unfreeze(); Pipe_Unfreeze();
if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
{ {
if (RNDISInterfaceInfo->State.BidirectionalDataEndpoints)
Pipe_SetPipeToken(PIPE_TOKEN_IN);
return ErrorCode; return ErrorCode;
} }
@ -500,9 +459,6 @@ uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn
Pipe_Freeze(); Pipe_Freeze();
if (RNDISInterfaceInfo->State.BidirectionalDataEndpoints)
Pipe_SetPipeToken(PIPE_TOKEN_IN);
return PIPE_RWSTREAM_NoError; return PIPE_RWSTREAM_NoError;
} }

@ -90,12 +90,8 @@
uint16_t DataINPipeSize; /**< Size in bytes of the RNDIS interface's IN data pipe */ uint16_t DataINPipeSize; /**< Size in bytes of the RNDIS interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the RNDIS interface's OUT data pipe */ uint16_t DataOUTPipeSize; /**< Size in bytes of the RNDIS interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the RNDIS interface's IN notification pipe, if used */ uint16_t NotificationPipeSize; /**< Size in bytes of the RNDIS interface's IN notification pipe, if used */
bool BidirectionalDataEndpoints; /**< Indicates if the attached RNDIS interface uses bidirectional data endpoints,
* and this has only the IN pipe configured (with \ref Pipe_SetPipeToken()
* used to switch the pipe's direction)
*/
uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device */ uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device */
uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair */ uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair */

@ -45,6 +45,7 @@
* - Fixed Benito project not resetting the target AVR automatically when programming has completed * - Fixed Benito project not resetting the target AVR automatically when programming has completed
* - Fixed DFU bootloader programming not discarding the correct number of filler bytes from the host when non-aligned programming * - Fixed DFU bootloader programming not discarding the correct number of filler bytes from the host when non-aligned programming
* ranges are specified (thanks to Thomas Bleeker) * ranges are specified (thanks to Thomas Bleeker)
* - Fixed CDC and RNDIS host demos and class drivers - bidirectional endpoints should use two seperate pipes, not one half-duplex pipe
* *
* \section Sec_ChangeLog091223 Version 091223 * \section Sec_ChangeLog091223 Version 091223
* *

@ -65,7 +65,8 @@ char PROGMEM HTTPPage[] =
" <body>" " <body>"
" <h1>Hello from your USB AVR!</h1>" " <h1>Hello from your USB AVR!</h1>"
" <p>" " <p>"
" Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack." " Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library and uIP TCP/IP network stack. This"
" demonstrates a simple HTTP webserver serving out pages to HTTP clients."
" <br /><br />" " <br /><br />"
" <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>" " <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"
" <hr />" " <hr />"

@ -174,7 +174,7 @@ void ProcessIncommingPacket(void)
LEDs_SetAllLEDs(LEDMASK_USB_BUSY); LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
/* Read the incomming packet straight into the UIP packet buffer */ /* Read the incomming packet straight into the UIP packet buffer */
printf("L=%d R=%d\r\n", uip_len, RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], &uip_len)); RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], &uip_len);
if (uip_len > 0) if (uip_len > 0)
{ {

Loading…
Cancel
Save