diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2009-08-11 01:52:15 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2009-08-11 01:52:15 +0000 |
commit | 8711dc7ced0ed02a33a96222d86bd27f65c239ed (patch) | |
tree | 0903f849fab0d0d26d6d5bd1af94327faebb7939 /LUFA/Drivers/USB | |
parent | a459f10b0c1a3e02f160ff3a1a2a0b45ae5b69a7 (diff) | |
download | lufa-8711dc7ced0ed02a33a96222d86bd27f65c239ed.tar.gz lufa-8711dc7ced0ed02a33a96222d86bd27f65c239ed.tar.bz2 lufa-8711dc7ced0ed02a33a96222d86bd27f65c239ed.zip |
Fix issue in CDC device class driver where received data the size of the data endpoint could lock up the driver.
Further work on the new CDC and HID host mode class drivers.
Reset changelog et. al. to reset development information for the new version currently under development.
Diffstat (limited to 'LUFA/Drivers/USB')
-rw-r--r-- | LUFA/Drivers/USB/Class/Device/CDC.c | 3 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/CDC.c | 113 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/CDC.h | 9 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/HID.c | 8 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/HID.h | 4 |
5 files changed, 135 insertions, 2 deletions
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c index 0d6b37850..47290ceb6 100644 --- a/LUFA/Drivers/USB/Class/Device/CDC.c +++ b/LUFA/Drivers/USB/Class/Device/CDC.c @@ -161,6 +161,9 @@ uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterface {
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
+ if (Endpoint_IsOUTReceived() && !(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
return Endpoint_BytesInEndpoint();
}
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.c b/LUFA/Drivers/USB/Class/Host/CDC.c index b7a192ac0..e0e15e145 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.c +++ b/LUFA/Drivers/USB/Class/Host/CDC.c @@ -51,6 +51,13 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint {
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
+
+ CDCInterfaceInfo->State.ControlInterfaceNumber =
+#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
+ DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).InterfaceNumber;
+#else
+ DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_Interface_t).bInterfaceNumber;
+#endif
while (FoundEndpoints != (CDC_FOUND_DATAPIPE_IN | CDC_FOUND_DATAPIPE_OUT | CDC_FOUND_DATAPIPE_NOTIFICATION))
{
@@ -126,6 +133,7 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint }
}
+ CDCInterfaceInfo->State.Active = true;
return CDC_ENUMERROR_NoError;
}
@@ -190,6 +198,111 @@ static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescript void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
{
+ EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo);
+}
+
+uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = REQ_SetControlLineState,
+ .wValue = 0,
+ .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = sizeof(CDCInterfaceInfo->State.LineEncoding),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding);
+}
+
+uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = REQ_SetControlLineState,
+ .wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice,
+ .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.Active))
+ return;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+ Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+ Pipe_Freeze();
+}
+
+void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.Active))
+ return;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ {
+ Pipe_ClearOUT();
+ Pipe_WaitUntilReady();
+ }
+
+ Pipe_Write_Byte(Data);
+ Pipe_Freeze();
+}
+
+uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
+{
+ uint16_t BytesInPipe = 0;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.Active))
+ return BytesInPipe;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsINReceived() && !(Pipe_BytesInPipe()))
+ Pipe_ClearIN();
+
+ BytesInPipe = Pipe_BytesInPipe();
+ Pipe_Freeze();
+
+ return BytesInPipe;
+}
+
+uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
+{
+ uint8_t ReceivedByte = 0;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.Active))
+ return ReceivedByte;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ ReceivedByte = Pipe_Read_Byte();
+
+ if (!(Pipe_BytesInPipe()))
+ Pipe_ClearIN();
+
+ Pipe_Freeze();
+
+ return ReceivedByte;
+}
+
+void CDC_Host_Event_Stub(void)
+{
}
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h index 5e0e4690c..79df489ff 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.h +++ b/LUFA/Drivers/USB/Class/Host/CDC.h @@ -71,6 +71,10 @@ */
struct
{
+ bool Active; /**< Indicates if the current interface instance is connected to an attached device */
+
+ uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device */
+
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 endpoint, if used */
@@ -118,8 +122,6 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor);
- void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
-
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
@@ -144,6 +146,9 @@ /* Function Prototypes: */
#if defined(INCLUDE_FROM_CDC_CLASS_HOST_C)
+ void CDC_Host_Event_Stub(void);
+ void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
+ ATTR_WEAK ATTR_ALIAS(CDC_Host_Event_Stub);
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor);
diff --git a/LUFA/Drivers/USB/Class/Host/HID.c b/LUFA/Drivers/USB/Class/Host/HID.c index 2f66dc2b1..3a4faffbd 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.c +++ b/LUFA/Drivers/USB/Class/Host/HID.c @@ -86,6 +86,7 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint }
}
+ HIDInterfaceInfo->State.Active = true;
return HID_ENUMERROR_NoError;
}
@@ -126,4 +127,11 @@ void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) }
+void HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
+{
+ Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
+
+ return Pipe_IsReadWriteAllowed();
+}
+
#endif
diff --git a/LUFA/Drivers/USB/Class/Host/HID.h b/LUFA/Drivers/USB/Class/Host/HID.h index 344c06f06..0386881d2 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.h +++ b/LUFA/Drivers/USB/Class/Host/HID.h @@ -78,6 +78,8 @@ */
struct
{
+ bool Active; /**< Indicates if the current interface instance is connected to an attached device */
+
uint16_t DataINPipeSize; /**< Size in bytes of the HID interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
@@ -99,6 +101,8 @@ void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo);
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor);
+
+ void HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
|