aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/USB
diff options
context:
space:
mode:
Diffstat (limited to 'LUFA/Drivers/USB')
-rw-r--r--LUFA/Drivers/USB/Class/ConfigDescriptor.h20
-rw-r--r--LUFA/Drivers/USB/Class/HIDParser.h10
-rw-r--r--LUFA/Drivers/USB/Class/HIDReportData.h10
-rw-r--r--LUFA/Drivers/USB/HighLevel/Events.h12
-rw-r--r--LUFA/Drivers/USB/HighLevel/StdDescriptors.h18
-rw-r--r--LUFA/Drivers/USB/HighLevel/StdRequestType.h24
-rw-r--r--LUFA/Drivers/USB/HighLevel/StreamCallbacks.h10
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBInterrupt.h12
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.c2
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.h10
-rw-r--r--LUFA/Drivers/USB/LowLevel/DevChapter9.c55
-rw-r--r--LUFA/Drivers/USB/LowLevel/DevChapter9.h6
-rw-r--r--LUFA/Drivers/USB/LowLevel/Device.h90
-rw-r--r--LUFA/Drivers/USB/LowLevel/Endpoint.c105
-rw-r--r--LUFA/Drivers/USB/LowLevel/Endpoint.h538
-rw-r--r--LUFA/Drivers/USB/LowLevel/Host.c2
-rw-r--r--LUFA/Drivers/USB/LowLevel/Host.h146
-rw-r--r--LUFA/Drivers/USB/LowLevel/HostChapter9.c18
-rw-r--r--LUFA/Drivers/USB/LowLevel/HostChapter9.h8
-rw-r--r--LUFA/Drivers/USB/LowLevel/LowLevel.h11
-rw-r--r--LUFA/Drivers/USB/LowLevel/OTG.h111
-rw-r--r--LUFA/Drivers/USB/LowLevel/Pipe.c65
-rw-r--r--LUFA/Drivers/USB/LowLevel/Pipe.h597
-rw-r--r--LUFA/Drivers/USB/USB.h8
24 files changed, 1267 insertions, 621 deletions
diff --git a/LUFA/Drivers/USB/Class/ConfigDescriptor.h b/LUFA/Drivers/USB/Class/ConfigDescriptor.h
index bd92b51f3..d5fcbb0bb 100644
--- a/LUFA/Drivers/USB/Class/ConfigDescriptor.h
+++ b/LUFA/Drivers/USB/Class/ConfigDescriptor.h
@@ -35,6 +35,14 @@
* and other descriptor data can be extracted and used as needed.
*/
+/** \ingroup Group_Descriptors
+ * @defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser
+ *
+ * Functions, macros, variables, enums and types related to the parsing of Configuration Descriptors.
+ *
+ * @{
+ */
+
#ifndef __CONFIGDESCRIPTOR_H__
#define __CONFIGDESCRIPTOR_H__
@@ -109,7 +117,7 @@
* for certain descriptors matching unique criteria.
*
* Comparator routines are passed in a single pointer named CurrentDescriptor, and should return a value
- * of a member of the DSEARCH_Return_ErrorCodes_t enum.
+ * of a member of the DSearch_Return_ErrorCodes_t enum.
*/
#define DESCRIPTOR_COMPARATOR(name) uint8_t DCOMP_##name (void* const CurrentDescriptor)
@@ -124,7 +132,7 @@
* \param DPos Pointer to the current position in the configuration descriptor
* \param DSearch Name of the comparator search function to use on the configuration descriptor
*
- * \return Value of one of the members of the DSEARCH_Comp_Return_ErrorCodes_t enum
+ * \return Value of one of the members of the DSearch_Comp_Return_ErrorCodes_t enum
*
* Usage Example:
* \code
@@ -151,7 +159,7 @@
USB_Host_GetNextDescriptorComp_P(DSize, DPos, DCOMP_##DSearch)
/* Enums: */
/** Enum for return values of a descriptor comparator made with DESCRIPTOR_COMPARATOR. */
- enum DSEARCH_Return_ErrorCodes_t
+ enum DSearch_Return_ErrorCodes_t
{
Descriptor_Search_Found = 0, /**< Current descriptor matches comparator criteria. */
Descriptor_Search_Fail = 1, /**< No further descriptor could possibly match criteria, fail the search. */
@@ -159,7 +167,7 @@
};
/** Enum for return values of USB_Host_GetNextDescriptorComp() */
- enum DSEARCH_Comp_Return_ErrorCodes_t
+ enum DSearch_Comp_Return_ErrorCodes_t
{
Descriptor_Search_Comp_Found = 0, /**< Configuration descriptor now points to descriptor which matches
* search criteria of the given comparator function. */
@@ -259,5 +267,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/Class/HIDParser.h b/LUFA/Drivers/USB/Class/HIDParser.h
index 47a678b9b..ad242fe56 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/HIDParser.h
@@ -44,6 +44,14 @@
* HID_INCLUDE_CONSTANT_DATA_ITEMS tokens in the user project makefile, passing them to the compiler via the -D
* switch.
*/
+
+/** \ingroup Group_USB
+ * @defgroup Group_HIDParser HID Report Parser
+ *
+ * Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.
+ *
+ * @{
+ */
#ifndef __HIDPARSER_H__
#define __HIDPARSER_H__
@@ -250,3 +258,5 @@
#endif
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/Class/HIDReportData.h b/LUFA/Drivers/USB/Class/HIDReportData.h
index b1468a31a..eee38be04 100644
--- a/LUFA/Drivers/USB/Class/HIDReportData.h
+++ b/LUFA/Drivers/USB/Class/HIDReportData.h
@@ -34,6 +34,14 @@
* flag's meaning when applied to an IN, OUT or FEATURE item.
*/
+/** \ingroup Group_HIDParser
+ * @defgroup Group_HIDIOFConst Input/Output/Feature Masks
+ *
+ * Masks indicating the type of Input, Output of Feature HID report item.
+ *
+ * @{
+ */
+
#ifndef __HIDREPORTDATA_H__
#define __HIDREPORTDATA_H__
@@ -126,5 +134,7 @@
#define TAG_LOCAL_USAGEMIN 0x10
#define TAG_LOCAL_USAGEMAX 0x20
#endif
+
+/** @} */
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h
index c9882cfc0..480e824a7 100644
--- a/LUFA/Drivers/USB/HighLevel/Events.h
+++ b/LUFA/Drivers/USB/HighLevel/Events.h
@@ -39,6 +39,14 @@
*
* Each event must only have one associated event handler, but can be raised by multiple sources.
*/
+
+/** \ingroup Group_USB
+ * @defgroup Group_Events USB Events
+ *
+ * Functions, macros, variables, enums and types related to the management of events from the USB kernel.
+ *
+ * @{
+ */
#ifndef __USBEVENTS_H__
#define __USBEVENTS_H__
@@ -436,5 +444,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/HighLevel/StdDescriptors.h b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
index d62836321..a1a051824 100644
--- a/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
+++ b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
@@ -44,6 +44,14 @@
* named counterparts, thus they can be correlated easily with the official USB specification.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_Descriptors USB Descriptors
+ *
+ * Functions, macros, variables, enums and types related to standard USB descriptors.
+ *
+ * @{
+ */
+
#ifndef __USBDESCRIPTORS_H__
#define __USBDESCRIPTORS_H__
@@ -472,12 +480,6 @@
int16_t bString[];
#endif
} USB_Descriptor_String_t;
-
- typedef struct
- {
- uint16_t Size;
- void* Address;
- } USB_Descriptor_Details_t;
/* Function Prototypes: */
/** Function to retrieve a given descriptor's size and memory location from the given descriptor type value,
@@ -519,5 +521,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/HighLevel/StdRequestType.h b/LUFA/Drivers/USB/HighLevel/StdRequestType.h
index 423de6d9c..bf9ef8aee 100644
--- a/LUFA/Drivers/USB/HighLevel/StdRequestType.h
+++ b/LUFA/Drivers/USB/HighLevel/StdRequestType.h
@@ -34,6 +34,14 @@
* direction, request recipient, etc.) can be extracted via masking.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_StdRequest Standard USB Requests
+ *
+ * Functions, macros, variables, enums and types related to standard USB requests to USB devices.
+ *
+ * @{
+ */
+
#ifndef __STDREQTYPE_H__
#define __STDREQTYPE_H__
@@ -181,11 +189,13 @@
* device mode. */
};
-/* Private Interface - For use in library only: */
- #if !defined(__DOXYGEN__)
- /* Macros: */
- #define FEATURE_SELFPOWERED_ENABLED (1 << 0)
- #define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
- #endif
-
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define FEATURE_SELFPOWERED_ENABLED (1 << 0)
+ #define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
+ #endif
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h b/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h
index 5c2dad637..300a3f217 100644
--- a/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h
+++ b/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h
@@ -35,6 +35,14 @@
* stream read/write process.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_StreamCallbacks Endpoint and Pipe Stream Callbacks
+ *
+ * Functions, macros, variables, enums and types related to endpoint and pipe stream callback functions.
+ *
+ * @{
+ */
+
#ifndef __STREAMCALLBACK_H__
#define __STREAMCALLBACK_H__
@@ -85,3 +93,5 @@
};
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.h b/LUFA/Drivers/USB/HighLevel/USBInterrupt.h
index d54de3920..65e0b5fb1 100644
--- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.h
+++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.h
@@ -34,6 +34,14 @@
* events as VBUS interrupts (on supported USB AVR models), device connections and disconnections, etc.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_USBInterrupt Endpoint and Pipe Interrupts
+ *
+ * Functions, macros, variables, enums and types related to endpoint and pipe interrupts.
+ *
+ * @{
+ */
+
#ifndef __USBINTERRUPT_H__
#define __USBINTERRUPT_H__
@@ -220,5 +228,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c
index e62ac687f..80731ac19 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.c
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.c
@@ -64,7 +64,7 @@ static void USB_DeviceTask(void)
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
- if (Endpoint_IsSetupReceived())
+ if (Endpoint_IsSETUPReceived())
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h
index e0ca8ede8..bcf117ddb 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.h
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.h
@@ -73,6 +73,8 @@
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
+ *
+ * \ingroup Group_USBManagement
*/
extern volatile bool USB_IsConnected;
@@ -81,6 +83,8 @@
*
* \note This variable should be treated as read-only in the user application, and never manually
* changed in value.
+ *
+ * \ingroup Group_USBManagement
*/
extern volatile bool USB_IsInitialized;
@@ -94,6 +98,8 @@
*
* \note This variable should be treated as read-only in the user application, and never manually
* changed in value.
+ *
+ * \ingroup Group_Device
*/
extern volatile bool USB_IsSuspended;
#endif
@@ -107,6 +113,8 @@
* by the library.
*
* \note This global is only present if the user application can be a USB host.
+ *
+ * \ingroup Group_Host
*/
extern volatile uint8_t USB_HostState;
#endif
@@ -173,6 +181,8 @@
* event and disabled again on the firing of the USB_DeviceUnattached event.
*
* \see Events.h for more information on the USB events.
+ *
+ * \ingroup Group_USBManagement
*/
TASK(USB_USBTask);
diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.c b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
index 765627b15..19d72983b 100644
--- a/LUFA/Drivers/USB/LowLevel/DevChapter9.c
+++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
@@ -105,10 +105,10 @@ void USB_Device_ProcessControlPacket(void)
if (!(RequestHandled))
RAISE_EVENT(USB_UnhandledControlPacket, bRequest, bmRequestType);
- if (Endpoint_IsSetupReceived())
+ if (Endpoint_IsSETUPReceived())
{
Endpoint_StallTransaction();
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
}
}
@@ -116,13 +116,13 @@ static void USB_Device_SetAddress(void)
{
uint8_t wValue_LSB = Endpoint_Read_Byte();
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
UDADDR = ((1 << ADDEN) | (wValue_LSB & 0x7F));
@@ -152,11 +152,11 @@ static void USB_Device_SetConfiguration(void)
return;
}
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
USB_ConfigurationNumber = wValue_LSB;
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
if (!(AlreadyConfigured) && USB_ConfigurationNumber)
RAISE_EVENT(USB_DeviceEnumerationComplete);
@@ -166,14 +166,14 @@ static void USB_Device_SetConfiguration(void)
void USB_Device_GetConfiguration(void)
{
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
Endpoint_Write_Byte(USB_ConfigurationNumber);
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
- while (!(Endpoint_IsSetupOUTReceived()));
- Endpoint_ClearSetupOUT();
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearControlOUT();
}
static void USB_Device_GetDescriptor(void)
@@ -190,18 +190,18 @@ static void USB_Device_GetDescriptor(void)
if ((DescriptorSize = USB_GetDescriptor(wValue, wIndex, &DescriptorPointer)) == NO_DESCRIPTOR)
return;
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
if (wLength > DescriptorSize)
wLength = DescriptorSize;
while (wLength)
{
- while (!(Endpoint_IsSetupINReady()))
+ while (!(Endpoint_IsINReady()))
{
- if (Endpoint_IsSetupOUTReceived())
+ if (Endpoint_IsOUTReceived())
{
- Endpoint_ClearSetupOUT();
+ Endpoint_ClearControlOUT();
return;
}
}
@@ -220,17 +220,17 @@ static void USB_Device_GetDescriptor(void)
}
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
}
if (SendZLP)
{
- while (!(Endpoint_IsSetupINReady()));
- Endpoint_ClearSetupIN();
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearControlIN();
}
- while (!(Endpoint_IsSetupOUTReceived()));
- Endpoint_ClearSetupOUT();
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearControlOUT();
}
static void USB_Device_GetStatus(const uint8_t bmRequestType)
@@ -264,13 +264,14 @@ static void USB_Device_GetStatus(const uint8_t bmRequestType)
}
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
- Endpoint_ClearSetupReceived();
+ Endpoint_ClearControlSETUP();
+
Endpoint_Write_Word_LE(CurrentStatus);
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
- while (!(Endpoint_IsSetupOUTReceived()));
- Endpoint_ClearSetupOUT();
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearControlOUT();
}
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
@@ -305,8 +306,8 @@ static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmR
}
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
- Endpoint_ClearSetupReceived();
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlSETUP();
+ Endpoint_ClearControlIN();
}
}
diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.h b/LUFA/Drivers/USB/LowLevel/DevChapter9.h
index 2b425e7e6..6571659c1 100644
--- a/LUFA/Drivers/USB/LowLevel/DevChapter9.h
+++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.h
@@ -66,6 +66,8 @@
*
* \note This variable should be treated as read-only in the user application, and never manually
* changed in value.
+ *
+ * \ingroup Group_Device
*/
extern uint8_t USB_ConfigurationNumber;
@@ -74,12 +76,16 @@
*
* \note This variable should be treated as read-only in the user application, and never manually
* changed in value.
+ *
+ * \ingroup Group_Device
*/
extern bool USB_RemoteWakeupEnabled;
/** Indicates if the device is currently being powered by its own power supply, rather than being
* powered by the host's USB supply. This flag should remain cleared if the device does not
* support self powered mode, as indicated in the device descriptors.
+ *
+ * \ingroup Group_Device
*/
extern bool USB_CurrentlySelfPowered;
diff --git a/LUFA/Drivers/USB/LowLevel/Device.h b/LUFA/Drivers/USB/LowLevel/Device.h
index c6e5f7f5a..8a2ee00c3 100644
--- a/LUFA/Drivers/USB/LowLevel/Device.h
+++ b/LUFA/Drivers/USB/LowLevel/Device.h
@@ -33,6 +33,14 @@
* USB Device mode related macros and enums. This module contains macros and enums which are used when
* the USB controller is initialized in device mode.
*/
+
+/** \ingroup Group_USB
+ * @defgroup Group_Device Device Management
+ *
+ * Functions, macros, variables, enums and types related to the management of a USB device when in Device mode.
+ *
+ * @{
+ */
#ifndef __USBDEVICE_H__
#define __USBDEVICE_H__
@@ -64,42 +72,52 @@
*/
#define USB_DEVICE_OPT_FULLSPEED (0 << 0)
- /** Sends a Remote Wakeup request to the host. This signals to the host that the device should
- * be taken out of suspended mode, and communications should resume.
- *
- * Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the
- * host computer when the host has suspended all USB devices to enter a low power state.
- *
- * \note This macro should only be used if the device has indicated to the host that it
- * supports the Remote Wakeup feature in the device descriptors, and should only be
- * issued if the host is currently allowing remote wakeup events from the device (i.e.,
- * the USB_RemoteWakeupEnabled flag is set, see DevChapter9.h documentation).
- *
- * \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
- */
- #define USB_Device_SendRemoteWakeup() MACROS{ UDCON |= (1 << RMWKUP); }MACROE
+ /* Psuedo-Function Macros: */
+ #if defined(__DOXYGEN__)
+ /** Sends a Remote Wakeup request to the host. This signals to the host that the device should
+ * be taken out of suspended mode, and communications should resume.
+ *
+ * Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the
+ * host computer when the host has suspended all USB devices to enter a low power state.
+ *
+ * \note This macro should only be used if the device has indicated to the host that it
+ * supports the Remote Wakeup feature in the device descriptors, and should only be
+ * issued if the host is currently allowing remote wakeup events from the device (i.e.,
+ * the USB_RemoteWakeupEnabled flag is set, see DevChapter9.h documentation).
+ *
+ * \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
+ */
+ static inline void USB_Device_SendRemoteWakeup(void);
+
+ /** Indicates if a Remote Wakeup request is being sent to the host. This returns true if a
+ * remote wakeup is currently being sent, false otherwise.
+ *
+ * This can be used in conjunction with the USB_Device_IsUSBSuspended() macro to determine if
+ * a sent RMWAKEUP request was accepted or rejected by the host.
+ *
+ * \note This macro should only be used if the device has indicated to the host that it
+ * supports the Remote Wakeup feature in the device descriptors.
+ *
+ * \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
+ *
+ * \return Boolean true if no Remote Wakeup request is currently being sent, false otherwise
+ */
+ static inline bool USB_Device_IsRemoteWakeupSent(void);
+
+ /** Indicates if the device is currently suspended by the host. While suspended, the device is
+ * to enter a low power state until resumed by the host. While suspended no USB traffic to or
+ * from the device can occur (except for Remote Wakeup requests).
+ *
+ * \return Boolean true if the USB communications have been suspended by the host, false otherwise.
+ */
+ static inline bool USB_Device_IsUSBSuspended(void);
+ #else
+ #define USB_Device_SendRemoteWakeup() MACROS{ UDCON |= (1 << RMWKUP); }MACROE
- /** Indicates if a Remote Wakeup request is being sent to the host. This returns true if a
- * remote wakeup is currently being sent, false otherwise.
- *
- * This can be used in conjunction with the USB_Device_IsUSBSuspended() macro to determine if
- * a sent RMWAKEUP request was accepted or rejected by the host.
- *
- * \note This macro should only be used if the device has indicated to the host that it
- * supports the Remote Wakeup feature in the device descriptors.
- *
- * \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
- */
- #define USB_Device_IsRemoteWakeupSent() ((UDCON & (1 << RMWKUP)) ? false : true)
+ #define USB_Device_IsRemoteWakeupSent() ((UDCON & (1 << RMWKUP)) ? false : true)
- /** Indicates if the device is currently suspended by the host. While suspended, the device is
- * to enter a low power state until resumed by the host. While suspended no USB traffic to or
- * from the device can occur (except for Remote Wakeup requests).
- *
- * This macro returns true if the USB communications have been suspended by the host, false
- * otherwise.
- */
- #define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false)
+ #define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false)
+ #endif
/* Enums: */
/** Enum for the ErrorCode parameter of the USB_DeviceError event.
@@ -122,5 +140,7 @@
#define USB_Device_SetLowSpeed() MACROS{ UDCON |= (1 << LSM); }MACROE
#define USB_Device_SetHighSpeed() MACROS{ UDCON &= ~(1 << LSM); }MACROE
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index aa18358c8..b88547177 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -88,8 +88,19 @@ uint8_t Endpoint_WaitUntilReady(void)
USB_INT_Clear(USB_INT_SOFI);
- while (!(Endpoint_ReadWriteAllowed()))
+ for (;;)
{
+ if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
+ {
+ if (Endpoint_IsINReady())
+ return ENDPOINT_READYWAIT_NoError;
+ }
+ else
+ {
+ if (Endpoint_IsOUTReceived())
+ return ENDPOINT_READYWAIT_NoError;
+ }
+
if (!(USB_IsConnected))
return ENDPOINT_READYWAIT_DeviceDisconnected;
else if (Endpoint_IsStalled())
@@ -103,8 +114,6 @@ uint8_t Endpoint_WaitUntilReady(void)
return ENDPOINT_READYWAIT_Timeout;
}
}
-
- return ENDPOINT_READYWAIT_NoError;
}
uint8_t Endpoint_Discard_Stream(uint16_t Length
@@ -120,9 +129,9 @@ uint8_t Endpoint_Discard_Stream(uint16_t Length
while (Length--)
{
- if (!(Endpoint_ReadWriteAllowed()))
+ if (!(Endpoint_IsReadWriteAllowed()))
{
- Endpoint_ClearCurrentBank();
+ Endpoint_ClearOUT();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -132,8 +141,10 @@ uint8_t Endpoint_Discard_Stream(uint16_t Length
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
}
-
- Endpoint_Discard_Byte();
+ else
+ {
+ Endpoint_Discard_Byte();
+ }
}
return ENDPOINT_RWSTREAM_ERROR_NoError;
@@ -153,9 +164,9 @@ uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Endpoint_ReadWriteAllowed()))
+ if (!(Endpoint_IsReadWriteAllowed()))
{
- Endpoint_ClearCurrentBank();
+ Endpoint_ClearIN();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -165,8 +176,10 @@ uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
}
-
- Endpoint_Write_Byte(*(DataStream++));
+ else
+ {
+ Endpoint_Write_Byte(*(DataStream++));
+ }
}
return ENDPOINT_RWSTREAM_ERROR_NoError;
@@ -186,9 +199,9 @@ uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Endpoint_ReadWriteAllowed()))
+ if (!(Endpoint_IsReadWriteAllowed()))
{
- Endpoint_ClearCurrentBank();
+ Endpoint_ClearIN();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -198,8 +211,10 @@ uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
}
-
- Endpoint_Write_Byte(*(DataStream--));
+ else
+ {
+ Endpoint_Write_Byte(*(DataStream--));
+ }
}
return ENDPOINT_RWSTREAM_ERROR_NoError;
@@ -219,9 +234,9 @@ uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Endpoint_ReadWriteAllowed()))
+ if (!(Endpoint_IsReadWriteAllowed()))
{
- Endpoint_ClearCurrentBank();
+ Endpoint_ClearOUT();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -231,8 +246,10 @@ uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
}
-
- *(DataStream++) = Endpoint_Read_Byte();
+ else
+ {
+ *(DataStream++) = Endpoint_Read_Byte();
+ }
}
return ENDPOINT_RWSTREAM_ERROR_NoError;
@@ -252,9 +269,9 @@ uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Endpoint_ReadWriteAllowed()))
+ if (!(Endpoint_IsReadWriteAllowed()))
{
- Endpoint_ClearCurrentBank();
+ Endpoint_ClearOUT();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -264,8 +281,10 @@ uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
}
-
- *(DataStream--) = Endpoint_Read_Byte();
+ else
+ {
+ *(DataStream--) = Endpoint_Read_Byte();
+ }
}
return ENDPOINT_RWSTREAM_ERROR_NoError;
@@ -276,9 +295,9 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
uint8_t* DataStream = (uint8_t*)Buffer;
bool SendZLP = true;
- while (Length && !(Endpoint_IsSetupOUTReceived()))
+ while (Length && !(Endpoint_IsOUTReceived()))
{
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
{
@@ -288,19 +307,19 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
}
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
}
- if (Endpoint_IsSetupOUTReceived())
+ if (Endpoint_IsOUTReceived())
return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
if (SendZLP)
{
- while (!(Endpoint_IsSetupINReady()));
- Endpoint_ClearSetupIN();
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearControlIN();
}
- while (!(Endpoint_IsSetupOUTReceived()));
+ while (!(Endpoint_IsOUTReceived()));
return ENDPOINT_RWCSTREAM_ERROR_NoError;
}
@@ -310,9 +329,9 @@ uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
bool SendZLP = true;
- while (Length && !(Endpoint_IsSetupOUTReceived()))
+ while (Length && !(Endpoint_IsOUTReceived()))
{
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
{
@@ -322,19 +341,19 @@ uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
}
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
- Endpoint_ClearSetupIN();
+ Endpoint_ClearControlIN();
}
- if (Endpoint_IsSetupOUTReceived())
+ if (Endpoint_IsOUTReceived())
return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
if (SendZLP)
{
- while (!(Endpoint_IsSetupINReady()));
- Endpoint_ClearSetupIN();
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearControlIN();
}
- while (!(Endpoint_IsSetupOUTReceived()));
+ while (!(Endpoint_IsOUTReceived()));
return ENDPOINT_RWCSTREAM_ERROR_NoError;
}
@@ -345,7 +364,7 @@ uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
while (Length)
{
- while (!(Endpoint_IsSetupOUTReceived()));
+ while (!(Endpoint_IsOUTReceived()));
while (Length && Endpoint_BytesInEndpoint())
{
@@ -354,10 +373,10 @@ uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
Length--;
}
- Endpoint_ClearSetupOUT();
+ Endpoint_ClearControlOUT();
}
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
return ENDPOINT_RWCSTREAM_ERROR_NoError;
}
@@ -368,7 +387,7 @@ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
while (Length)
{
- while (!(Endpoint_IsSetupOUTReceived()));
+ while (!(Endpoint_IsOUTReceived()));
while (Length && Endpoint_BytesInEndpoint())
{
@@ -377,10 +396,10 @@ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
Length--;
}
- Endpoint_ClearSetupOUT();
+ Endpoint_ClearControlOUT();
}
- while (!(Endpoint_IsSetupINReady()));
+ while (!(Endpoint_IsINReady()));
return ENDPOINT_RWCSTREAM_ERROR_NoError;
}
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.h b/LUFA/Drivers/USB/LowLevel/Endpoint.h
index c0eab3584..2223f0ca4 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.h
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.h
@@ -34,7 +34,25 @@
* module contains the endpoint management macros, as well as endpoint interrupt and data
* send/recieve functions for various data types.
*/
+
+/** \ingroup Group_USB
+ * @defgroup Group_EndpointManagement Endpoint Management
+ *
+ * Functions, macros, variables, enums and types related to the setup and management of endpoints while in USB Device mode.
+ *
+ * @{
+ */
+
+/** @defgroup Group_EndpointRW Endpoint Data Reading and Writing
+ *
+ * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints.
+ */
+/** @defgroup Group_EndpointPacketManagement Endpoint Packet Management
+ *
+ * Functions, macros, variables, enums and types related to packet management of endpoints.
+ */
+
#ifndef __ENDPOINT_H__
#define __ENDPOINT_H__
@@ -85,10 +103,10 @@
*/
#define ENDPOINT_CONTROLEP 0
- /** Default size of the default control endpoint's bank, until altered by the Endpoint0Size value
- * in the device descriptor. Not available if the FIXED_CONTROL_ENDPOINT_SIZE token is defined.
- */
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
+ /** Default size of the default control endpoint's bank, until altered by the Endpoint0Size value
+ * in the device descriptor. Not available if the FIXED_CONTROL_ENDPOINT_SIZE token is defined.
+ */
#define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8
#endif
@@ -165,125 +183,271 @@
*/
#define ENDPOINT_INT_OUT UEIENX, (1 << RXOUTE), UEINTX, (1 << RXOUTI)
- #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
- /** Indicates the number of bytes currently stored in the current endpoint's selected bank. */
- #define Endpoint_BytesInEndpoint() UEBCX
- #else
- #define Endpoint_BytesInEndpoint() UEBCLX
- #endif
-
- /** Returns the endpoint address of the currently selected endpoint. This is typically used to save
- * the currently selected endpoint number so that it can be restored after another endpoint has
- * been manipulated.
- */
- #define Endpoint_GetCurrentEndpoint() (UENUM & ENDPOINT_EPNUM_MASK)
+ /* Psuedo-Function Macros: */
+ #if defined(__DOXYGEN__)
+ /** Indicates the number of bytes currently stored in the current endpoint's selected bank.
+ *
+ * \note The return width of this function may differ, depending on the maximum endpoint bank size
+ * of the selected AVR model.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Total number of bytes in the currently selected Endpoint's FIFO buffer
+ */
+ static inline uint16_t Endpoint_BytesInEndpoint(void);
- /** Selects the given endpoint number. If the address from the device descriptors is used, the
- * value should be masked with the ENDPOINT_EPNUM_MASK constant to extract only the endpoint
- * number (and discarding the endpoint direction bit).
- *
- * Any endpoint operations which do not require the endpoint number to be indicated will operate on
- * the currently selected endpoint.
- */
- #define Endpoint_SelectEndpoint(epnum) MACROS{ UENUM = epnum; }MACROE
+ /** Get the endpoint address of the currently selected endpoint. This is typically used to save
+ * the currently selected endpoint number so that it can be restored after another endpoint has
+ * been manipulated.
+ *
+ * \return Index of the currently selected endpoint
+ */
+ static inline uint8_t Endpoint_GetCurrentEndpoint(void);
+
+ /** Selects the given endpoint number. If the address from the device descriptors is used, the
+ * value should be masked with the ENDPOINT_EPNUM_MASK constant to extract only the endpoint
+ * number (and discarding the endpoint direction bit).
+ *
+ * Any endpoint operations which do not require the endpoint number to be indicated will operate on
+ * the currently selected endpoint.
+ *
+ * \param EndpointNumber Endpoint number to select
+ */
+ static inline void Endpoint_SelectEndpoint(uint8_t EndpointNumber);
+
+ /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
+ * In and Out pointers to the bank's contents.
+ *
+ * \param EndpointNumber Endpoint number whose FIFO buffers are to be reset
+ */
+ static inline void Endpoint_ResetFIFO(uint8_t EndpointNumber);
+
+ /** Enables the currently selected endpoint so that data can be sent and received through it to
+ * and from a host.
+ *
+ * \note Endpoints must first be configured properly rather than just being enabled via the
+ * Endpoint_ConfigureEndpoint() macro, which calls Endpoint_EnableEndpoint() automatically.
+ */
+ static inline void Endpoint_EnableEndpoint(void);
- /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
- * In and Out pointers to the bank's contents.
- */
- #define Endpoint_ResetFIFO(epnum) MACROS{ UERST = (1 << epnum); UERST = 0; }MACROE
+ /** Disables the currently selected endpoint so that data cannot be sent and received through it
+ * to and from a host.
+ */
+ static inline void Endpoint_DisableEndpoint(void);
+
+ /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
+ *
+ * \return Boolean True if the currently selected endpoint is enabled, false otherwise
+ */
+ static inline bool Endpoint_IsEnabled(void);
+
+ /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
+ * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
+ * direction). This function will return false if an error has occurred in the endpoint, if the endpoint
+ * is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN
+ * direction and the endpoint bank is full.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \return Boolean true if the currently selected endpoint may be read from or written to, depending on its direction
+ */
+ static inline bool Endpoint_IsReadWriteAllowed(void);
+
+ /** Determines if the currently selected endpoint is configured.
+ *
+ * \return Boolean true if the currently selected endpoint has been configured, false otherwise
+ */
+ static inline bool Endpoint_IsConfigured(void);
+
+ /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
+ * interrupt duration has elapsed. Which endpoints have interrupted can be determined by
+ * masking the return value against (1 << {Endpoint Number}).
+ *
+ * \return Mask whose bits indicate which endpoints have interrupted
+ */
+ static inline uint8_t Endpoint_GetEndpointInterrupts(void);
+
+ /** Clears the endpoint interrupt flag. This clears the specified endpoint number's interrupt
+ * mask in the endpoint interrupt flag register.
+ *
+ * \param EndpointNumber Index of the endpoint whose interrupt flag should be cleared
+ */
+ static inline void Endpoint_ClearEndpointInterrupt(uint8_t EndpointNumber);
+
+ /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
+ * endpoints).
+ *
+ * \param EndpointNumber Index of the endpoint whose interrupt flag should be tested
+ *
+ * \return Boolean true if the specified endpoint has interrupted, false otherwise
+ */
+ static inline bool Endpoint_HasEndpointInterrupted(uint8_t EndpointNumber);
+
+ /** Determines if the selected IN endpoint is ready for a new packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \return Boolean true if the current endpoint is ready for an IN packet, false otherwise.
+ */
+ static inline bool Endpoint_IsINReady(void);
+
+ /** Determines if the selected OUT endpoint has received new packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \return Boolean true if current endpoint is has received an OUT packet, false otherwise.
+ */
+ static inline bool Endpoint_IsOUTReceived(void);
+
+ /** Determines if the current CONTROL type endpoint has received a SETUP packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \return Boolean true if the selected endpoint has received a SETUP packet, false otherwise.
+ */
+ static inline bool Endpoint_IsSETUPReceived(void);
+
+ /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
+ * endpoint for the next packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \note This is not applicable for non CONTROL type endpoints.
+ */
+ static inline void Endpoint_ClearControlSETUP(void);
+
+ /** Sends an IN packet to the host on the currently selected CONTROL type endpoint, freeing up the
+ * endpoint for the next packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \note For non CONTROL type endpoints, use Endpoint_ClearIN() instead.
+ */
+ static inline void Endpoint_ClearControlIN(void);
+
+ /** Acknowledges an OUT packet to the host on the currently selected CONTROL type endpoint, freeing
+ * up the endpoint for the next packet.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \note For non CONTROL type endpoints, use Endpoint_ClearOUT() instead.
+ */
+ static inline void Endpoint_ClearControlOUT(void);
+
+ /** Sends an IN packet to the host on the currently selected non CONTROL type endpoint, freeing
+ * up the endpoint for the next packet and switching to the alternative endpoint bank if double banked.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \note For CONTROL type endpoints, use Endpoint_ClearControlIN() instead.
+ */
+ static inline void Endpoint_ClearIN(void);
+
+ /** Acknowledges an OUT packet to the host on the currently selected non CONTROL type endpoint, freeing
+ * up the endpoint for the next packet and switching to the alternative endpoint bank if double banked.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \note For CONTROL type endpoints, use Endpoint_ClearControlOUT() instead.
+ */
+ static inline void Endpoint_ClearOUT(void);
+
+ /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
+ * indicated endpoint and that the current transfer sequence should be aborted. This provides a
+ * way for devices to indicate invalid commands to the host so that the current transfer can be
+ * aborted and the host can begin its own recovery sequence.
+ *
+ * The currently selected endpoint remains stalled until either the Endpoint_ClearStall() macro
+ * is called, or the host issues a CLEAR FEATURE request to the device for the currently selected
+ * endpoint.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ */
+ static inline void Endpoint_StallTransaction(void);
+
+ /** Clears the STALL condition on the currently selected endpoint.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ */
+ static inline void Endpoint_ClearStall(void);
+
+ /** Determines if the currently selected endpoint is stalled, false otherwise.
+ *
+ * \ingroup Group_EndpointPacketManagement
+ *
+ * \return Boolean true if the currently selected endpoint is stalled, false otherwise
+ */
+ static inline bool Endpoint_IsStalled(void);
+
+ /** Resets the data toggle of the currently selected endpoint. */
+ static inline void Endpoint_ResetDataToggle(void);
+
+ /** Determines the currently selected endpoint's direction.
+ *
+ * \return The currently selected endpoint's direction, as a ENDPOINT_DIR_* mask.
+ */
+ static inline uint8_t Endpoint_GetEndpointDirection(void);
+ #else
+ #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
+ #define Endpoint_BytesInEndpoint() UEBCX
+ #else
+ #define Endpoint_BytesInEndpoint() UEBCLX
+ #endif
+
+ #define Endpoint_GetCurrentEndpoint() (UENUM & ENDPOINT_EPNUM_MASK)
+
+ #define Endpoint_SelectEndpoint(epnum) MACROS{ UENUM = epnum; }MACROE
- /** Enables the currently selected endpoint so that data can be sent and received through it to
- * and from a host.
- *
- * \note Endpoints must first be configured properly rather than just being enabled via the
- * Endpoint_ConfigureEndpoint() macro, which calls Endpoint_EnableEndpoint() automatically.
- */
- #define Endpoint_EnableEndpoint() MACROS{ UECONX |= (1 << EPEN); }MACROE
+ #define Endpoint_ResetFIFO(epnum) MACROS{ UERST = (1 << epnum); UERST = 0; }MACROE
- /** Disables the currently selected endpoint so that data cannot be sent and received through it
- * to and from a host.
- */
- #define Endpoint_DisableEndpoint() MACROS{ UECONX &= ~(1 << EPEN); }MACROE
+ #define Endpoint_EnableEndpoint() MACROS{ UECONX |= (1 << EPEN); }MACROE
- /** Returns true if the currently selected endpoint is enabled, false otherwise. */
- #define Endpoint_IsEnabled() ((UECONX & (1 << EPEN)) ? true : false)
+ #define Endpoint_DisableEndpoint() MACROS{ UECONX &= ~(1 << EPEN); }MACROE
- /** Returns true if the currently selected endpoint may be read from (if data is waiting in the endpoint
- * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an
- * IN direction). This function will return false if an error has occurred in the endpoint, or if
- * the endpoint is an OUT direction and no packet has been received, or if the endpoint is an IN
- * direction and the endpoint bank is full.
- */
- #define Endpoint_ReadWriteAllowed() ((UEINTX & (1 << RWAL)) ? true : false)
+ #define Endpoint_IsEnabled() ((UECONX & (1 << EPEN)) ? true : false)
- /** Returns true if the currently selected endpoint is configured, false otherwise. */
- #define Endpoint_IsConfigured() ((UESTA0X & (1 << CFGOK)) ? true : false)
+ #define Endpoint_IsReadWriteAllowed() ((UEINTX & (1 << RWAL)) ? true : false)
- /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
- * interrupt duration has elapsed. Which endpoints have interrupted can be determined by
- * masking the return value against (1 << {Endpoint Number}).
- */
- #define Endpoint_GetEndpointInterrupts() UEINT
+ #define Endpoint_IsConfigured() ((UESTA0X & (1 << CFGOK)) ? true : false)
- /** Clears the endpoint interrupt flag. This clears the specified endpoint number's interrupt
- * mask in the endpoint interrupt flag register.
- */
- #define Endpoint_ClearEndpointInterrupt(n) MACROS{ UEINT &= ~(1 << n); }MACROE
+ #define Endpoint_GetEndpointInterrupts() UEINT
- /** Returns true if the specified endpoint number has interrupted (valid only for INTERRUPT type
- * endpoints), false otherwise.
- */
- #define Endpoint_HasEndpointInterrupted(n) ((UEINT & (1 << n)) ? true : false)
+ #define Endpoint_ClearEndpointInterrupt(n) MACROS{ UEINT &= ~(1 << n); }MACROE
- /** Clears the currently selected endpoint bank, and switches to the alternate bank if the currently
- * selected endpoint is dual-banked. When cleared, this either frees the bank up for the next packet
- * from the host (if the endpoint is of the OUT direction) or sends the packet contents to the host
- * (if the endpoint is of the IN direction).
- */
- #define Endpoint_ClearCurrentBank() MACROS{ UEINTX &= ~(1 << FIFOCON); }MACROE
-
- /** Returns true if the current CONTROL type endpoint is ready for an IN packet, false otherwise. */
- #define Endpoint_IsSetupINReady() ((UEINTX & (1 << TXINI)) ? true : false)
+ #define Endpoint_HasEndpointInterrupted(n) ((UEINT & (1 << n)) ? true : false)
+
+ #define Endpoint_IsINReady() ((UEINTX & (1 << TXINI)) ? true : false)
+
+ #define Endpoint_IsOUTReceived() ((UEINTX & (1 << RXOUTI)) ? true : false)
- /** Returns true if the current CONTROL type endpoint is ready for an OUT packet, false otherwise. */
- #define Endpoint_IsSetupOUTReceived() ((UEINTX & (1 << RXOUTI)) ? true : false)
+ #define Endpoint_IsSETUPReceived() ((UEINTX & (1 << RXSTPI)) ? true : false)
- /** Returns true if the current CONTROL type endpoint is ready for a SETUP packet, false otherwise. */
- #define Endpoint_IsSetupReceived() ((UEINTX & (1 << RXSTPI)) ? true : false)
+ #define Endpoint_ClearControlSETUP() MACROS{ UEINTX &= ~(1 << RXSTPI); }MACROE
- /** Clears a received SETUP packet on the currently selected CONTROL type endpoint. */
- #define Endpoint_ClearSetupReceived() MACROS{ UEINTX &= ~(1 << RXSTPI); }MACROE
+ #define Endpoint_ClearControlIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE
- /** Sends an IN packet to the host on the currently selected CONTROL type endpoint. */
- #define Endpoint_ClearSetupIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE
+ #define Endpoint_ClearControlOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE
- /** Acknowledges an OUT packet to the host on the currently selected CONTROL type endpoint, freeing
- * up the endpoint for the next packet.
- */
- #define Endpoint_ClearSetupOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE
+ #define Endpoint_ClearIN() MACROS{ UEINTX &= ~(1 << TXINI); UEINTX &= ~(1 << FIFOCON); }MACROE
- /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
- * indicated endpoint and that the current transfer sequence should be aborted. This provides a
- * way for devices to indicate invalid commands to the host so that the current transfer can be
- * aborted and the host can begin its own recovery sequence.
- *
- * The currently selected endpoint remains stalled until either the Endpoint_ClearStall() macro
- * is called, or the host issues a CLEAR FEATURE request to the device for the currently selected
- * endpoint.
- */
- #define Endpoint_StallTransaction() MACROS{ UECONX |= (1 << STALLRQ); }MACROE
+ #define Endpoint_ClearOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); UEINTX &= ~(1 << FIFOCON); }MACROE
- /** Clears the stall on the currently selected endpoint. */
- #define Endpoint_ClearStall() MACROS{ UECONX |= (1 << STALLRQC); }MACROE
+ #define Endpoint_StallTransaction() MACROS{ UECONX |= (1 << STALLRQ); }MACROE
- /** Returns true if the currently selected endpoint is stalled, false otherwise. */
- #define Endpoint_IsStalled() ((UECONX & (1 << STALLRQ)) ? true : false)
+ #define Endpoint_ClearStall() MACROS{ UECONX |= (1 << STALLRQC); }MACROE
- /** Resets the data toggle of the currently selected endpoint. */
- #define Endpoint_ResetDataToggle() MACROS{ UECONX |= (1 << RSTDT); }MACROE
+ #define Endpoint_IsStalled() ((UECONX & (1 << STALLRQ)) ? true : false)
+
+ #define Endpoint_ResetDataToggle() MACROS{ UECONX |= (1 << RSTDT); }MACROE
+
+ #define Endpoint_GetEndpointDirection() (UECFG0X & ENDPOINT_DIR_IN)
+ #endif
/* Enums: */
- /** Enum for the possible error return codes of the Endpoint_WaitUntilReady function */
+ /** Enum for the possible error return codes of the Endpoint_WaitUntilReady function.
+ *
+ * \ingroup Group_EndpointRW
+ */
enum Endpoint_WaitUntilReady_ErrorCodes_t
{
ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */
@@ -299,7 +463,10 @@
*/
};
- /** Enum for the possible error return codes of the Endpoint_*_Stream_* functions. */
+ /** Enum for the possible error return codes of the Endpoint_*_Stream_* functions.
+ *
+ * \ingroup Group_EndpointRW
+ */
enum Endpoint_Stream_RW_ErrorCodes_t
{
ENDPOINT_RWSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
@@ -318,7 +485,10 @@
*/
};
- /** Enum for the possible error return codes of the Endpoint_*_Control_Stream_* functions. */
+ /** Enum for the possible error return codes of the Endpoint_*_Control_Stream_* functions..
+ *
+ * \ingroup Group_EndpointRW
+ */
enum Endpoint_ControlStream_RW_ErrorCodes_t
{
ENDPOINT_RWCSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
@@ -326,21 +496,34 @@
};
/* Inline Functions: */
- /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. */
+ /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Next byte in the currently selected endpoint's FIFO buffer
+ */
static inline uint8_t Endpoint_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_Read_Byte(void)
{
return UEDATX;
}
- /** Writes one byte from the currently selected endpoint's bank, for IN direction endpoints. */
+ /** Writes one byte from the currently selected endpoint's bank, for IN direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \param Byte Next byte to write into the the currently selected endpoint's FIFO buffer
+ */
static inline void Endpoint_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_Byte(const uint8_t Byte)
{
UEDATX = Byte;
}
- /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints. */
+ /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ */
static inline void Endpoint_Discard_Byte(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Discard_Byte(void)
{
@@ -351,6 +534,10 @@
/** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Next word in the currently selected endpoint's FIFO buffer
*/
static inline uint16_t Endpoint_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Endpoint_Read_Word_LE(void)
@@ -365,6 +552,10 @@
/** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Next word in the currently selected endpoint's FIFO buffer
*/
static inline uint16_t Endpoint_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Endpoint_Read_Word_BE(void)
@@ -379,6 +570,10 @@
/** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \param Word Next word to write to the currently selected endpoint's FIFO buffer
*/
static inline void Endpoint_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_Word_LE(const uint16_t Word)
@@ -389,6 +584,10 @@
/** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \param Word Next word to write to the currently selected endpoint's FIFO buffer
*/
static inline void Endpoint_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_Word_BE(const uint16_t Word)
@@ -397,7 +596,10 @@
UEDATX = (Word & 0xFF);
}
- /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints. */
+ /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ */
static inline void Endpoint_Discard_Word(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Discard_Word(void)
{
@@ -409,6 +611,10 @@
/** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Next double word in the currently selected endpoint's FIFO buffer
*/
static inline uint32_t Endpoint_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint32_t Endpoint_Read_DWord_LE(void)
@@ -429,6 +635,10 @@
/** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \return Next double word in the currently selected endpoint's FIFO buffer
*/
static inline uint32_t Endpoint_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint32_t Endpoint_Read_DWord_BE(void)
@@ -449,6 +659,10 @@
/** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \param DWord Next double word to write to the currently selected endpoint's FIFO buffer
*/
static inline void Endpoint_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_DWord_LE(const uint32_t DWord)
@@ -461,6 +675,10 @@
/** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
* direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ *
+ * \param DWord Next double word to write to the currently selected endpoint's FIFO buffer
*/
static inline void Endpoint_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_DWord_BE(const uint32_t DWord)
@@ -471,7 +689,10 @@
UEDATX = (DWord & 0xFF);
}
- /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints. */
+ /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.
+ *
+ * \ingroup Group_EndpointRW
+ */
static inline void Endpoint_Discard_DWord(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Discard_DWord(void)
{
@@ -539,6 +760,8 @@
*
* \note This routine should not be called on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \return A value from the Endpoint_WaitUntilReady_ErrorCodes_t enum.
*/
uint8_t Endpoint_WaitUntilReady(void);
@@ -546,7 +769,7 @@
/** Reads and discards the given number of bytes from the endpoint from the given buffer,
* discarding fully read packets from the host as needed. The last packet is not automatically
* discarded once the remaining bytes has been read; the user is responsible for manually
- * discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
+ * discarding the last packet from the host via the Endpoint_ClearOUT() macro. Between
* each USB packet, the given stream callback function is executed repeatedly until the next
* packet is ready, allowing for early aborts of stream transfers.
*
@@ -556,6 +779,8 @@
*
* \note This routine should not be used on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Length Number of bytes to send via the currently selected endpoint.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
*
@@ -570,7 +795,7 @@
/** Writes the given number of bytes to the endpoint from the given buffer in little endian,
* sending full packets to the host as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Endpoint_ClearCurrentBank() macro. Between each USB packet, the given stream callback function
+ * Endpoint_ClearIN() macro. Between each USB packet, the given stream callback function
* is executed repeatedly until the endpoint is ready to accept the next packet, allowing for early
* aborts of stream transfers.
*
@@ -580,6 +805,8 @@
*
* \note This routine should not be used on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -595,7 +822,7 @@
/** Writes the given number of bytes to the endpoint from the given buffer in big endian,
* sending full packets to the host as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Endpoint_ClearCurrentBank() macro. Between each USB packet, the given stream callback function
+ * Endpoint_ClearIN() macro. Between each USB packet, the given stream callback function
* is executed repeatedly until the endpoint is ready to accept the next packet, allowing for early
* aborts of stream transfers.
*
@@ -605,6 +832,8 @@
*
* \note This routine should not be used on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -620,7 +849,7 @@
/** Reads the given number of bytes from the endpoint from the given buffer in little endian,
* discarding fully read packets from the host as needed. The last packet is not automatically
* discarded once the remaining bytes has been read; the user is responsible for manually
- * discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
+ * discarding the last packet from the host via the Endpoint_ClearOUT() macro. Between
* each USB packet, the given stream callback function is executed repeatedly until the endpoint
* is ready to accept the next packet, allowing for early aborts of stream transfers.
*
@@ -630,6 +859,8 @@
*
* \note This routine should not be used on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the destination data buffer to write to.
* \param Length Number of bytes to send via the currently selected endpoint.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -645,7 +876,7 @@
/** Reads the given number of bytes from the endpoint from the given buffer in big endian,
* discarding fully read packets from the host as needed. The last packet is not automatically
* discarded once the remaining bytes has been read; the user is responsible for manually
- * discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
+ * discarding the last packet from the host via the Endpoint_ClearOUT() macro. Between
* each USB packet, the given stream callback function is executed repeatedly until the endpoint
* is ready to accept the next packet, allowing for early aborts of stream transfers.
*
@@ -655,6 +886,8 @@
*
* \note This routine should not be used on CONTROL type endpoints.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the destination data buffer to write to.
* \param Length Number of bytes to send via the currently selected endpoint.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -670,13 +903,15 @@
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian,
* sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
* in both failure and success states; the user is responsible for manually clearing the setup OUT to
- * finalize the transfer via the Endpoint_ClearSetupOUT() macro.
+ * finalize the transfer via the Endpoint_ClearControlOUT() macro.
*
* \note This routine should only be used on CONTROL type endpoints.
*
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
* together; i.e. the entire stream data must be read or written at the one time.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
*
@@ -687,13 +922,15 @@
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian,
* sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
* in both failure and success states; the user is responsible for manually clearing the setup OUT to
- * finalize the transfer via the Endpoint_ClearSetupOUT() macro.
+ * finalize the transfer via the Endpoint_ClearControlOUT() macro.
*
* \note This routine should only be used on CONTROL type endpoints.
*
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
* together; i.e. the entire stream data must be read or written at the one time.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
*
@@ -704,13 +941,15 @@
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian,
* discarding fully read packets from the host as needed. The device IN acknowledgement is not
* automatically sent after success or failure states; the user is responsible for manually sending the
- * setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
+ * setup IN to finalize the transfer via the Endpoint_ClearControlIN() macro.
*
* \note This routine should only be used on CONTROL type endpoints.
*
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
* together; i.e. the entire stream data must be read or written at the one time.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the destination data buffer to write to.
* \param Length Number of bytes to send via the currently selected endpoint.
*
@@ -721,80 +960,21 @@
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian,
* discarding fully read packets from the host as needed. The device IN acknowledgement is not
* automatically sent after success or failure states; the user is responsible for manually sending the
- * setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
+ * setup IN to finalize the transfer via the Endpoint_ClearControlIN() macro.
*
* \note This routine should only be used on CONTROL type endpoints.
*
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
* together; i.e. the entire stream data must be read or written at the one time.
*
+ * \ingroup Group_EndpointRW
+ *
* \param Buffer Pointer to the destination data buffer to write to.
* \param Length Number of bytes to send via the currently selected endpoint.
*
* \return A value from the Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
-
- /* Function Aliases: */
- /** Alias for Endpoint_Discard_Byte().
- */
- #define Endpoint_Ignore_Byte() Endpoint_Discard_Byte()
-
- /** Alias for Endpoint_Discard_Word().
- */
- #define Endpoint_Ignore_Word() Endpoint_Discard_Word()
-
- /** Alias for Endpoint_Discard_DWord().
- */
- #define Endpoint_Ignore_DWord() Endpoint_Discard_DWord()
-
- /** Alias for Endpoint_Read_Word_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Read_Word() Endpoint_Read_Word_LE()
-
- /** Alias for Endpoint_Write_Word_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Write_Word(Word) Endpoint_Write_Word_LE(Word)
-
- /** Alias for Endpoint_Read_DWord_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Read_DWord() Endpoint_Read_DWord_LE()
-
- /** Alias for Endpoint_Write_DWord_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Write_DWord(DWord) Endpoint_Write_DWord_LE(DWord)
-
- /** Alias for Endpoint_Read_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #if !defined(NO_STREAM_CALLBACKS)
- #define Endpoint_Read_Stream(Buffer, Length, Callback) Endpoint_Read_Stream_LE(Buffer, Length, Callback)
- #else
- #define Endpoint_Read_Stream(Buffer, Length) Endpoint_Read_Stream_LE(Buffer, Length)
- #endif
-
- /** Alias for Endpoint_Write_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #if !defined(NO_STREAM_CALLBACKS)
- #define Endpoint_Write_Stream(Buffer, Length, Callback) Endpoint_Write_Stream_LE(Buffer, Length, Callback)
- #else
- #define Endpoint_Write_Stream(Buffer, Length) Endpoint_Write_Stream_LE(Buffer, Length)
- #endif
-
- /** Alias for Endpoint_Read_Control_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Read_Control_Stream(Data, Length) Endpoint_Read_Control_Stream_LE(Data, Length)
-
- /** Alias for Endpoint_Write_Control_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Endpoint_Write_Control_Stream(Data, Length) Endpoint_Write_Control_Stream_LE(Data, Length)
+ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
@@ -868,3 +1048,5 @@
#endif
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index 52f19a5fd..fe02f7cd1 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -87,7 +87,7 @@ void USB_Host_ResetDevice(void)
USB_INT_Disable(USB_INT_DDISCI);
USB_Host_ResetBus();
- while (!(USB_Host_IsResetBusDone()));
+ while (!(USB_Host_IsBusResetComplete()));
USB_INT_Clear(USB_INT_HSOFI);
USB_Host_ResumeBus();
diff --git a/LUFA/Drivers/USB/LowLevel/Host.h b/LUFA/Drivers/USB/LowLevel/Host.h
index 18eebfec1..1ff2d7ab2 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.h
+++ b/LUFA/Drivers/USB/LowLevel/Host.h
@@ -34,6 +34,14 @@
* the USB controller is initialized in host mode.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_Host Host Management
+ *
+ * Functions, macros, variables, enums and types related to the management of a USB host when in Host mode.
+ *
+ * @{
+ */
+
#ifndef __USBHOST_H__
#define __USBHOST_H__
@@ -81,64 +89,94 @@
*/
#define HOST_DEVICE_SETTLE_DELAY_MS 1500
#endif
-
- /** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host.
- * USB bus resets leave the default control pipe configured (if already configured).
- *
- * If the USB bus has been suspended prior to issuing a bus reset, the attached device will be
- * woken up automatically and the bus resumed after the reset has been correctly issued.
- */
- #define USB_Host_ResetBus() MACROS{ UHCON |= (1 << RESET); }MACROE
+
+ /* Psuedo-Function Macros: */
+ #if defined(__DOXYGEN__)
+ /** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host.
+ * USB bus resets leave the default control pipe configured (if already configured).
+ *
+ * If the USB bus has been suspended prior to issuing a bus reset, the attached device will be
+ * woken up automatically and the bus resumed after the reset has been correctly issued.
+ */
+ static inline void USB_Host_ResetBus(void);
- /** Determines if a previously issued bus reset (via the USB_Host_ResetBus() macro) has
- * completed. This macro returns true if no bus reset is currently being sent, false
- * otherwise.
- */
- #define USB_Host_IsResetBusDone() ((UHCON & (1 << RESET)) ? false : true)
-
- /** Resumes USB communications with an attached and enumerated device, by resuming the transmission
- * of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the
- * host and attached device may occur.
- */
- #define USB_Host_ResumeBus() MACROS{ UHCON |= (1 << SOFEN); }MACROE
+ /** Determines if a previously issued bus reset (via the USB_Host_ResetBus() macro) has
+ * completed.
+ *
+ * \return Boolean true if no bus reset is currently being sent, false otherwise.
+ */
+ static inline void USB_Host_IsBusResetComplete(void);
- /** Suspends the USB bus, preventing any communications from occurring between the host and attached
- * device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
- * messages to the device.
- */
- #define USB_Host_SuspendBus() MACROS{ UHCON &= ~(1 << SOFEN); }MACROE
-
- /** Returns true if the USB bus has been suspended via the use of the USB_Host_SuspendBus() macro,
- * false otherwise. While suspended, no USB communications can occur until the bus is resumed,
- * except for the Remote Wakeup event from the device if supported.
- */
- #define USB_Host_IsBusSuspended() ((UHCON & (1 << SOFEN)) ? false : true)
-
- /** Returns true if the attached device is currently enumerated in Full Speed mode (12Mb/s), or
- * false if the attached device is enumerated in Low Speed mode (1.5Mb/s).
- */
- #define USB_Host_IsDeviceFullSpeed() ((USBSTA & (1 << SPEED)) ? true : false)
+ /** Resumes USB communications with an attached and enumerated device, by resuming the transmission
+ * of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the
+ * host and attached device may occur.
+ */
+ static inline void USB_Host_ResumeBus(void);
- /** Returns true if the attached device is currently issuing a Remote Wakeup request, requesting
- * that the host resume the USB bus and wake up the device, false otherwise.
- */
- #define USB_Host_IsRemoteWakeupSent() ((UHINT & (1 << RXRSMI)) ? true : false)
+ /** Suspends the USB bus, preventing any communications from occurring between the host and attached
+ * device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
+ * messages to the device.
+ */
+ static inline void USB_Host_SuspendBus(void);
+
+ /** Determines if the USB bus has been suspended via the use of the USB_Host_SuspendBus() macro,
+ * false otherwise. While suspended, no USB communications can occur until the bus is resumed,
+ * except for the Remote Wakeup event from the device if supported.
+ *
+ * \return Boolean true if the bus is currently suspended, false otherwise
+ */
+ static inline bool USB_Host_IsBusSuspended(void);
+
+ /** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or
+ * false if the attached device is enumerated in Low Speed mode (1.5Mb/s).
+ *
+ * \return Boolean true if the attached device is enumerated in Full Speed mode, false otherwise
+ */
+ static inline bool USB_Host_IsDeviceFullSpeed(void);
- /** Clears the flag indicating that a Remote Wakeup request has been issued by an attached
- * device.
- */
- #define USB_Host_ClearRemoteWakeupSent() MACROS{ UHINT &= ~(1 << RXRSMI); }MACROE
+ /** Determines if the attached device is currently issuing a Remote Wakeup request, requesting
+ * that the host resume the USB bus and wake up the device, false otherwise.
+ *
+ * \return Boolean true if the attached device has sent a Remote Wakeup request, false otherwise
+ */
+ static inline bool USB_Host_IsRemoteWakeupSent(void);
- /** Accepts a Remote Wakeup request from an attached device. This must be issued in response to
- * a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to
- * be resumed.
- */
- #define USB_Host_ResumeFromWakeupRequest() MACROS{ UHCON |= (1 << RESUME); }MACROE
+ /** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */
+ static inline void USB_Host_ClearRemoteWakeupSent(void);
+
+ /** Accepts a Remote Wakeup request from an attached device. This must be issued in response to
+ * a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to
+ * be resumed.
+ */
+ static inline void USB_Host_ResumeFromWakeupRequest(void);
+
+ /** Determines if a resume from Remote Wakeup request is currently being sent to an attached
+ * device.
+ *
+ * \return Boolean true if no resume request is currently being sent, false otherwise
+ */
+ static inline bool USB_Host_IsResumeFromWakeupRequestSent(void);
+ #else
+ #define USB_Host_ResetBus() MACROS{ UHCON |= (1 << RESET); }MACROE
+
+ #define USB_Host_IsBusResetComplete() ((UHCON & (1 << RESET)) ? false : true)
+
+ #define USB_Host_ResumeBus() MACROS{ UHCON |= (1 << SOFEN); }MACROE
+
+ #define USB_Host_SuspendBus() MACROS{ UHCON &= ~(1 << SOFEN); }MACROE
+
+ #define USB_Host_IsBusSuspended() ((UHCON & (1 << SOFEN)) ? false : true)
- /** Returns true if no resume from Remote Wakeup request is currently being sent to an attached
- * device, false otherwise.
- */
- #define USB_Host_IsResumeFromWakeupRequestSent() ((UHCON & (1 << RESUME)) ? false : true)
+ #define USB_Host_IsDeviceFullSpeed() ((USBSTA & (1 << SPEED)) ? true : false)
+
+ #define USB_Host_IsRemoteWakeupSent() ((UHINT & (1 << RXRSMI)) ? true : false)
+
+ #define USB_Host_ClearRemoteWakeupSent() MACROS{ UHINT &= ~(1 << RXRSMI); }MACROE
+
+ #define USB_Host_ResumeFromWakeupRequest() MACROS{ UHCON |= (1 << RESUME); }MACROE
+
+ #define USB_Host_IsResumeFromWakeupRequestSent() ((UHCON & (1 << RESUME)) ? false : true)
+ #endif
/* Enums: */
/** Enum for the various states of the USB Host state machine. Only some states are
@@ -241,5 +279,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/LowLevel/HostChapter9.c b/LUFA/Drivers/USB/LowLevel/HostChapter9.c
index 5367c984c..c89910e63 100644
--- a/LUFA/Drivers/USB/LowLevel/HostChapter9.c
+++ b/LUFA/Drivers/USB/LowLevel/HostChapter9.c
@@ -52,19 +52,17 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
Pipe_SetToken(PIPE_TOKEN_SETUP);
Pipe_ClearErrorFlags();
- Pipe_ClearSetupSent();
Pipe_Unfreeze();
for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Host_Request_Header_t); HeaderByte++)
Pipe_Write_Byte(*(HeaderStream++));
- Pipe_ClearSetupOUT();
+ Pipe_ClearControlSETUP();
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_SetupSent)))
goto End_Of_Control_Send;
- Pipe_ClearSetupSent();
Pipe_Freeze();
if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
@@ -93,7 +91,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
}
Pipe_Freeze();
- Pipe_ClearSetupIN();
+ Pipe_ClearControlIN();
}
}
@@ -103,7 +101,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
goto End_Of_Control_Send;
- Pipe_ClearSetupOUT();
+ Pipe_ClearControlOUT();
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
goto End_Of_Control_Send;
@@ -126,7 +124,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
DataLen--;
}
- Pipe_ClearSetupOUT();
+ Pipe_ClearControlOUT();
}
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
@@ -141,7 +139,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_InReceived)))
goto End_Of_Control_Send;
- Pipe_ClearSetupIN();
+ Pipe_ClearControlIN();
}
End_Of_Control_Send:
@@ -159,9 +157,9 @@ static uint8_t USB_Host_Wait_For_Setup_IOS(const uint8_t WaitType)
{
uint16_t TimeoutCounter = USB_HOST_TIMEOUT_MS;
- while (!(((WaitType == USB_HOST_WAITFOR_SetupSent) && Pipe_IsSetupSent()) ||
- ((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsSetupINReceived()) ||
- ((WaitType == USB_HOST_WAITFOR_OutReady) && Pipe_IsSetupOUTReady())))
+ while (!(((WaitType == USB_HOST_WAITFOR_SetupSent) && Pipe_IsSETUPSent()) ||
+ ((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsINReceived()) ||
+ ((WaitType == USB_HOST_WAITFOR_OutReady) && Pipe_IsOUTReady())))
{
uint8_t ErrorCode;
diff --git a/LUFA/Drivers/USB/LowLevel/HostChapter9.h b/LUFA/Drivers/USB/LowLevel/HostChapter9.h
index 7ced889b3..8e7695b34 100644
--- a/LUFA/Drivers/USB/LowLevel/HostChapter9.h
+++ b/LUFA/Drivers/USB/LowLevel/HostChapter9.h
@@ -58,6 +58,8 @@
*
* \see StdRequestType.h for information on the request type and data.
* \see The USB 2.0 specification for more information on standard control requests.
+ *
+ * \ingroup Group_PipeControlReq
*/
typedef struct
{
@@ -71,6 +73,8 @@
/* Enums: */
/** Enum for the USB_Host_SendControlRequest() return code, indicating the reason for the error
* if the transfer of the request is unsuccessful.
+ *
+ * \ingroup Group_PipeControlReq
*/
enum USB_Host_SendControlErrorCodes_t
{
@@ -89,6 +93,8 @@
/** Global for the request to send via the USB_Host_SendControlRequest() function. This
* global should be filled with the correct control request data before sending the request to
* the attached device while in host mode.
+ *
+ * \ingroup Group_PipeControlReq
*/
extern USB_Host_Request_Header_t USB_HostRequest;
@@ -97,6 +103,8 @@
* and transfers the data stored in the buffer to the device, or from the device to the buffer
* as requested. The transfer is made on the currently selected pipe.
*
+ * \ingroup Group_PipeControlReq
+ *
* \param BufferPtr Pointer to the start of the data buffer if the request has a data stage, or
* NULL if the request transfers no data to or from the device.
*
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.h b/LUFA/Drivers/USB/LowLevel/LowLevel.h
index 07be4396d..a6f506f3b 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.h
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.h
@@ -34,6 +34,14 @@
* USB interface in either device or (if supported) host mode.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_USBManagement USB Interface Management
+ *
+ * Functions, macros, variables, enums and types related to the setup and management of the USB interface.
+ *
+ * @{
+ */
+
#ifndef __USBLOWLEVEL_H__
#define __USBLOWLEVEL_H__
@@ -70,7 +78,6 @@
/* Preprocessor Checks and Defines: */
#if !defined(F_CLOCK)
#error F_CLOCK is not defined. You must device F_CLOCK to the frequency of the unprescaled input clock in your project makefile.
- #define F_CLOCK 0
#endif
#if (F_CLOCK == 8000000)
@@ -376,3 +383,5 @@
#endif
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/LowLevel/OTG.h b/LUFA/Drivers/USB/LowLevel/OTG.h
index 88a955403..caef82cb6 100644
--- a/LUFA/Drivers/USB/LowLevel/OTG.h
+++ b/LUFA/Drivers/USB/LowLevel/OTG.h
@@ -35,6 +35,14 @@
*
* \note These macros are only for AVRs which support the OTG protocol, and do not exist for device-only AVRs.
*/
+
+/** \ingroup Group_USB
+ * @defgroup Group_OTGManagement USB On The Go (OTG) Management
+ *
+ * Functions, macros, variables, enums and types related to the setup and management of dual role devices.
+ *
+ * @{
+ */
#ifndef __USBOTG_H__
#define __USBOTG_H__
@@ -47,46 +55,6 @@
/* Public Interface - May be used in end-application: */
/* Macros: */
- /** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
- * that the device wishes to change device/host roles.
- */
- #define USB_OTG_DEV_Request_HNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE
-
- /** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
- * connected device.
- */
- #define USB_OTG_DEV_Cancel_HNP_Request() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE
-
- /** Returns boolean false if not currently sending a HNP to the other connected device, or true
- * if a HNP is currently being issued.
- */
- #define USB_OTG_DEV_IsSendingHNP() ((OTGCON & (1 << HNPREQ)) ? true : false)
-
- /** Accepts a HNP from a connected device, indicating that both devices should exchange
- * device/host roles.
- */
- #define USB_OTG_HOST_Accept_HNP() USB_OTG_DEV_Request_HNP()
-
- /** Rejects a HNP from a connected device, indicating that both devices should remain in their
- * current device/host roles.
- */
- #define USB_OTG_HOST_Reject_HNP() USB_OTG_DEV_Cancel_HNP_Request()
-
- /** Returns boolean false if the connected device is not currently sending a HNP request, or true
- * if a HNP is currently being issued by the connected device.
- */
- #define USB_OTG_HOST_IsHNPReceived() ((OTGCON & (1 << HNPREQ)) ? true : false)
-
- /** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB
- * interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in
- * host mode indicates that VBUS should be applied and a session started.
- *
- * There are two different methods of sending a SRP - either pulses on the VBUS line, or by
- * pulsing the Data + line via the internal pull-up resistor. The SRP mode is given as the
- * "type" parameter, and can be either USB_OTG_SRP_VBUS or USB_OTG_STP_DATA.
- */
- #define USB_OTG_DEV_Initiate_SRP(type) MACROS{ OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (type | (1 << SRPREQ))); }MACROE
-
/** Mask for the VBUS pulsing method of SRP, supported by some OTG devices.
*
* \see USB_OTG_DEV_Initiate_SRP()
@@ -99,4 +67,67 @@
*/
#define USB_OTG_STP_DATA 0
+ /* Psuedo-Function Macros: */
+ #if defined(__DOXYGEN__)
+ /** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
+ * that the device wishes to change device/host roles.
+ */
+ static inline void USB_OTG_DEV_Request_HNP(void);
+
+ /** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
+ * connected device.
+ */
+ static inline void USB_OTG_DEV_Cancel_HNP_Request(void);
+
+ /** Determines if the device is currently sending a HNP to an attached host.
+ *
+ * \return Boolean true if currently sending a HNP to the other connected device, false otherwise
+ */
+ static inline bool USB_OTG_DEV_IsSendingHNP(void);
+
+ /** Accepts a HNP from a connected device, indicating that both devices should exchange
+ * device/host roles.
+ */
+ static inline void USB_OTG_HOST_Accept_HNP(void);
+
+ /** Rejects a HNP from a connected device, indicating that both devices should remain in their
+ * current device/host roles.
+ */
+ static inline void USB_OTG_HOST_Reject_HNP(void);
+
+ /** Indicates if the connected device is not currently sending a HNP request.
+ *
+ * \return Boolean true if a HNP is currently being issued by the connected device, false otherwise.
+ */
+ static inline bool USB_OTG_HOST_IsHNPReceived(void);
+
+ /** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB
+ * interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in
+ * host mode indicates that VBUS should be applied and a session started.
+ *
+ * There are two different methods of sending a SRP - either pulses on the VBUS line, or by
+ * pulsing the Data + line via the internal pull-up resistor.
+ *
+ * \param SRPTypeMask Mask indicating the type of SRP to use, either USB_OTG_SRP_VBUS or USB_OTG_STP_DATA.
+ */
+ static inline void USB_OTG_DEV_Initiate_SRP(uint8_t SRPTypeMask);
+ #else
+
+ #define USB_OTG_DEV_Request_HNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE
+
+ #define USB_OTG_DEV_Cancel_HNP_Request() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE
+
+ #define USB_OTG_DEV_IsSendingHNP() ((OTGCON & (1 << HNPREQ)) ? true : false)
+
+ #define USB_OTG_HOST_Accept_HNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE
+
+ #define USB_OTG_HOST_Reject_HNP() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE
+
+ #define USB_OTG_HOST_IsHNPReceived() ((OTGCON & (1 << HNPREQ)) ? true : false)
+
+ #define USB_OTG_DEV_Initiate_SRP(type) MACROS{ OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (type | (1 << SRPREQ))); }MACROE
+ #endif
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index 1218d2f24..5850fcf7c 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -74,8 +74,19 @@ uint8_t Pipe_WaitUntilReady(void)
USB_INT_Clear(USB_INT_HSOFI);
- while (!(Pipe_ReadWriteAllowed()))
+ for (;;)
{
+ if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
+ {
+ if (Pipe_IsINReceived())
+ return PIPE_READYWAIT_NoError;
+ }
+ else
+ {
+ if (Pipe_IsOUTReady())
+ return PIPE_READYWAIT_NoError;
+ }
+
if (Pipe_IsStalled())
return PIPE_READYWAIT_PipeStalled;
else if (!(USB_IsConnected))
@@ -89,8 +100,6 @@ uint8_t Pipe_WaitUntilReady(void)
return PIPE_READYWAIT_Timeout;
}
}
-
- return PIPE_READYWAIT_NoError;
}
uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
@@ -107,9 +116,9 @@ uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
while (Length--)
{
- if (!(Pipe_ReadWriteAllowed()))
+ if (!(Pipe_IsReadWriteAllowed()))
{
- Pipe_ClearCurrentBank();
+ Pipe_ClearOUT();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -119,8 +128,10 @@ uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
}
-
- Pipe_Write_Byte(*(DataStream++));
+ else
+ {
+ Pipe_Write_Byte(*(DataStream++));
+ }
}
return PIPE_RWSTREAM_ERROR_NoError;
@@ -140,9 +151,9 @@ uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
while (Length--)
{
- if (!(Pipe_ReadWriteAllowed()))
+ if (!(Pipe_IsReadWriteAllowed()))
{
- Pipe_ClearCurrentBank();
+ Pipe_ClearOUT();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -152,8 +163,10 @@ uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
}
-
- Pipe_Write_Byte(*(DataStream--));
+ else
+ {
+ Pipe_Write_Byte(*(DataStream--));
+ }
}
return PIPE_RWSTREAM_ERROR_NoError;
@@ -172,9 +185,9 @@ uint8_t Pipe_Discard_Stream(uint16_t Length
while (Length--)
{
- if (!(Pipe_ReadWriteAllowed()))
+ if (!(Pipe_IsReadWriteAllowed()))
{
- Pipe_ClearCurrentBank();
+ Pipe_ClearIN();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -184,8 +197,10 @@ uint8_t Pipe_Discard_Stream(uint16_t Length
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
}
-
- Pipe_Discard_Byte();
+ else
+ {
+ Pipe_Discard_Byte();
+ }
}
return PIPE_RWSTREAM_ERROR_NoError;
@@ -205,9 +220,9 @@ uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Pipe_ReadWriteAllowed()))
+ if (!(Pipe_IsReadWriteAllowed()))
{
- Pipe_ClearCurrentBank();
+ Pipe_ClearIN();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -217,8 +232,10 @@ uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
}
-
- *(DataStream++) = Pipe_Read_Byte();
+ else
+ {
+ *(DataStream++) = Pipe_Read_Byte();
+ }
}
return PIPE_RWSTREAM_ERROR_NoError;
@@ -238,9 +255,9 @@ uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
while (Length--)
{
- if (!(Pipe_ReadWriteAllowed()))
+ if (!(Pipe_IsReadWriteAllowed()))
{
- Pipe_ClearCurrentBank();
+ Pipe_ClearIN();
#if !defined(NO_STREAM_CALLBACKS)
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
@@ -250,8 +267,10 @@ uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
}
-
- *(DataStream--) = Pipe_Read_Byte();
+ else
+ {
+ *(DataStream--) = Pipe_Read_Byte();
+ }
}
return PIPE_RWSTREAM_ERROR_NoError;
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.h b/LUFA/Drivers/USB/LowLevel/Pipe.h
index 46a10e493..253ce2a93 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.h
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.h
@@ -35,6 +35,29 @@
* send/recieve functions for various data types.
*/
+/** \ingroup Group_USB
+ * @defgroup Group_PipeManagement Pipe Management
+ *
+ * Functions, macros, variables, enums and types related to the setup and management of pipes while in USB Device mode.
+ *
+ * @{
+ */
+
+/** @defgroup Group_PipeRW Pipe Data Reading and Writing
+ *
+ * Functions, macros, variables, enums and types related to data reading and writing from and to pipes.
+ */
+
+/** @defgroup Group_PipePacketManagement Pipe Packet Management
+ *
+ * Functions, macros, variables, enums and types related to packet management of pipes.
+ */
+
+/** @defgroup Group_PipeControlReq Pipe Control Request Management
+ *
+ * Functions, macros, variables, enums and types related to control request management of pipes.
+ */
+
#ifndef __PIPE_H__
#define __PIPE_H__
@@ -221,158 +244,339 @@
*/
#define PIPE_INT_STALL UPIENX, (1 << RXSTALLE), UPINTX, (1 << RXSTALLI)
- /** Indicates the number of bytes currently stored in the current pipe's selected bank. */
- #define Pipe_BytesInPipe() UPBCX
+ /* Psuedo-Function Macros: */
+ #if defined(__DOXYGEN__)
+ /** Indicates the number of bytes currently stored in the current pipes's selected bank.
+ *
+ * \note The return width of this function may differ, depending on the maximum pipe bank size
+ * of the selected AVR model.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Total number of bytes in the currently selected Pipe's FIFO buffer
+ */
+ static inline uint16_t Pipe_BytesInPipe(void);
+
+ /** Returns the pipe address of the currently selected pipe. This is typically used to save the
+ * currently selected pipe number so that it can be restored after another pipe has been manipulated.
+ *
+ * \return Index of the currently selected pipe
+ */
+ static inline uint8_t Pipe_GetCurrentPipe(void);
+
+ /** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
+ * indicated will operate on the currently selected pipe.
+ *
+ * \param PipeNumber Index of the pipe to select
+ */
+ static inline void Pipe_SelectPipe(uint8_t PipeNumber);
+
+ /** Resets the desired pipe, including the pipe banks and flags.
+ *
+ * \param PipeNumber Index of the pipe to reset
+ */
+ static inline void Pipe_ResetPipe(uint8_t PipeNumber);
+
+ /** Enables the currently selected pipe so that data can be sent and received through it to and from
+ * an attached device.
+ *
+ * \note Pipes must first be configured properly rather than just being enabled via the
+ * Pipe_ConfigurePipe() macro, which calls Pipe_EnablePipe() automatically.
+ */
+ static inline void Pipe_EnablePipe(void);
+
+ /** Disables the currently selected pipe so that data cannot be sent and received through it to and
+ * from an attached device.
+ */
+ static inline void Pipe_DisablePipe(void);
+
+ /** Determines if the currently selected pipe is enabled, but not necessarily configured.
+ *
+ * \return Boolean True if the currently selected pipe is enabled, false otherwise
+ */
+ static inline bool Pipe_IsEnabled(void);
+
+ /** Gets the current pipe token, indicating the pipe's data direction and type.
+ *
+ * \return The current pipe token, as a PIPE_TOKEN_* mask
+ */
+ static inline uint8_t Pipe_GetCurrentToken(void);
+
+ /** Sets the token for the currently selected pipe to one of the tokens specified by the PIPE_TOKEN_*
+ * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during
+ * control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices
+ * which have two endpoints of opposite direction sharing the same endpoint address within the device.
+ *
+ * \param Token New pipe token to set the selected pipe to, as a PIPE_TOKEN_* mask
+ */
+ static inline void Pipe_SetPipeToken(uint8_t Token);
+
+ /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
+ static inline void Pipe_SetInfiniteINRequests(void);
+
+ /** Configures the currently selected pipe to only allow the specified number of IN requests to be
+ * accepted by the pipe before it is automatically frozen.
+ *
+ * \param TotalINRequests Total number of IN requests that the pipe may receive before freezing
+ */
+ static inline void Pipe_SetFiniteINRequests(uint8_t TotalINRequests);
+
+ /** Determines if the currently selected pipe is configured.
+ *
+ * \return Boolean true if the selected pipe is configured, false otherwise
+ */
+ static inline bool Pipe_IsConfigured(void);
+
+ /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
+ *
+ * \param Milliseconds Number of milliseconds between each pipe poll
+ */
+ static inline void Pipe_SetInterruptPeriod(uint8_t Milliseconds);
+
+ /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
+ * be serviced.
+ *
+ * \return Mask whose bits indicate which pipes have interrupted
+ */
+ static inline uint8_t Pipe_GetPipeInterrupts(void);
+
+ /** Clears the interrupt flag for the specified pipe number.
+ *
+ * \param PipeNumber Index of the pipe whose interrupt flag is to be cleared
+ */
+ static inline void Pipe_ClearPipeInterrupt(uint8_t PipeNumber);
+
+ /** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
+ * pipes).
+ *
+ * \param PipeNumber Index of the pipe whose interrupt flag should be tested
+ *
+ * \return Boolean true if the specified pipe has interrupted, false otherwise
+ */
+ static inline bool Pipe_HasPipeInterrupted(uint8_t PipeNumber);
+
+ /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
+ static inline void Pipe_Unfreeze(void);
+
+ /** Freezes the selected pipe, preventing it from communicating with an attached device. */
+ static inline void Pipe_Freeze(void);
- /** Resets the desired pipe, including the pipe banks and flags. */
- #define Pipe_ResetPipe(pipenum) MACROS{ UPRST = (1 << pipenum); UPRST = 0; }MACROE
+ /** Clears the master pipe error flag. */
+ static inline void Pipe_ClearError(void);
+
+ /** Determines if the master pipe error flag is set for the currently selected pipe, indicating that
+ * some sort of hardware error has occurred on the pipe.
+ *
+ * \see Pipe_GetErrorFlags() macro for information on retrieving the exact error flag.
+ *
+ * \return Boolean true if an error has ocurred on the selected pipe, false otherwise
+ */
+ static inline bool Pipe_IsError(void);
+
+ /** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
+ * flag for the pipe.
+ */
+ static inline void Pipe_ClearErrorFlags(void);
+
+ /** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This
+ * value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred.
+ *
+ * \return Mask comprising of PIPE_ERRORFLAG_* bits indicating what error has ocurred on the selected pipe
+ */
+ static inline uint8_t Pipe_GetErrorFlags(void);
+
+ /** Determines if the currently selected pipe may be read from (if data is waiting in the pipe
+ * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
+ * direction). This function will return false if an error has occurred in the pipe, or if the pipe
+ * is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT
+ * direction and the pipe bank is full.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction
+ */
+ static inline bool Pipe_IsReadWriteAllowed(void);
+
+ /** Determines if an IN request has been received on the currently selected pipe.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if the current pipe has received an IN packet, false otherwise.
+ */
+ static inline bool Pipe_IsINReceived(void);
+
+ /** Determines if the currently selected pipe is ready to send an OUT request.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if the current pipe is ready for an OUT packet, false otherwise.
+ */
+ static inline bool Pipe_IsOUTReady(void);
+
+ /** Determines if no SETUP request is currently being sent to the attached device on the selected
+ * CONTROL type pipe.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if the current pipe is ready for a SETUP packet, false otherwise.
+ */
+ static inline bool Pipe_IsSETUPSent(void);
+
+ /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
+ * CONTROL type pipe, freeing the bank ready for the next packet.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \note For non CONTROL type pipes, use Pipe_ClearIN() instead.
+ */
+ static inline void Pipe_ClearControlIN(void);
+
+ /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
+ * the bank ready for the next packet.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \note For non CONTROL type pipes, use Pipe_ClearOUT() instead.
+ */
+ static inline void Pipe_ClearControlOUT(void);
+
+ /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \note This is not applicable for non CONTROL type pipes.
+ */
+ static inline void Pipe_ClearControlSETUP(void);
+
+ /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
+ * pipe, freeing the bank ready for the next packet.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \note For CONTROL type pipes, use Pipe_ClearControlIN() instead.
+ */
+ static inline void Pipe_ClearIN(void);
+
+ /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
+ * the bank ready for the next packet.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \note For CONTROL type pipes, use Pipe_ClearControlOUT() instead.
+ */
+ static inline void Pipe_ClearOUT(void);
+
+ /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
+ * the currently selected pipe. This occurs when the host sends a packet to the device, but the device
+ * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
+ * received, it must be cleared using Pipe_ClearNAKReceived() before the previous (or any other) packet
+ * can be re-sent.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if an NAK has been received on the current pipe, false otherwise
+ */
+ static inline bool Pipe_IsNAKReceived(void);
+
+ /** Clears the NAK condition on the currently selected pipe.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \see Pipe_IsNAKReceived() for more details.
+ */
+ static inline void Pipe_ClearNAKReceived(void);
+
+ /** Determines if the currently selected pipe has had the STALL condition set by the attached device.
+ *
+ * \ingroup Group_PipePacketManagement
+ *
+ * \return Boolean true if the current pipe has been stalled by the attached device, false otherwise
+ */
+ static inline bool Pipe_IsStalled(void);
+
+ /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the
+ * STALL condition itself (this must be done via a ClearFeature control request to the device).
+ *
+ * \ingroup Group_PipePacketManagement
+ */
+ static inline void Pipe_ClearStall(void);
+ #else
+ #define Pipe_BytesInPipe() UPBCX
- /** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
- * indicated will operate on the currently selected pipe.
- */
- #define Pipe_SelectPipe(pipenum) MACROS{ UPNUM = pipenum; }MACROE
+ #define Pipe_GetCurrentPipe() (UPNUM & PIPE_PIPENUM_MASK)
- /** Returns the pipe address of the currently selected pipe. This is typically used to save the
- * currently selected pipe number so that it can be restored after another pipe has been manipulated.
- */
- #define Pipe_GetCurrentPipe() (UPNUM & PIPE_PIPENUM_MASK)
+ #define Pipe_SelectPipe(pipenum) MACROS{ UPNUM = pipenum; }MACROE
+
+ #define Pipe_ResetPipe(pipenum) MACROS{ UPRST = (1 << pipenum); UPRST = 0; }MACROE
- /** Enables the currently selected pipe so that data can be sent and received through it to and from
- * an attached device.
- *
- * \note Pipes must first be configured properly rather than just being enabled via the
- * Pipe_ConfigurePipe() macro, which calls Pipe_EnablePipe() automatically.
- */
- #define Pipe_EnablePipe() MACROS{ UPCONX |= (1 << PEN); }MACROE
+ #define Pipe_EnablePipe() MACROS{ UPCONX |= (1 << PEN); }MACROE
- /** Disables the currently selected pipe so that data cannot be sent and received through it to and
- * from an attached device.
- */
- #define Pipe_DisablePipe() MACROS{ UPCONX &= ~(1 << PEN); }MACROE
+ #define Pipe_DisablePipe() MACROS{ UPCONX &= ~(1 << PEN); }MACROE
- /** Returns true if the currently selected pipe is enabled, false otherwise. */
- #define Pipe_IsEnabled() ((UPCONX & (1 << PEN)) ? true : false)
+ #define Pipe_IsEnabled() ((UPCONX & (1 << PEN)) ? true : false)
- /** Sets the token for the currently selected endpoint to one of the tokens specified by the PIPE_TOKEN_*
- * masks. This should only be used on CONTROL type endpoints, to allow for bidirectional transfer of
- * data during control requests.
- */
- #define Pipe_SetToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | token); }MACROE
-
- /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
- #define Pipe_SetInfiniteINRequests() MACROS{ UPCONX |= (1 << INMODE); }MACROE
+ #define Pipe_GetPipeToken() (UPCFG0X & PIPE_TOKEN_MASK)
- /** Configures the currently selected pipe to only allow the specified number of IN requests to be
- * accepted by the pipe before it is automatically frozen.
- */
- #define Pipe_SetFiniteINRequests(n) MACROS{ UPCONX &= ~(1 << INMODE); UPINRQX = n; }MACROE
+ #define Pipe_SetToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | token); }MACROE
+
+ #define Pipe_SetInfiniteINRequests() MACROS{ UPCONX |= (1 << INMODE); }MACROE
- /** Returns true if the currently selected pipe is configured, false otherwise. */
- #define Pipe_IsConfigured() ((UPSTAX & (1 << CFGOK)) ? true : false)
+ #define Pipe_SetFiniteINRequests(n) MACROS{ UPCONX &= ~(1 << INMODE); UPINRQX = n; }MACROE
- /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds. */
- #define Pipe_SetInterruptPeriod(ms) MACROS{ UPCFG2X = ms; }MACROE
+ #define Pipe_IsConfigured() ((UPSTAX & (1 << CFGOK)) ? true : false)
- /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
- * be serviced.
- */
- #define Pipe_GetPipeInterrupts() UPINT
+ #define Pipe_SetInterruptPeriod(ms) MACROS{ UPCFG2X = ms; }MACROE
- /** Clears the interrupt flag for the specified pipe number. */
- #define Pipe_ClearPipeInterrupt(n) MACROS{ UPINT &= ~(1 << n); }MACROE
+ #define Pipe_GetPipeInterrupts() UPINT
- /** Returns true if the specified pipe's interrupt period has elapsed, false otherwise. */
- #define Pipe_HasPipeInterrupted(n) ((UPINT & (1 << n)) ? true : false)
-
- /** Clears the pipe bank, and switches to the alternate bank if the currently selected pipe is
- * dual-banked. When cleared, this either frees the bank up for the next packet from the host
- * (if the endpoint is of the OUT direction) or sends the packet contents to the host (if the
- * pipe is of the IN direction).
- */
- #define Pipe_ClearCurrentBank() MACROS{ UPINTX &= ~(1 << FIFOCON); }MACROE
+ #define Pipe_ClearPipeInterrupt(n) MACROS{ UPINT &= ~(1 << n); }MACROE
- /** Unfreezes the pipe, allowing it to communicate with an attached device. */
- #define Pipe_Unfreeze() MACROS{ UPCONX &= ~(1 << PFREEZE); }MACROE
+ #define Pipe_HasPipeInterrupted(n) ((UPINT & (1 << n)) ? true : false)
- /** Freezes the pipe, preventing it from communicating with an attached device. */
- #define Pipe_Freeze() MACROS{ UPCONX |= (1 << PFREEZE); }MACROE
+ #define Pipe_Unfreeze() MACROS{ UPCONX &= ~(1 << PFREEZE); }MACROE
- /** Clears the master pipe error flag. */
- #define Pipe_ClearError() MACROS{ UPINTX &= ~(1 << PERRI); }MACROE
+ #define Pipe_Freeze() MACROS{ UPCONX |= (1 << PFREEZE); }MACROE
- /** Returns true if the master pipe error flag is set for the currently selected pipe, indicating that
- * some sort of hardware error has occurred on the pipe.
- *
- * \see Pipe_GetErrorFlags() macro for information on retrieving the exact error flag.
- */
- #define Pipe_IsError() ((UPINTX & (1 << PERRI)) ? true : false)
-
- /** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
- * flag for the pipe. */
- #define Pipe_ClearErrorFlags() MACROS{ UPERRX = 0; }MACROE
+ #define Pipe_ClearError() MACROS{ UPINTX &= ~(1 << PERRI); }MACROE
- /** Returns a mask of the hardware error flags which have occurred on the currently selected pipe. This
- * value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred.
- */
- #define Pipe_GetErrorFlags() UPERRX
+ #define Pipe_IsError() ((UPINTX & (1 << PERRI)) ? true : false)
+
+ #define Pipe_ClearErrorFlags() MACROS{ UPERRX = 0; }MACROE
- /** Returns true if the currently selected pipe may be read from (if data is waiting in the pipe
- * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
- * direction). This function will return false if an error has occurred in the pipe, or if the pipe
- * is an IN direction and no packet has been received, or if the pipe is an OUT direction and the
- * pipe bank is full.
- */
- #define Pipe_ReadWriteAllowed() ((UPINTX & (1 << RWAL)) ? true : false)
+ #define Pipe_GetErrorFlags() UPERRX
- /** Clears the flag indicating that a SETUP request has been sent to the attached device from the
- * currently selected CONTROL type pipe.
- */
- #define Pipe_ClearSetupSent() MACROS{ UPINTX &= ~(1 << TXSTPI); }MACROE
+ #define Pipe_IsReadWriteAllowed() ((UPINTX & (1 << RWAL)) ? true : false)
- /** Returns true if no SETUP request is currently being sent to the attached device, false otherwise. */
- #define Pipe_IsSetupSent() ((UPINTX & (1 << TXSTPI)) ? true : false)
+ #define Pipe_IsINReceived() ((UPINTX & (1 << RXINI)) ? true : false)
- /** Returns true if the currently selected pipe has been stalled by the attached device, false otherwise. */
- #define Pipe_IsStalled() ((UPINTX & (1 << RXSTALLI)) ? true : false)
+ #define Pipe_IsOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false)
- /** Clears the stall condition on the currently selected pipe. */
- #define Pipe_ClearStall() MACROS{ UPINTX &= ~(1 << RXSTALLI); }MACROE
+ #define Pipe_IsSETUPSent() ((UPINTX & (1 << TXSTPI)) ? true : false)
- /** Returns true if an IN request has been received on the currently selected CONTROL type pipe, false
- * otherwise.
- */
- #define Pipe_IsSetupINReceived() ((UPINTX & (1 << RXINI)) ? true : false)
+ #define Pipe_ClearIN() MACROS{ UPINTX &= ~(1 << RXINI); UPINTX &= ~(1 << FIFOCON); }MACROE
- /** Returns true if the currently selected CONTROL type pipe is ready to send an OUT request, false
- * otherwise.
- */
- #define Pipe_IsSetupOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false)
+ #define Pipe_ClearControlIN() MACROS{ UPINTX &= ~(1 << RXINI); UPINTX &= ~(1 << FIFOCON); }MACROE
- /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
- * CONTROL type endpoint, allowing for the transmission of a setup OUT packet, or the reception of
- * another setup IN packet.
- */
- #define Pipe_ClearSetupIN() MACROS{ UPINTX &= ~(1 << RXINI); UPINTX &= ~(1 << FIFOCON); }MACROE
+ #define Pipe_ClearOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE
+
+ #define Pipe_ClearControlOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE
- /** Sends the currently selected CONTROL type pipe's contents to the device as a setup OUT packet. */
- #define Pipe_ClearSetupOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE
-
- /** Returns true if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
- * the currently selected pipe. This occurs when the host sends a packet to the device, but the device
- * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
- * received, it must be cleared using Pipe_ClearNAKReceived() before the previous (or any other) packet
- * can be re-sent.
- */
- #define Pipe_IsNAKReceived() ((UPINTX & (1 << NAKEDI)) ? true : false)
+ #define Pipe_ClearControlSETUP() MACROS{ UPINTX &= ~(1 << TXSTPI); UPINTX &= ~(1 << FIFOCON); }MACROE
- /** Clears the NAK condition on the currently selected pipe.
- *
- * \see Pipe_IsNAKReceived() for more details.
- */
- #define Pipe_ClearNAKReceived() MACROS{ UPINTX &= ~(1 << NAKEDI); }MACROE
+ #define Pipe_IsNAKReceived() ((UPINTX & (1 << NAKEDI)) ? true : false)
+
+ #define Pipe_ClearNAKReceived() MACROS{ UPINTX &= ~(1 << NAKEDI); }MACROE
+
+ #define Pipe_IsStalled() ((UPINTX & (1 << RXSTALLI)) ? true : false)
+
+ #define Pipe_ClearStall() MACROS{ UPINTX &= ~(1 << RXSTALLI); }MACROE
+ #endif
/* Enums: */
- /** Enum for the possible error return codes of the Pipe_WaitUntilReady function */
+ /** Enum for the possible error return codes of the Pipe_WaitUntilReady function
+ *
+ * \ingroup Group_PipeRW
+ */
enum Pipe_WaitUntilReady_ErrorCodes_t
{
PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error */
@@ -384,7 +588,10 @@
*/
};
- /** Enum for the possible error return codes of the Pipe_*_Stream_* functions. */
+ /** Enum for the possible error return codes of the Pipe_*_Stream_* functions.
+ *
+ * \ingroup Group_PipeRW
+ */
enum Pipe_Stream_RW_ErrorCodes_t
{
PIPE_RWSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
@@ -402,21 +609,34 @@
};
/* Inline Functions: */
- /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes. */
+ /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Next byte in the currently selected pipe's FIFO buffer
+ */
static inline uint8_t Pipe_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_Read_Byte(void)
{
return UPDATX;
}
- /** Writes one byte from the currently selected pipe's bank, for IN direction pipes. */
+ /** Writes one byte from the currently selected pipe's bank, for IN direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \param Byte Next byte to write into the the currently selected pipe's FIFO buffer
+ */
static inline void Pipe_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
static inline void Pipe_Write_Byte(const uint8_t Byte)
{
UPDATX = Byte;
}
- /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes. */
+ /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ */
static inline void Pipe_Discard_Byte(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_Discard_Byte(void)
{
@@ -427,6 +647,10 @@
/** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Next word in the currently selected pipe's FIFO buffer
*/
static inline uint16_t Pipe_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Pipe_Read_Word_LE(void)
@@ -441,6 +665,10 @@
/** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Next word in the currently selected pipe's FIFO buffer
*/
static inline uint16_t Pipe_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Pipe_Read_Word_BE(void)
@@ -455,6 +683,10 @@
/** Writes two bytes to the currently selected pipe's bank in little endian format, for IN
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \param Word Next word to write to the currently selected pipe's FIFO buffer
*/
static inline void Pipe_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE;
static inline void Pipe_Write_Word_LE(const uint16_t Word)
@@ -465,6 +697,10 @@
/** Writes two bytes to the currently selected pipe's bank in big endian format, for IN
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \param Word Next word to write to the currently selected pipe's FIFO buffer
*/
static inline void Pipe_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE;
static inline void Pipe_Write_Word_BE(const uint16_t Word)
@@ -473,9 +709,12 @@
UPDATX = (Word & 0xFF);
}
- /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes. */
- static inline void Pipe_Ignore_Word(void) ATTR_ALWAYS_INLINE;
- static inline void Pipe_Ignore_Word(void)
+ /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ */
+ static inline void Pipe_Discard_Word(void) ATTR_ALWAYS_INLINE;
+ static inline void Pipe_Discard_Word(void)
{
uint8_t Dummy;
@@ -485,6 +724,10 @@
/** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Next double word in the currently selected pipe's FIFO buffer
*/
static inline uint32_t Pipe_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint32_t Pipe_Read_DWord_LE(void)
@@ -505,6 +748,10 @@
/** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \return Next double word in the currently selected pipe's FIFO buffer
*/
static inline uint32_t Pipe_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint32_t Pipe_Read_DWord_BE(void)
@@ -525,6 +772,10 @@
/** Writes four bytes to the currently selected pipe's bank in little endian format, for IN
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \param DWord Next double word to write to the currently selected pipe's FIFO buffer
*/
static inline void Pipe_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE;
static inline void Pipe_Write_DWord_LE(const uint32_t DWord)
@@ -535,6 +786,10 @@
/** Writes four bytes to the currently selected pipe's bank in big endian format, for IN
* direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ *
+ * \param DWord Next double word to write to the currently selected pipe's FIFO buffer
*/
static inline void Pipe_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE;
static inline void Pipe_Write_DWord_BE(const uint32_t DWord)
@@ -543,7 +798,10 @@
Pipe_Write_Word_BE(DWord);
}
- /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes. */
+ /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes.
+ *
+ * \ingroup Group_PipeRW
+ */
static inline void Pipe_Ignore_DWord(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_Ignore_DWord(void)
{
@@ -595,6 +853,8 @@
*
* \note This routine should not be called on CONTROL type pipes.
*
+ * \ingroup Group_PipeRW
+ *
* \return A value from the Pipe_WaitUntilReady_ErrorCodes_t enum.
*/
uint8_t Pipe_WaitUntilReady(void);
@@ -602,13 +862,15 @@
/** Writes the given number of bytes to the pipe from the given buffer in little endian,
* sending full packets to the device as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
+ * Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
*
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
* and this function has the Callback parameter omitted.
*
+ * \ingroup Group_PipeRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected pipe into the buffer.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -624,13 +886,15 @@
/** Writes the given number of bytes to the pipe from the given buffer in big endian,
* sending full packets to the device as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
+ * Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
*
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
* and this function has the Callback parameter omitted.
*
+ * \ingroup Group_PipeRW
+ *
* \param Buffer Pointer to the source data buffer to read from.
* \param Length Number of bytes to read for the currently selected pipe into the buffer.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -645,7 +909,7 @@
/** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host
* as needed. The last packet is not automatically discarded once the remaining bytes has been read; the
- * user is responsible for manually discarding the last packet from the host via the Pipe_ClearCurrentBank() macro.
+ * user is responsible for manually discarding the last packet from the device via the Pipe_ClearIN() macro.
* Between each USB packet, the given stream callback function is executed repeatedly until the next packet is ready,
* allowing for early aborts of stream transfers.
*
@@ -653,6 +917,8 @@
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
* and this function has the Callback parameter omitted.
*
+ * \ingroup Group_PipeRW
+ *
* \param Length Number of bytes to send via the currently selected pipe.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
*
@@ -667,13 +933,15 @@
/** Reads the given number of bytes from the pipe into the given buffer in little endian,
* sending full packets to the device as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
+ * Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
*
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
* and this function has the Callback parameter omitted.
*
+ * \ingroup Group_PipeRW
+ *
* \param Buffer Pointer to the source data buffer to write to.
* \param Length Number of bytes to read for the currently selected pipe to read from.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -689,13 +957,15 @@
/** Reads the given number of bytes from the pipe into the given buffer in big endian,
* sending full packets to the device as needed. The last packet filled is not automatically sent;
* the user is responsible for manually sending the last written packet to the host via the
- * Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
+ * Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
*
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
* and this function has the Callback parameter omitted.
*
+ * \ingroup Group_PipeRW
+ *
* \param Buffer Pointer to the source data buffer to write to.
* \param Length Number of bytes to read for the currently selected pipe to read from.
* \param Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback
@@ -706,58 +976,7 @@
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
, uint8_t (* const Callback)(void)
#endif
- ) ATTR_NON_NULL_PTR_ARG(1);
-
- /* Function Aliases: */
- /** Alias for Pipe_Discard_Byte().
- */
- #define Pipe_Ignore_Byte() Pipe_Discard_Byte()
-
- /** Alias for Pipe_Discard_Word().
- */
- #define Pipe_Ignore_Word() Pipe_Discard_Word()
-
- /** Alias for Pipe_Discard_DWord().
- */
- #define Pipe_Ignore_DWord() Pipe_Discard_DWord()
-
- /** Alias for Pipe_Read_Word_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Pipe_Read_Word() Pipe_Read_Word_LE()
-
- /** Alias for Pipe_Write_Word_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Pipe_Write_Word(Word) Pipe_Write_Word_LE(Word)
-
- /** Alias for Pipe_Read_DWord_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Pipe_Read_DWord() Pipe_Read_DWord_LE()
-
- /** Alias for Pipe_Write_DWord_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #define Pipe_Write_DWord(DWord) Pipe_Write_DWord_LE(DWord)
-
- /** Alias for Pipe_Read_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #if !defined(NO_STREAM_CALLBACKS)
- #define Pipe_Read_Stream(Buffer, Length, Callback) Pipe_Read_Stream_LE(Buffer, Length, Callback)
- #else
- #define Pipe_Read_Stream(Buffer, Length) Pipe_Read_Stream_LE(Buffer, Length)
- #endif
-
- /** Alias for Pipe_Write_Stream_LE(). By default USB transfers use little endian format, thus
- * the command with no endianness specified indicates little endian mode.
- */
- #if !defined(NO_STREAM_CALLBACKS)
- #define Pipe_Write_Stream(Buffer, Length, Callback) Pipe_Read_Stream_LE(Buffer, Length, Callback)
- #else
- #define Pipe_Write_Stream(Buffer, Length) Pipe_Read_Stream_LE(Buffer, Length)
- #endif
+ ) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
@@ -794,5 +1013,7 @@
#if defined(__cplusplus)
}
#endif
-
+
#endif
+
+/** @} */
diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h
index 499c59be2..75fff2fcd 100644
--- a/LUFA/Drivers/USB/USB.h
+++ b/LUFA/Drivers/USB/USB.h
@@ -38,6 +38,11 @@
* the USB library unless desired by the library user.
*/
+/** @defgroup Group_USB USB - LUFA/Drivers/USB/USB.h
+ *
+ * Functions, macros, variables, enums and types related to the management of USB communications.
+ */
+
#ifndef __USB_H__
#define __USB_H__
@@ -79,5 +84,8 @@
#include "LowLevel/OTG.h"
#endif
+ #include "Class/ConfigDescriptor.h"
+ #include "Class/HIDParser.h"
+
#endif