Example #1
0
//*****************************************************************************
//
// Handles USB_EVENT_TX_COMPLETE for a transmit buffer.
//
// \param psBuffer points to the buffer which is receiving the event.
// \param ulSize is the number of bytes that have been transmitted and
// acknowledged.
//
// This function informs us that data written to the lower layer from a
// transmit buffer has been successfully transmitted.  We use this to update
// the buffer read pointer and attempt to schedule the next transmission if
// data remains in the buffer.
//
// \return Returns the number of bytes remaining to be processed.
//
//*****************************************************************************
static unsigned long
HandleTxComplete(tUSBBuffer *psBuffer, unsigned long ulSize)
{
    tUSBBufferVars *psVars;

    //
    // Get a pointer to our workspace variables.
    //
    psVars = psBuffer->pvWorkspace;

    //
    // Update the transmit buffer read pointer to remove the data that has
    // now been transmitted.
    //
    USBRingBufAdvanceRead(&psVars->sRingBuf, ulSize);

    //
    // Try to schedule the next packet transmission if data remains to be
    // sent.
    //
    ScheduleNextTransmission(psBuffer);

    //
    // The return code from this event is ignored.
    //
    return(0);
}
Example #2
0
//*****************************************************************************
//
// Handles USB_EVENT_TX_COMPLETE for a transmit buffer.
//
// \param psBuffer points to the buffer which is receiving the event.
// \param ui32Size is the number of bytes that have been transmitted and
// acknowledged.
//
// This function informs us that data written to the lower layer from a
// transmit buffer has been successfully transmitted.  We use this to update
// the buffer read pointer and attempt to schedule the next transmission if
// data remains in the buffer.
//
// \return Returns the number of bytes remaining to be processed.
//
//*****************************************************************************
static uint32_t
HandleTxComplete(tUSBBuffer *psBuffer, uint32_t ui32Size)
{
    //
    // Update the transmit buffer read pointer to remove the data that has
    // now been transmitted.
    //
    USBRingBufAdvanceRead(&psBuffer->sPrivateData.sRingBuf, ui32Size);

    //
    // Try to schedule the next packet transmission if data remains to be
    // sent.
    //
    ScheduleNextTransmission(psBuffer);

    //
    // The return code from this event is ignored.
    //
    return(0);
}
Example #3
0
//*****************************************************************************
//
//! Indicates that a client has read data directly out of the buffer.
//!
//! \param psBuffer is the pointer to the buffer instance from which data has
//! been read.
//! \param ui32Length is the number of bytes of data that the client has read.
//!
//! This function updates the USB buffer read pointer to remove data that
//! the client has read directly rather than via a call to USBBufferRead().
//! The function is provided to aid a client wishing to minimize data copying.
//! To read directly from the buffer, a client must call USBBufferInfoGet() to
//! retrieve the current buffer inpsBufVarsdices.  With this information, the
//! data following the current read index can be read.  Once the client has
//! processed much data as it needs, USBBufferDataRemoved() must be called to
//! advance the read pointer past the data that has been read and free up that
//! section of the buffer.  The client must take care to correctly handle the
//! wrap point if accessing the buffer directly.
//!
//! \return None.
//
//*****************************************************************************
void
USBBufferDataRemoved(const tUSBBuffer *psBuffer, uint32_t ui32Length)
{
    tUSBBufferVars *psPrivate;

    //
    // Check parameter validity.
    //
    ASSERT(psBuffer);

    //
    // Create a writable pointer to the private data.
    //
    psPrivate = &((tUSBBuffer *)psBuffer)->sPrivateData;

    //
    // Advance the ring buffer write pointer to include the newly written
    // data.
    //
    if(ui32Length) {
        USBRingBufAdvanceRead(&psPrivate->sRingBuf, ui32Length);
    }
}
Example #4
0
//*****************************************************************************
//
//! Indicates that a client has read data directly out of the buffer.
//!
//! \param psBuffer is the pointer to the buffer instance from which data has
//! been read.
//! \param ulLength is the number of bytes of data that the client has read.
//!
//! This function updates the USB buffer read pointer to remove data that
//! the client has read directly rather than via a call to USBBufferRead().
//! The function is provided to aid a client wishing to minimize data copying.
//! To read directly from the buffer, a client must call USBBufferInfoGet() to
//! retrieve the current buffer indices.  With this information, the data
//! following the current read index can be read.  Once the client has
//! processed much data as it needs, USBBufferDataRemoved() must be called to
//! advance the read pointer past the data that has been read and free up that
//! section of the buffer.  The client must take care to correctly handle the
//! wrap point if accessing the buffer directly.
//!
//! \return None.
//
//*****************************************************************************
void
USBBufferDataRemoved(const tUSBBuffer *psBuffer, unsigned long ulLength)
{
    tUSBBufferVars *psVars;

    //
    // Check parameter validity.
    //
    ASSERT(psBuffer);

    //
    // Get our workspace variables.
    //
    psVars = psBuffer->pvWorkspace;

    //
    // Advance the ring buffer write pointer to include the newly written
    // data.
    //
    if(ulLength)
    {
        USBRingBufAdvanceRead(&psVars->sRingBuf, ulLength);
    }
}
Example #5
0
//*****************************************************************************
//
// Handles USB_EVENT_RX_AVAILABLE for a receive buffer.
//
// \param psBuffer points to the buffer which is receiving the event.
// \param ulSize is the size reported in the event.
// \param pucData is the pointer provided in the event.
//
// This function is responsible for reading data from the lower layer into
// the buffer or, if we had previously passed a section of the buffer to the
// lower layer for it to write into directly, updating the buffer write pointer
// to add the new data to the buffer.
//
// If the pointer provided is NULL, we call the low level pfnTransfer function
// to get the new data.  If the pointer is not NULL and not within the existing
// ring buffer, we copy the data directly from the pointer to the buffer and
// return the number of bytes read.
//
// \return Returns the number of bytes read from the lower layer.
//
//*****************************************************************************
static unsigned long
HandleRxAvailable(tUSBBuffer *psBuffer, unsigned long ulSize,
                  unsigned char *pucData)
{
    tUSBBufferVars *psVars;
    unsigned long ulAvail, ulRead, ulPacket, ulRetCount;

    //
    // Get a pointer to our workspace variables.
    //
    psVars = psBuffer->pvWorkspace;

    //
    // Has the data already been read into memory?
    //
    if(pucData)
    {
        //
        // Yes - is it already in our ring buffer?
        //
        if((pucData >= psBuffer->pcBuffer) &&
           (pucData < psBuffer->pcBuffer + psBuffer->ulBufferSize))
        {
            //
            // The data is already in our ring buffer so merely update the
            // write pointer to add the new data.
            //
            USBRingBufAdvanceWrite(&psVars->sRingBuf, ulSize);

            //
            // In this case, we pass back 0 to indicate that the lower layer
            // doesn't need to make any buffer pointer updates.
            //
            ulRetCount = 0;
        }
        else
        {
            //
            // The data is not within our buffer so we need to copy it into
            // the buffer.
            //
            // How much space does the buffer have available?
            //
            ulAvail = USBRingBufFree(&psVars->sRingBuf);

            //
            // How much should we copy?
            //
            ulRead = (ulAvail < ulSize) ? ulAvail : ulSize;

            //
            // Copy the data into the buffer.
            //
            USBRingBufWrite(&psVars->sRingBuf, pucData, ulRead);

            //
            // We need to return the number of bytes we read in this case
            // since the buffer supplied to us was owned by the lower layer and
            // it may need to update its read pointer.
            //
            ulRetCount = ulRead;
        }
    }
    else
    {
        //
        // We were passed a NULL pointer so the low level driver has not read
        // the data into memory yet.  We need to call the transfer function to
        // get the packet.
        //
        // How big is the packet that we need to receive?
        //
        ulPacket = psBuffer->pfnAvailable(psBuffer->pvHandle);

        //
        // How much contiguous space do we have in the buffer?
        //
        ulAvail = USBRingBufContigFree(&psVars->sRingBuf);

        //
        // Get as much of the packet as we can in the available space.
        //
        ulRead = psBuffer->pfnTransfer(psBuffer->pvHandle,
                                       (psVars->sRingBuf.pucBuf +
                                        psVars->sRingBuf.ulWriteIndex),
                                       ulAvail, true);

        //
        // Advance the ring buffer write pointer to add our new data.
        //
        if(ulRead)
        {
            USBRingBufAdvanceWrite(&psVars->sRingBuf, ulRead);
        }

        //
        // Did we get the whole packet?
        //
        if(ulRead < ulPacket)
        {
            //
            // No - how much space do we have in the buffer?
            //
            ulAvail = USBRingBufContigFree(&psVars->sRingBuf);

            //
            // If there is any space left, read as much of the remainder of
            // the packet as we can.
            //
            if(ulAvail)
            {
                ulPacket =
                    psBuffer->pfnTransfer(psBuffer->pvHandle,
                                          (psVars->sRingBuf.pucBuf +
                                           psVars->sRingBuf.ulWriteIndex),
                                          ulAvail, true);

                //
                // Update the write pointer after we read more data into the
                // buffer.
                //
                if(ulPacket)
                {
                    USBRingBufAdvanceWrite(&psVars->sRingBuf, ulPacket);
                }
            }
        }

        //
        // We need to return 0 in this case to indicate that the lower layer
        // need not perform any buffer maintenance as a result of the callback.
        //
        ulRetCount = 0;
    }

    //
    // How much data do we have in the buffer?
    //
    ulAvail = USBRingBufUsed(&psVars->sRingBuf);

    //
    // Pass the event on to the client with the current read pointer and
    // available data size.  The client is expected to understand the ring
    // structure and be able to deal with wrap if it wants to read the data
    // directly from the buffer.
    //
    ulRead = psBuffer->pfnCallback(psBuffer->pvCBData,
                                   USB_EVENT_RX_AVAILABLE,
                                   ulAvail,
                                   (psVars->sRingBuf.pucBuf +
                                    psVars->sRingBuf.ulReadIndex));

    //
    // If the client read anything from the buffer, update the read pointer.
    //
    USBRingBufAdvanceRead(&psVars->sRingBuf, ulRead);

    //
    // Return the correct value to the low level driver.
    //
    return(ulRetCount);
}