| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- // -----------------------------------------------------------------------------
- // USB Library "usblib"
- // Author: Sychov A.
- // Date: 29/07/2019
- // Version: 1.1
- // -----------------------------------------------------------------------------
- // File: Thread-unsafe internal buffer-object 'USB-transfer' header
- // Version: 1.1
- // ------------------------------------------------------------------------------
- #ifndef USB_LOGICAL_TRANSFER_H
- #define USB_LOGICAL_TRANSFER_H
- #include <stddef.h>
- #include <stdint.h>
- #include <stdbool.h>
-
- // USB_TRANSFER_MOVE_SEMANTIC
- // Enables a move semantic on the transfers.
- // When enabled, some functions will perfrom additional checking of a transfer parameters.
- #define USB_TRANSFER_MOVE_SEMANTIC 1
- // USB_TRANSFER_SUPPORT_FLAGS
- // Implements user-defined flags support for each transfer
- #define USB_TRANSFER_SUPPORT_FLAGS 1
- // USB_TRANSFER_SUPPORT_EOTH
- // Implements the End-of-transfer-handler support
- #define USB_TRANSFER_SUPPORT_EOTH 0
- struct sUSBTransfer_t;
- // USB Transfers
- // Software module implements the logical data unit with separated
- // read- and write- methods based on linear buffer.
-
- // fEndOfTransferHandler_t
- // End-of-thansfer handler, is called when data in the transfer running out
- // @transf - the transfer generated the the handler call
- // @ctx - user defined context, the context specified at usb_create_pipe()
- // The handler is only called when usb_read_pipe() is performed.
- // The value returned by the handler must be amount of bytes loaded into the transfer
- typedef size_t ( * fEndOfTransferHandler_t)( struct sUSBTransfer_t * transf, void * ctx );
- // @tUSBTransferFlag_t
- // User-dependent general-purpose bit flags
- typedef uint32_t tUSBTransferFlags_t;
- // @tUSBTransferFlagMask_t
- // User-dependent lock-mask for general-purpose bit flags
- typedef uint32_t tUSBTransferFlagMask_t;
- // @eUSBTransferFlagMode_t
- // Flags checking mode for @usb_transfer_check_flags()
- typedef enum {
- eUSBTransferFlagMode_Or, // OR-operation with mask
- eUSBTransferFlagMode_And, // AND-operation with mask
- }
- eUSBTransferFlagMode_t;
- // Usb Data Transfer Descriptor
- struct sUSBTransfer_t
- {
- size_t size; // maximum buffer capacity
-
- uint8_t * pDefaultBuffer; // Main data buffer
- uint8_t * pWriteData; // current Write-data pointer
- uint8_t * pReadData; // current Read-data pointer
- #if USB_TRANSFER_SUPPORT_EOTH
- // End-of-transfer handler: processes the event when the last byte of pipe transferred
- fEndOfTransferHandler_t fEndOfTransferHandler;
- #endif
- #if USB_TRANSFER_SUPPORT_FLAGS
- tUSBTransferFlags_t flags;
- tUSBTransferFlagMask_t flagsLock;
- #endif
- void * ctx; // used-defined context
- };
- typedef struct sUSBTransfer_t sUSBTransfer_t;
-
- // USB Logical Pipe Descriptor
- typedef struct
- {
- sUSBTransfer_t TxTransfer; // IN: Device->Host pipe
- sUSBTransfer_t RxTransfer; // OUT: Host->Device pipe
- }
- sUSBEpChannel_t;
- // usb_reset_transfer()
- // Non thread-safe!
- // Resets the specified transfer.
- // Note: the specified end-of-transfer handler isn't called.
- void usb_reset_transfer( sUSBTransfer_t * pUsbTransfer );
- // usb_reset_channel()
- // Non thread-safe!
- // Resets either RX and TX transfers in the channel
- void usb_reset_channel( sUSBEpChannel_t * ch );
- // usb_reset_channel_tx()
- // Non thread-safe!
- // Resets the TX-transfer in the channel
- void usb_reset_channel_tx( sUSBEpChannel_t * ch );
-
- // usb_reset_channel_rx()
- // Non thread-safe!
- // Resets the RX-transfer in the channel
- void usb_reset_channel_rx( sUSBEpChannel_t * ch );
- #if USB_TRANSFER_SUPPORT_EOTH
- // usb_create_channel()
- // Creates a bidirectional linear-buffered logical-channel
- // @ch - the channel to construct
- // @pTxBuffer and @txSize - buffer and size of the buffer to Tx operations
- // @pRxBuffer and @rxSize - buffer and size of the buffer to Rx operations
- // @eotTxHandler - the event handler, is called when data run out in Tx Buffer
- // @eotRxHandler - the event handler, is called when data run out in Rx Buffer
- // @chContext - user defined context, will be passed into @eotTxHandler and @eotRxHandler
- // Returns true in case the channel is successfully created
- bool usb_create_channel( sUSBEpChannel_t * ch,
- void * pTxBuffer, size_t txSize,
- void * pRxBuffer, size_t rxSize,
- fEndOfTransferHandler_t eotTxHandler,
- fEndOfTransferHandler_t eotRxHandler,
- void * channelContext );
- #else
- bool usb_create_channel( sUSBEpChannel_t * ch,
- void * pTxBuffer, size_t txSize,
- void * pRxBuffer, size_t rxSize,
- const void * reserved1,
- const void * reserved2,
- void * channelContext );
- #endif
- // usb_create_transfer()
- // Creates a signle linear-buffered transfer
- // @transf - the transfer to construct
- // @pBuffer and @size - buffer and size of the buffer for transfer operations
- // @eotHandler - the event handler, is called when data run out in the buffer
- // @chContext - user defined context, will be passed into @eotHandler
- // Returns true in case the channel is successfully created
- #if USB_TRANSFER_SUPPORT_EOTH
- bool usb_create_transfer( sUSBTransfer_t * ch,
- void * pBuffer, size_t size,
- fEndOfTransferHandler_t eotHandler,
- void * channelContext );
- #else
- bool usb_create_transfer( sUSBTransfer_t * ch,
- void * pBuffer, size_t size,
- const void * reserved,
- void * channelContext );
- #endif
- // usb_push_transfer()
- // Non thread-safe!
- // Writes data into the transfer.
- // @transf - specifies the transfer to operate with
- // @pWriteBuffer - data to be written
- // @pushSize - amount of bytes to write
- // Returns the @pushSize in case all the data has been written into the transfer
- // Otherwise, returns 0. In this case no write operation has been performed.
- // Note: the write operation can be split up to several write operations,
- // until the buffer is full.
- // To prepare the transfer for next portion of data, use usb_reset_transfer()
- size_t usb_push_transfer( sUSBTransfer_t * transf, const void * pWriteBuffer, size_t pushSize );
- // usb_write_transfer()
- // Non thread-safe!
- // Writes data into the transfer.
- // @transf - specifies the transfer to operate with
- // @pWriteBuffer - data to be written
- // @writeSize - amount of bytes to write
- // Returns amount of bytes written into the transfer
- // In this case no write operation has been performed the function returns 0.
- // Note: the write operation can be split up to several write operations,
- // until the buffer is full.
- // To prepare the transfer for next portion of data, use usb_reset_transfer()
- size_t usb_write_transfer( sUSBTransfer_t * transf, const void * pWriteBuffer, size_t writeSize );
- // usb_read_transfer()
- // Non thread-safe!
- // Reads the data from the transfer.
- // @transf - specifies the transfer to operate with
- // @pReadBuffer - the buffer to receive data, can be NULL
- // @readSize - amount of data to copy into the @pReadBuffer, can be 0.
- // @enableEotHandler - enables/disables calling of End-Of-Transfer handler
- // during the call if the transfer is empty.
- // In case, @readSize is equal or greater than amount of data in the transfer,
- // the function reads actual amount of data and returns count of read bytes.
- // Since all data is read from the transfer, the transfer is being reset
- // automatically. If the End-of-transfer handler is specified for this transfer,
- // it will be invoked after the transfer is reset only if @enableEotHandler is
- // true, so the handler can write the next portion of data into the transfer.
- // Otherwise, if @readSize is less than amount of data in the transfer, then
- // only @readSize bytes will be copyied into @pReadBuffer, the rest data are
- // still stored in the transfer-buffer and should be either read by next call,
- // or reset by calling usb_reset_transfer().
- // Note: if the data in transfer is reset by calling usb_reset_transfer(), the
- // End-of-pipe handler is not called.
- // You can call the function with @pReadBuffer = NULL and @readSize = 0, and
- // @enableEotHandler = true to check if the transfer empty and call the End-of-
- // -transfer handler. In this case the function always returns zero.
- // Note: if you specify @pReadBuffer = NULL, you must set @readSize = 0.
- // To determine amount of bytes in the transfer use usb_count_transfer().
- //
- size_t usb_read_transfer( sUSBTransfer_t * transf, void * pReadBuffer, size_t readSize, bool enableEotHandler );
- // usb_count_transfer():
- // Non thread-safe!
- // Returns amount of data in the transfer.
- // @transf - the transfer to operate with, Non-NULL
- // Returns amount of data to be read.
- size_t usb_count_transfer( sUSBTransfer_t * transf );
- // usb_truncate_transfer()
- //
- // Non thread-safe!
- //
- // Truncates the data into the transfer.
- // @transf - the transfer to operate with, Non-NULL
- // @size - the size limit to apply
- // The function truncates the data in the transfer to the specified @size
- // Returns amount of data truncated.
- size_t usb_truncate_transfer( sUSBTransfer_t * transf, size_t size );
- #if USB_TRANSFER_SUPPORT_EOTH
- // usb_transfer_override_handler:
- // Replaces the End-of-transfer handler for the specified transfer @transf
- // @transf - the transfer to operate with
- // @handler - new end-of-transfer handler
- // If succeeded, the previous handler pointer is returned by function, and NULL otherwise.
- fEndOfTransferHandler_t usb_transfer_override_handler( sUSBTransfer_t * transf, fEndOfTransferHandler_t handler );
- #endif
- // usb_transfer_overridelength()
- //
- // Non thread-safe!
- //
- // Overrides the transfer data length.
- // @transf - the transfer to operate with, Non-NULL
- // @length - new length
- // The function overrides the original transfer data length with the specified @length
- // Returns new length value.
- size_t usb_transfer_overridelength( sUSBTransfer_t * transf, size_t length );
- // usb_transfer_virtual_read()
- //
- // Non thread-safe!
- //
- // Performs virtual reading from transfer without actual data retrieving from.
- // @transf - the transfer to operate with, Non-NULL
- // @length - the number of bytes for virtual reading
- // The function changes the transfer data length.
- // Returns the number of read bytes
- size_t usb_transfer_virtual_read( sUSBTransfer_t * transf, size_t length );
- // usb_transfer_virtual_write()
- //
- // Non thread-safe!
- //
- // Performs virtual writing to transfer without actual data placing in.
- // @transf - the transfer to operate with, Non-NULL
- // @length - the number of bytes for virtual writing
- // The function changes the transfer data length.
- // Returns the number of written bytes
- size_t usb_transfer_virtual_write( sUSBTransfer_t * transf, size_t length );
- // usb_transfer_compress()
- //
- // Non thread-safe!
- //
- // Optimizes the transfer by size by packing data inside.
- // @transf - the transfer to operate with, Non-NULL
- // The function moves the data from middle of the transfer to the beginning
- // with keeping actual size.
- // Returns new length value.
- size_t usb_transfer_compress( sUSBTransfer_t * transf );
- // usb_size_transfer()
- //
- // Non thread-safe!
- //
- // Returns the transfer absoulte size.
- // @transf - the transfer to operate with, Non-NULL
- // Returns the size in bytes
- size_t usb_size_transfer( sUSBTransfer_t * transf );
- // usb_space_transfer()
- //
- // Non thread-safe!
- //
- // Returns the transfer available space.
- // @transf - the transfer to operate with, Non-NULL
- // Returns amount of free space in the transfer in bytes.
- size_t usb_space_transfer( sUSBTransfer_t * transf );
- // usb_transfer_raw_write()
- // Returns raw write-pointer to the transfer storage.
- // # Ponetially dangerous function, use usb_space_transfer() before.
- static inline void * usb_transfer_raw_write( sUSBTransfer_t * transf )
- {
- return transf->pWriteData;
- }
- // usb_transfer_raw_read()
- // Returns raw read-pointer to the transfer storage.
- // # Ponetially dangerous function, use usb_count_transfer() before.
- static inline void * usb_transfer_raw_read( sUSBTransfer_t * transf )
- {
- return transf->pReadData;
- }
- #if USB_TRANSFER_MOVE_SEMANTIC
- // usb_move_transfer()
- //
- // Non thread-safe!
- //
- // Implements a move-semantic on couple of transfer objects
- // @transf_to - the transfer for move to, can not be NULL
- // @transf_from - the transfer for move from, can not be NULL
- // @copyContextValue - copy the context value assotiated with the source tranfer.
- // Returns the operation result, true if object had been moved
- // successfully, and false otherwise.
- // The source object (@transf_from) must be valid, while it does
- // not matter if the destination object @transf_to is invalid or not.
- bool usb_move_transfer( sUSBTransfer_t * transf_to, sUSBTransfer_t * transf_from, bool copyContextValue );
- #endif
- // usb_validate_transfer()
- //
- // Non thread-safe!
- //
- // Validates the transfer parameters. Usefull for checking objects
- // after moving by usb_move_transfer().
- // @transf - the transfer to operate with, Non-NULL
- // Returns true if the specified object is valid, false otherwise.
- bool usb_validate_transfer( sUSBTransfer_t * transf );
- // usb_transfer_get_context
- //
- // Non thread-safe!
- //
- // Retrieves optional user context value.
- // @transf - the transfer to operate with, Non-NULL
- // @pCtxStore - the pointer to the variable the function will store
- // the context value to, must not be NULL
- //
- // Returns the context value assotiated with the @transf
- // In case of success returns 'true', and returns 'false' otherwise.
- static inline bool usb_transfer_get_context( sUSBTransfer_t * transf, void ** pCtxStore )
- {
- if( NULL != transf && NULL != pCtxStore )
- {
- *pCtxStore = transf->ctx;
- return true;
- }
- return false;
- }
- // usb_transfer_set_context
- //
- // Non thread-safe!
- //
- // Assotiate optional user context value with the transfer.
- // @transf - the transfer to operate with, Non-NULL
- // @pCtx - user-dependent context value to be assotiated with the transfer, can be NULL
- //
- // Returns the context value assotiated with the @transf
- // In case of success returns 'true', and returns 'false' otherwise.
- static inline bool usb_transfer_set_context( sUSBTransfer_t * transf, void * pCtx )
- {
- if( NULL != transf )
- {
- transf->ctx = pCtx;
- return true;
- }
- return false;
- }
- // usb_copy_transfer()
- // Copies the data from one transfer to another
- // The source transfer is not being modified if @keepSource is true.
- // Otherwise, if @keepSource is false, the source transfer will be changed,
- // and the data copied to destination transfer will be removed from the source transfer.
- // @count - specifies amount of data to be copied.
- // If the source transfer contains less bytes that specified in @count, or the
- // destination transfer does not have enough free space, only the minimum between
- // these number of bytes will be copied.
- // Returns: number of copied bytes
- size_t usb_copy_transfer( sUSBTransfer_t * transf_to, sUSBTransfer_t * transf_from, size_t count, bool keepSource );
- #if USB_TRANSFER_SUPPORT_FLAGS
- // @usb_transfer_check_flags
- // Check if the user-dependent general-purpose flags fit to the specified mask @mask and value @value using comparing method @mode.
- // @transf - the transfer object to operate with;
- // @mask - specified mask to check
- // @value - specified value to check
- // @mode - comparing method:
- // - eUSBTransferFlagMode_Or: at least one transfer bit-flag must be equal to the specified value;
- // - eUSBTransferFlagMode_And: all the transfer bit-flag must be equal to the specified value;
- // @pResult = the pointer to receive output result
- // Returns: true if no error occurred, false otherwise.
- bool usb_transfer_check_flags( sUSBTransfer_t * transf, tUSBTransferFlags_t mask, tUSBTransferFlags_t value, eUSBTransferFlagMode_t mode, bool * pResult );
-
- // @usb_transfer_check_flags_fast
- // Check if the user-dependent general-purpose flags fit to the specified mask @mask and value @value using comparing method @mode.
- // @transf - the transfer object to operate with;
- // @mask - specified mask to check
- // @value - specified value to check
- // @mode - comparing method:
- // - eUSBTransferFlagMode_Or: at least one transfer bit-flag must be equal to the specified value;
- // - eUSBTransferFlagMode_And: all the transfer bit-flag must be equal to the specified value;
- // Returns: true if no error occurred and the comparing output is TRUE, false otherwise.
- // Note: you can use this function instead of @usb_transfer_check_flags if you are sure that the @transf pointer is valid.
- bool usb_transfer_check_flags_fast( sUSBTransfer_t * transf, tUSBTransferFlags_t mask, tUSBTransferFlags_t value, eUSBTransferFlagMode_t mode );
-
- // @usb_transfer_modify_flags
- // Modifies the user-dependent general-purpose flags using specified mask @mask and value @value
- // Returns: true if no error occurred, false otherwise.
- bool usb_transfer_modify_flags( sUSBTransfer_t * transf, tUSBTransferFlags_t mask, tUSBTransferFlags_t value );
- // @usb_transfer_modify_flags_locks
- // Modifies the lock mask for user-dependent general-purpose flags using specified mask @mask and value @value
- // Returns: true if no error occurred, false otherwise.
- bool usb_transfer_modify_flags_locks( sUSBTransfer_t * transf, tUSBTransferFlags_t lockMask, tUSBTransferFlags_t lockValue );
- #endif
- #endif
|