diff options
Diffstat (limited to 'LUFA/Drivers/USB/HighLevel')
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/EndpointStream.c | 120 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/EndpointStream.h | 549 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/PipeStream.c | 90 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/PipeStream.h | 435 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/StreamCallbacks.h | 87 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_R.c | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_W.c | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_RW.c | 25 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/Template/Template_Pipe_RW.c | 26 |
9 files changed, 864 insertions, 472 deletions
diff --git a/LUFA/Drivers/USB/HighLevel/EndpointStream.c b/LUFA/Drivers/USB/HighLevel/EndpointStream.c index c2bb3922c..974af682c 100644 --- a/LUFA/Drivers/USB/HighLevel/EndpointStream.c +++ b/LUFA/Drivers/USB/HighLevel/EndpointStream.c @@ -36,13 +36,17 @@ #include "EndpointStream.h"
#if !defined(CONTROL_ONLY_DEVICE)
-uint8_t Endpoint_Discard_Stream(uint16_t Length
- __CALLBACK_PARAM)
+uint8_t Endpoint_Discard_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed)
{
- uint8_t ErrorCode;
+ uint8_t ErrorCode;
+ uint16_t BytesInTransfer = 0;
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
+
+ if (BytesProcessed != NULL)
+ Length -= *BytesProcessed;
while (Length)
{
@@ -50,10 +54,11 @@ uint8_t Endpoint_Discard_Stream(uint16_t Length {
Endpoint_ClearOUT();
- #if !defined(NO_STREAM_CALLBACKS)
- if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
- return ENDPOINT_RWSTREAM_CallbackAborted;
- #endif
+ if (BytesProcessed != NULL)
+ {
+ *BytesProcessed += BytesInTransfer;
+ return ENDPOINT_RWSTREAM_IncompleteTransfer;
+ }
if ((ErrorCode = Endpoint_WaitUntilReady()))
return ErrorCode;
@@ -61,7 +66,48 @@ uint8_t Endpoint_Discard_Stream(uint16_t Length else
{
Endpoint_Discard_Byte();
+
+ Length--;
+ BytesInTransfer++;
+ }
+ }
+
+ return ENDPOINT_RWSTREAM_NoError;
+}
+
+uint8_t Endpoint_Null_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed)
+{
+ uint8_t ErrorCode;
+ uint16_t BytesInTransfer = 0;
+
+ if ((ErrorCode = Endpoint_WaitUntilReady()))
+ return ErrorCode;
+
+ if (BytesProcessed != NULL)
+ Length -= *BytesProcessed;
+
+ while (Length)
+ {
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+
+ if (BytesProcessed != NULL)
+ {
+ *BytesProcessed += BytesInTransfer;
+ return ENDPOINT_RWSTREAM_IncompleteTransfer;
+ }
+
+ if ((ErrorCode = Endpoint_WaitUntilReady()))
+ return ErrorCode;
+ }
+ else
+ {
+ Endpoint_Write_Byte(0);
+
Length--;
+ BytesInTransfer++;
}
}
@@ -72,122 +118,142 @@ uint8_t Endpoint_Discard_Stream(uint16_t Length #define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*BufferPtr)
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE
#define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE
#define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE
#define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*BufferPtr)
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE
#define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE
#define TEMPLATE_BUFFER_TYPE const void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE
#define TEMPLATE_BUFFER_TYPE void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_Byte()
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE
#define TEMPLATE_BUFFER_TYPE void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_Byte())
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE
#define TEMPLATE_BUFFER_TYPE void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_Byte()
#include "Template/Template_Endpoint_RW.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE
#define TEMPLATE_BUFFER_TYPE void*
#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_Byte())
#include "Template/Template_Endpoint_RW.c"
#endif
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*BufferPtr)
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*BufferPtr)
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Endpoint_Control_W.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_Byte()
#include "Template/Template_Endpoint_Control_R.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_Byte())
#include "Template/Template_Endpoint_Control_R.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_Byte()
#include "Template/Template_Endpoint_Control_R.c"
#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_Byte())
#include "Template/Template_Endpoint_Control_R.c"
#endif diff --git a/LUFA/Drivers/USB/HighLevel/EndpointStream.h b/LUFA/Drivers/USB/HighLevel/EndpointStream.h index 6d8491b58..cd4a2185b 100644 --- a/LUFA/Drivers/USB/HighLevel/EndpointStream.h +++ b/LUFA/Drivers/USB/HighLevel/EndpointStream.h @@ -57,10 +57,6 @@ #include "../../../Common/Common.h"
#include "USBTask.h"
-
- #if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
- #include "StreamCallbacks.h"
- #endif
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
@@ -72,12 +68,6 @@ #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
#endif
- #if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
- #define __CALLBACK_PARAM , StreamCallbackPtr_t Callback
- #else
- #define __CALLBACK_PARAM
- #endif
-
/* Public Interface - May be used in end-application: */
/* Enums: */
/** Enum for the possible error return codes of the \c Endpoint_*_Stream_* functions. */
@@ -98,8 +88,10 @@ * within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
- ENDPOINT_RWSTREAM_CallbackAborted = 5, /**< Indicates that the stream's callback function
- * aborted the transfer early.
+ ENDPOINT_RWSTREAM_IncompleteTransfer = 5, /**< Indicates that the endpoint bank became full or empty before
+ * the complete contents of the current stream could be
+ * transferred. The endpoint stream function should be called
+ * again to process the next chunk of data in the transfer.
*/
};
@@ -118,194 +110,274 @@ };
/* Function Prototypes: */
- /** Reads and discards the given number of bytes from the endpoint from the given buffer,
+
+ /** \name Stream functions for null data */
+ //@{
+
+ /** Reads and discards the given number of bytes from the currently selected endpoint's bank,
* 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 \ref 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.
- *
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * If the token \c NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are
- * disabled and this function has the Callback parameter omitted.
+ * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
+ *
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the endpoint bank becomes empty while there is still data to process (and after the current
+ * packet has been acknowledged) the BytesProcessed location will be updated with the total number
+ * of bytes processed in the stream, and the function will exit with an error code of
+ * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
*
* \note This routine should not be used on CONTROL type endpoints.
*
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[in] Length Number of bytes to discard via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Discard_Stream(uint16_t Length
- __CALLBACK_PARAM);
-
- /** 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
- * \ref 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.
- *
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * If the token \c NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are
- * disabled and this function has the Callback parameter omitted.
+ uint8_t Endpoint_Discard_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed);
+
+ /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending
+ * full packets to the host as needed. The last packet is not automatically sent once the
+ * remaining bytes have been written; the user is responsible for manually sending the last
+ * packet to the host via the \ref Endpoint_ClearIN() macro.
+ *
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the endpoint bank becomes full while there is still data to process (and after the current
+ * packet transmission has been initiated) the BytesProcessed location will be updated with the
+ * total number of bytes processed in the stream, and the function will exit with an error code of
+ * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
*
* \note This routine should not be used on CONTROL type endpoints.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[in] Length Number of zero bytes to send via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Stream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Null_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed);
- /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE().
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
- *
- * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Endpoint_Write_EStream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
- /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE().
+ /** \name Stream functions for RAM source/destination data */
+ //@{
+
+ /** 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
+ * \ref Endpoint_ClearIN() macro.
+ *
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the endpoint bank becomes full while there is still data to process (and after the current
+ * packet transmission has been initiated) the BytesProcessed location will be updated with the
+ * total number of bytes processed in the stream, and the function will exit with an error code of
+ * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream),
+ * NULL)) != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream),
+ * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
*
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ * \note This routine should not be used on CONTROL type endpoints.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_PStream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Write_Stream_LE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
/** 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
- * \ref 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.
- *
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * If the token \c NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are
- * disabled and this function has the Callback parameter omitted.
+ * \ref Endpoint_ClearIN() macro.
*
* \note This routine should not be used on CONTROL type endpoints.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Endpoint_Write_Stream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE().
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
- *
- * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Endpoint_Write_EStream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE().
- *
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
- *
- * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Endpoint_Write_PStream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
/** 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 \ref 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.
- *
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * If the token \c NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are
- * disabled and this function has the Callback parameter omitted.
+ * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
+ *
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the endpoint bank becomes empty while there is still data to process (and after the current
+ * packet has been acknowledged) the BytesProcessed location will be updated with the total number
+ * of bytes processed in the stream, and the function will exit with an error code of
+ * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream),
+ * NULL)) != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream),
+ * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != ENDPOINT_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
*
* \note This routine should not be used on CONTROL type endpoints.
*
- * \param[out] Buffer Pointer to the destination data buffer to write to.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[out] Buffer Pointer to the destination data buffer to write to.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Endpoint_Read_Stream_LE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of \ref Endpoint_Read_Stream_LE().
- *
- * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
- *
- * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Endpoint_Read_EStream_LE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
/** 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 \ref 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.
- *
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * If the token \c NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are
- * disabled and this function has the Callback parameter omitted.
+ * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro.
*
* \note This routine should not be used on CONTROL type endpoints.
*
- * \param[out] Buffer Pointer to the destination data buffer to write to.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
+ * \param[out] Buffer Pointer to the destination data buffer to write to.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Endpoint_Read_Stream_BE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** EEPROM buffer source version of \ref Endpoint_Read_Stream_BE().
- *
- * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, \c NULL if no callback.
- *
- * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Endpoint_Read_EStream_BE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
/** 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
@@ -329,7 +401,10 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE.
+ /** 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 \ref Endpoint_ClearOUT() macro.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -345,12 +420,13 @@ *
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Control_EStream_LE(const void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE().
- *
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ /** 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 \ref Endpoint_ClearIN() macro.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -361,18 +437,18 @@ * \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.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[out] Buffer Pointer to the destination data buffer to write to.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
*
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Control_PStream_LE(const void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** 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 \ref Endpoint_ClearOUT() macro.
+ /** 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 \ref Endpoint_ClearIN() macro.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -383,15 +459,71 @@ * \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.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[out] Buffer Pointer to the destination data buffer to write to.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
*
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
- /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE().
+ /** \name Stream functions for EEPROM source/destination data */
+ //@{
+
+ /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE().
+ *
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Write_EStream_LE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE().
+ *
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Write_EStream_BE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of \ref Endpoint_Read_Stream_LE().
+ *
+ * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Read_EStream_LE(void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of \ref Endpoint_Read_Stream_BE().
+ *
+ * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space.
+ * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be read at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Read_EStream_BE(void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -407,12 +539,10 @@ *
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Control_EStream_BE(const void* Buffer,
+ uint8_t Endpoint_Write_Control_EStream_LE(const void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE().
- *
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE().
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -428,13 +558,10 @@ *
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Write_Control_PStream_BE(const void* Buffer,
+ uint8_t Endpoint_Write_Control_EStream_BE(const void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** 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 \ref Endpoint_ClearIN() macro.
+ /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE().
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -450,10 +577,10 @@ *
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Read_Control_EStream_LE(void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE().
+ /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE().
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -469,13 +596,46 @@ *
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Read_Control_EStream_LE(void* Buffer,
+ uint8_t Endpoint_Read_Control_EStream_BE(void* Buffer,
uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
- /** 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 \ref Endpoint_ClearIN() macro.
+ /** \name Stream functions for PROGMEM source/destination data */
+ //@{
+
+ /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE().
+ *
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ *
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Write_PStream_LE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE().
+ *
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ *
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current
+ * transaction should be updated, \c NULL if the entire stream should be written at once.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Endpoint_Write_PStream_BE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE().
+ *
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -486,15 +646,17 @@ * \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.
*
- * \param[out] Buffer Pointer to the destination data buffer to write to.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
*
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
-
- /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE().
+ uint8_t Endpoint_Write_Control_PStream_LE(const void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE().
+ *
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
*
* \note This function automatically clears the control transfer's status stage. Do not manually attempt
* to clear the status stage when using this routine in a control transaction.
@@ -505,13 +667,14 @@ * \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.
*
- * \param[out] Buffer Pointer to the destination data buffer to write to.
- * \param[in] Length Number of bytes to send via the currently selected endpoint.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer.
*
* \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum.
*/
- uint8_t Endpoint_Read_Control_EStream_BE(void* Buffer,
- uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Endpoint_Write_Control_PStream_BE(const void* Buffer,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/HighLevel/PipeStream.c b/LUFA/Drivers/USB/HighLevel/PipeStream.c index 98c57206f..9f8898177 100644 --- a/LUFA/Drivers/USB/HighLevel/PipeStream.c +++ b/LUFA/Drivers/USB/HighLevel/PipeStream.c @@ -35,26 +35,31 @@ #include "PipeStream.h"
-uint8_t Pipe_Discard_Stream(uint16_t Length
- __CALLBACK_PARAM)
+uint8_t Pipe_Discard_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed)
{
uint8_t ErrorCode;
+ uint16_t BytesInTransfer = 0;
Pipe_SetPipeToken(PIPE_TOKEN_IN);
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
+ if (BytesProcessed != NULL)
+ Length -= *BytesProcessed;
+
while (Length)
{
if (!(Pipe_IsReadWriteAllowed()))
{
Pipe_ClearIN();
- #if !defined(NO_STREAM_CALLBACKS)
- if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
- return PIPE_RWSTREAM_CallbackAborted;
- #endif
+ if (BytesProcessed != NULL)
+ {
+ *BytesProcessed += BytesInTransfer;
+ return PIPE_RWSTREAM_IncompleteTransfer;
+ }
if ((ErrorCode = Pipe_WaitUntilReady()))
return ErrorCode;
@@ -62,7 +67,50 @@ uint8_t Pipe_Discard_Stream(uint16_t Length else
{
Pipe_Discard_Byte();
+
+ Length--;
+ BytesInTransfer++;
+ }
+ }
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t Pipe_Null_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed)
+{
+ uint8_t ErrorCode;
+ uint16_t BytesInTransfer = 0;
+
+ Pipe_SetPipeToken(PIPE_TOKEN_OUT);
+
+ if ((ErrorCode = Pipe_WaitUntilReady()))
+ return ErrorCode;
+
+ if (BytesProcessed != NULL)
+ Length -= *BytesProcessed;
+
+ while (Length)
+ {
+ if (!(Pipe_IsReadWriteAllowed()))
+ {
+ Pipe_ClearOUT();
+
+ if (BytesProcessed != NULL)
+ {
+ *BytesProcessed += BytesInTransfer;
+ return PIPE_RWSTREAM_IncompleteTransfer;
+ }
+
+ if ((ErrorCode = Pipe_WaitUntilReady()))
+ return ErrorCode;
+ }
+ else
+ {
+ Pipe_Write_Byte(0);
+
Length--;
+ BytesInTransfer++;
}
}
@@ -77,7 +125,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(*((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(*BufferPtr)
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_LE
@@ -85,7 +134,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_LE
@@ -93,7 +143,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE
@@ -101,7 +152,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(*((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(*BufferPtr)
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_BE
@@ -109,7 +161,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(pgm_read_byte(BufferPtr))
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_BE
@@ -117,7 +170,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_OUT
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_Byte(eeprom_read_byte(BufferPtr))
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE
@@ -125,7 +179,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_IN
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Pipe_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_Byte()
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_LE
@@ -133,7 +188,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_IN
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) 0
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr++, Pipe_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_Byte())
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE
@@ -141,7 +197,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_IN
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Pipe_Read_Byte()
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_Byte()
#include "Template/Template_Pipe_RW.c"
#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_BE
@@ -149,7 +206,8 @@ uint8_t Pipe_Discard_Stream(uint16_t Length #define TEMPLATE_TOKEN PIPE_TOKEN_IN
#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN()
#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
-#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr--, Pipe_Read_Byte())
+#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount
+#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_Byte())
#include "Template/Template_Pipe_RW.c"
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/PipeStream.h b/LUFA/Drivers/USB/HighLevel/PipeStream.h index 5d95197ec..a327a89c1 100644 --- a/LUFA/Drivers/USB/HighLevel/PipeStream.h +++ b/LUFA/Drivers/USB/HighLevel/PipeStream.h @@ -57,10 +57,6 @@ #include "../../../Common/Common.h"
#include "USBTask.h"
-
- #if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
- #include "StreamCallbacks.h"
- #endif
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
@@ -71,12 +67,6 @@ #if !defined(__INCLUDE_FROM_USB_DRIVER)
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
#endif
-
- #if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
- #define __CALLBACK_PARAM , StreamCallbackPtr_t Callback
- #else
- #define __CALLBACK_PARAM
- #endif
/* Public Interface - May be used in end-application: */
/* Enums: */
@@ -92,200 +82,377 @@ * within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
- PIPE_RWSTREAM_CallbackAborted = 4, /**< Indicates that the stream's callback function aborted
- * the transfer early.
+ PIPE_RWSTREAM_IncompleteTransfer = 4, /**< Indicates that the pipe bank became full/empty before the
+ * complete contents of the stream could be transferred.
*/
};
/* Function Prototypes: */
+
+ /** \name Stream functions for null data */
+ //@{
+
/** 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 device via the \ref 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 according to the information in \ref Group_StreamCallbacks.
- * 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.
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or
+ * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer
+ * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data
+ * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with
+ * the total number of bytes processed in the stream, and the function will exit with an error code of
+ * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to
+ * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed
+ * value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ *
+ * \param[in] Length Number of bytes to discard via the currently selected pipe.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be processed at once.
*
- * The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
- * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
- *
- * \param[in] Length Number of bytes to send via the currently selected pipe.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Pipe_Discard_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed);
+
+ /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device
+ * as needed. The last packet is not automatically sent once the remaining bytes has been written; the
+ * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro.
+ *
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or
+ * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer
+ * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data
+ * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be
+ * updated with the total number of bytes processed in the stream, and the function will exit with an error code of
+ * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to
+ * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed
+ * value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ *
+ * \param[in] Length Number of zero bytes to write via the currently selected pipe.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be processed at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Discard_Stream(uint16_t Length
- __CALLBACK_PARAM);
+ uint8_t Pipe_Null_Stream(uint16_t Length,
+ uint16_t* const BytesProcessed);
+
+ //@}
+ /** \name Stream functions for RAM source/destination data */
+ //@{
+
/** 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
* \ref 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 according to the information in \ref Group_StreamCallbacks.
- * 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.
- *
- * The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
- * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the pipe bank becomes full while there is still data to process (and after the current
+ * packet transmission has been initiated) the BytesProcessed location will be updated with the
+ * total number of bytes processed in the stream, and the function will exit with an error code of
+ * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream),
+ * NULL)) != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream),
+ * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ *
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Pipe_Write_Stream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of \ref Pipe_Write_Stream_LE().
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
- *
- * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Pipe_Write_EStream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** FLASH buffer source version of \ref Pipe_Write_Stream_LE().
- *
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
- *
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
- *
- * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
- */
- uint8_t Pipe_Write_PStream_LE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
/** 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
* \ref 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 according to the information in \ref Group_StreamCallbacks.
- * 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.
- *
- * The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
- * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Pipe_Write_Stream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of \ref Pipe_Write_Stream_BE().
+ /** 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
+ * \ref 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.
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once,
+ * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid
+ * storage location, the transfer will instead be performed as a series of chunks. Each time
+ * the pipe bank becomes empty while there is still data to process (and after the current
+ * packet has been acknowledged) the BytesProcessed location will be updated with the total number
+ * of bytes processed in the stream, and the function will exit with an error code of
+ * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed
+ * in the user code - to continue the transfer, call the function again with identical parameters
+ * and it will resume until the BytesProcessed value reaches the total transfer length.
+ *
+ * <b>Single Stream Transfer Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ *
+ * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream),
+ * NULL)) != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * <b>Partial Stream Transfers Example:</b>
+ * \code
+ * uint8_t DataStream[512];
+ * uint8_t ErrorCode;
+ * uint16_t BytesProcessed;
+ *
+ * BytesProcessed = 0;
+ * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream),
+ * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer)
+ * {
+ * // Stream not yet complete - do other actions here, abort if required
+ * }
+ *
+ * if (ErrorCode != PIPE_RWSTREAM_NoError)
+ * {
+ * // Stream failed to complete - check ErrorCode here
+ * }
+ * \endcode
+ *
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ *
+ * \param[out] Buffer Pointer to the source data buffer to write to.
+ * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Write_EStream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** FLASH buffer source version of \ref Pipe_Write_Stream_BE().
+ uint8_t Pipe_Read_Stream_LE(void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** 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
+ * \ref 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.
*
- * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
+ * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
+ * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
*
- * \param[in] Buffer Pointer to the source data buffer to read from.
- * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[out] Buffer Pointer to the source data buffer to write to.
+ * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Write_PStream_BE(const void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Pipe_Read_Stream_BE(void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
- /** 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
- * \ref 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.
+ /** \name Stream functions for EEPROM source/destination data */
+ //@{
+
+ /** EEPROM buffer source version of \ref Pipe_Write_Stream_LE().
*
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * 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.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
- * The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
- * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Pipe_Write_EStream_LE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of \ref Pipe_Write_Stream_BE().
*
- * \param[out] Buffer Pointer to the source data buffer to write to.
- * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Read_Stream_LE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Pipe_Write_EStream_BE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
/** EEPROM buffer source version of \ref Pipe_Read_Stream_LE().
*
- * \param[out] Buffer Pointer to the source data buffer to write to.
- * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[out] Buffer Pointer to the source data buffer to write to.
+ * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be read at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
uint8_t Pipe_Read_EStream_LE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
-
- /** 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
- * \ref 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.
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** EEPROM buffer source version of \ref Pipe_Read_Stream_BE().
*
- * The callback routine should be created according to the information in \ref Group_StreamCallbacks.
- * 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.
+ * \param[out] Buffer Pointer to the source data buffer to write to.
+ * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be read at once.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t Pipe_Read_EStream_BE(void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
+
+ /** \name Stream functions for PROGMEM source/destination data */
+ //@{
+
+ /** FLASH buffer source version of \ref Pipe_Write_Stream_LE().
*
- * The pipe token is set automatically, thus this can be used on bi-directional pipes directly without
- * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken().
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
*
- * \param[out] Buffer Pointer to the source data buffer to write to.
- * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Read_Stream_BE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Pipe_Write_PStream_LE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
- /** EEPROM buffer source version of \ref Pipe_Read_Stream_BE().
+ /** FLASH buffer source version of \ref Pipe_Write_Stream_BE().
+ *
+ * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
*
- * \param[out] Buffer Pointer to the source data buffer to write to.
- * \param[in] Length Number of bytes to read for the currently selected pipe to read from.
- * \param[in] Callback Name of a callback routine to call between successive USB packet transfers, NULL if no callback.
+ * \param[in] Buffer Pointer to the source data buffer to read from.
+ * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer.
+ * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should
+ * updated, \c NULL if the entire stream should be written at once.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
- uint8_t Pipe_Read_EStream_BE(void* Buffer,
- uint16_t Length
- __CALLBACK_PARAM) ATTR_NON_NULL_PTR_ARG(1);
+ uint8_t Pipe_Write_PStream_BE(const void* Buffer,
+ uint16_t Length,
+ uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1);
+ //@}
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h b/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h deleted file mode 100644 index 6ff8a35a0..000000000 --- a/LUFA/Drivers/USB/HighLevel/StreamCallbacks.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2011. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * \brief USB endpoint/pipe stream callback management. - * - * This file contains definitions for the creation of optional callback routines which can be passed to the - * endpoint and/or pipe stream APIs, to abort the transfer currently in progress when a condition is met. - * - * \note This file should not be included directly. It is automatically included as needed by the USB driver - * dispatch header located in LUFA/Drivers/USB/USB.h. - */ - -/** \ingroup Group_USB - * @defgroup Group_StreamCallbacks Endpoint and Pipe Stream Callbacks - * - * Macros and enums for the stream callback routines. This module contains the code required to easily set up - * stream callback functions which can be used to force early abort of a stream read/write process. Each callback - * should take no arguments, and return a value from the \ref StreamCallback_Return_ErrorCodes_t enum. - * - * @{ - */ - -#ifndef __STREAMCALLBACK_H__ -#define __STREAMCALLBACK_H__ - - /* Includes: */ - #include <stdint.h> - - /* Preprocessor Checks: */ - #if !defined(__INCLUDE_FROM_USB_DRIVER) - #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** Used with the Endpoint and Pipe stream functions as the callback function parameter, indicating that the stream - * call has no callback function to be called between USB packets. - */ - #define NO_STREAM_CALLBACK NULL - - /* Enums: */ - /** Enum for the possible error return codes of a stream callback function. */ - enum StreamCallback_Return_ErrorCodes_t - { - STREAMCALLBACK_Continue = 0, /**< Continue sending or receiving the stream. */ - STREAMCALLBACK_Abort = 1, /**< Abort the stream send or receiving process. */ - }; - - /* Type Defines: */ - /** Type define for a Stream Callback function (function taking no arguments and retuning a - * uint8_t value). Stream callback functions should have an identical function signature if they - * are to be used as the callback parameter of the stream functions. - */ - typedef uint8_t (* const StreamCallbackPtr_t)(void); - -#endif - -/** @} */ - diff --git a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_R.c index 5cc11d7fe..cd11705c2 100644 --- a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_R.c +++ b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_R.c @@ -22,6 +22,7 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, while (Length && Endpoint_BytesInEndpoint()) { TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); Length--; } @@ -44,5 +45,6 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, #undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE #undef TEMPLATE_FUNC_NAME #undef TEMPLATE_TRANSFER_BYTE diff --git a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_W.c index 16fe3999b..43724e805 100644 --- a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_W.c +++ b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_Control_W.c @@ -29,6 +29,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* Buffer, while (Length && (BytesInEndpoint < USB_ControlEndpointSize)) { TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); Length--; BytesInEndpoint++; } @@ -52,5 +53,6 @@ uint8_t TEMPLATE_FUNC_NAME (const void* Buffer, } #undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE #undef TEMPLATE_FUNC_NAME #undef TEMPLATE_TRANSFER_BYTE diff --git a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_RW.c b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_RW.c index 8a97e1565..8a68d65e2 100644 --- a/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_RW.c +++ b/LUFA/Drivers/USB/HighLevel/Template/Template_Endpoint_RW.c @@ -1,23 +1,31 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, - uint16_t Length - __CALLBACK_PARAM) + uint16_t Length, + uint16_t* const BytesProcessed) { - uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; uint8_t ErrorCode; if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + while (Length) { if (!(Endpoint_IsReadWriteAllowed())) { TEMPLATE_CLEAR_ENDPOINT(); - #if !defined(NO_STREAM_CALLBACKS) - if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) - return ENDPOINT_RWSTREAM_CallbackAborted; - #endif + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } if ((ErrorCode = Endpoint_WaitUntilReady())) return ErrorCode; @@ -25,7 +33,9 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, else { TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); Length--; + BytesInTransfer++; } } @@ -37,3 +47,4 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, #undef TEMPLATE_TRANSFER_BYTE #undef TEMPLATE_CLEAR_ENDPOINT #undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE diff --git a/LUFA/Drivers/USB/HighLevel/Template/Template_Pipe_RW.c b/LUFA/Drivers/USB/HighLevel/Template/Template_Pipe_RW.c index eebe52f12..8c5d47d4d 100644 --- a/LUFA/Drivers/USB/HighLevel/Template/Template_Pipe_RW.c +++ b/LUFA/Drivers/USB/HighLevel/Template/Template_Pipe_RW.c @@ -1,8 +1,9 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, - uint16_t Length - __CALLBACK_PARAM) + uint16_t Length, + uint16_t* const BytesProcessed) { - uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; uint8_t ErrorCode; Pipe_SetPipeToken(TEMPLATE_TOKEN); @@ -10,16 +11,23 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + while (Length) { if (!(Pipe_IsReadWriteAllowed())) { TEMPLATE_CLEAR_PIPE(); - #if !defined(NO_STREAM_CALLBACKS) - if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) - return PIPE_RWSTREAM_CallbackAborted; - #endif + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; @@ -27,7 +35,9 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, else { TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); Length--; + BytesInTransfer++; } } @@ -40,4 +50,4 @@ uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer, #undef TEMPLATE_TRANSFER_BYTE #undef TEMPLATE_CLEAR_PIPE #undef TEMPLATE_BUFFER_OFFSET - +#undef TEMPLATE_BUFFER_MOVE |