From 8c6c27d88bb40ecf55f369fc4499ec990d2d93d2 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 25 Nov 2009 03:26:57 +0000 Subject: 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. --- LUFA/Drivers/USB/Class/Host/CDC.c | 66 +++++++++++++++++----- LUFA/Drivers/USB/Class/Host/CDC.h | 5 ++ LUFA/Drivers/USB/LowLevel/HostChapter9.c | 10 ++-- LUFA/Drivers/USB/LowLevel/Pipe.c | 2 +- LUFA/Drivers/USB/LowLevel/Pipe.h | 2 +- .../USB/LowLevel/Template/Template_Pipe_RW.c | 2 +- 6 files changed, 66 insertions(+), 21 deletions(-) (limited to 'LUFA/Drivers/USB') diff --git a/LUFA/Drivers/USB/Class/Host/CDC.c b/LUFA/Drivers/USB/Class/Host/CDC.c index 2d42be65f..e284492a4 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.c +++ b/LUFA/Drivers/USB/Class/Host/CDC.c @@ -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(); diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h index 0ead68ce9..4e035d97e 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.h +++ b/LUFA/Drivers/USB/Class/Host/CDC.h @@ -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 { diff --git a/LUFA/Drivers/USB/LowLevel/HostChapter9.c b/LUFA/Drivers/USB/LowLevel/HostChapter9.c index 42e3262ff..8b104ef7a 100644 --- a/LUFA/Drivers/USB/LowLevel/HostChapter9.c +++ b/LUFA/Drivers/USB/LowLevel/HostChapter9.c @@ -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) diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c index ccab07413..fd8f81bc6 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.c +++ b/LUFA/Drivers/USB/LowLevel/Pipe.c @@ -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; diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.h b/LUFA/Drivers/USB/LowLevel/Pipe.h index c04849167..97257d706 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.h +++ b/LUFA/Drivers/USB/LowLevel/Pipe.h @@ -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 diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Pipe_RW.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Pipe_RW.c index d003e4073..ef8035d50 100644 --- a/LUFA/Drivers/USB/LowLevel/Template/Template_Pipe_RW.c +++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Pipe_RW.c @@ -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; -- cgit v1.2.3