Ejemplo n.º 1
0
//*****************************************************************************
//
// Schedule the next packet transmission to the host if data remains to be
// sent.
//
// \param psBuffer points to the buffer from which a packet transmission is
// to be scheduled.
//
// This function checks to determine whether the lower layer is capable of
// accepting a new packet for transmission and, if so, schedules the next
// packet transmission if data remains in the buffer.
//
// \return None.
//
//*****************************************************************************
static void
ScheduleNextTransmission(const tUSBBuffer *psBuffer)
{
    tUSBBufferVars *psVars;
    unsigned long ulPacket, ulSpace, ulTotal;

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

    //
    // Ask the lower layer if it has space to accept another packet of data.
    //
    ulPacket = psBuffer->pfnAvailable(psBuffer->pvHandle);

    //
    // If we were returned something other than zero, we can write that number
    // of bytes to the lower layer.
    //
    if(ulPacket)
    {
        //
        // How much contiguous data do we have in the buffer?
        //
        ulSpace = USBRingBufContigUsed(&psVars->sRingBuf);

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

        //
        // Write the contiguous bytes to the lower layer assuming there is
        // something to send.
        //
        if(ulSpace)
        {
            //
            // Determine the maximum sized block we can send in this transfer.
            //
            ulSpace = (ulSpace < ulPacket) ? ulSpace : ulPacket;
            //
            // Call the lower layer to send the new packet.  If the current
            // data spans the buffer wrap, tell the lower layer that it can
            // expect a second call to fill the whole packet before it
            // transmits it.
            //
            psBuffer->pfnTransfer(psBuffer->pvHandle,
                                 (psVars->sRingBuf.pucBuf +
                                  psVars->sRingBuf.ulReadIndex), ulSpace,
                                  (((ulSpace < ulPacket) &&
                                    (ulSpace < ulTotal)) ? false : true));

            //
            // Do we need to send a second part to fill out the packet?  This
            // will occur if the current packet spans the buffer wrap.
            //
            if((ulSpace < ulPacket) && (ulSpace < ulTotal))
            {
                //
                // The packet straddled the wrap.  How much space remains in
                // the packet?
                //
                ulPacket -= ulSpace;

                //
                // How much data can we actually send?
                //
                ulSpace = ulTotal - ulSpace;
                ulSpace = (ulSpace > ulPacket) ? ulPacket : ulSpace;

                psBuffer->pfnTransfer(psBuffer->pvHandle,
                                      psVars->sRingBuf.pucBuf, ulSpace, true);
            }
        }

        //
        // Don't update the ring buffer read index yet.  We do this once we are
        // sure the packet was correctly transmitted.
        //
    }
}
Ejemplo n.º 2
0
//*****************************************************************************
//
// Schedule the next packet transmission to the host if data remains to be
// sent.
//
// \param psBuffer points to the buffer from which a packet transmission is
// to be scheduled.
//
// This function checks to determine whether the lower layer is capable of
// accepting a new packet for transmission and, if so, schedules the next
// packet transmission if data remains in the buffer.
//
// \return None.
//
//*****************************************************************************
static void
ScheduleNextTransmission(tUSBBuffer *psBuffer)
{
    uint32_t ui32Packet, ui32Space, ui32Total, ui32Sent;

    //
    // Ask the lower layer if it has space to accept another packet of data.
    //
    ui32Packet = psBuffer->pfnAvailable(psBuffer->pvHandle);

    //
    // If we were returned something other than zero, we can write that number
    // of bytes to the lower layer.
    //
    if(ui32Packet)
    {
        //
        // How much contiguous data do we have in the buffer?
        //
        ui32Space = USBRingBufContigUsed(&psBuffer->sPrivateData.sRingBuf);

        //
        // How much total data do we have in the buffer?
        //
        ui32Total = USBRingBufUsed(&psBuffer->sPrivateData.sRingBuf);

        //
        // How much data will we be sending as a result of this call?
        //
        ui32Sent = (ui32Packet < ui32Total) ? ui32Packet : ui32Total;

        //
        // Write the contiguous bytes to the lower layer assuming there is
        // something to send.
        //
        if(ui32Space)
        {
            //
            // There is data available to send.  Update our state to indicate
            // the amount we will be sending in this packet.
            //
            psBuffer->sPrivateData.ui32LastSent = ui32Sent;

            //
            // Determine the maximum sized block we can send in this transfer.
            //
            ui32Space = (ui32Space < ui32Packet) ? ui32Space : ui32Packet;
            //
            // Call the lower layer to send the new packet.  If the current
            // data spans the buffer wrap, tell the lower layer that it can
            // expect a second call to fill the whole packet before it
            // transmits it.
            //
            psBuffer->pfnTransfer(psBuffer->pvHandle,
                              (psBuffer->sPrivateData.sRingBuf.pui8Buf +
                               psBuffer->sPrivateData.sRingBuf.ui32ReadIndex),
                               ui32Space,
                              (((ui32Space < ui32Packet) &&
                                (ui32Space < ui32Total)) ? false : true));

            //
            // Do we need to send a second part to fill out the packet?  This
            // will occur if the current packet spans the buffer wrap.
            //
            if((ui32Space < ui32Packet) && (ui32Space < ui32Total))
            {
                //
                // The packet straddled the wrap.  How much space remains in
                // the packet?
                //
                ui32Packet -= ui32Space;

                //
                // How much data can we actually send?
                //
                ui32Space = ui32Total - ui32Space;
                ui32Space = (ui32Space > ui32Packet) ? ui32Packet : ui32Space;

                psBuffer->pfnTransfer(psBuffer->pvHandle,
                                      psBuffer->sPrivateData.sRingBuf.pui8Buf,
                                      ui32Space, true);
            }
        }
        else
        {
            //
            // There is no data to send.  Did we last send a full packet?
            //
            if(psBuffer->sPrivateData.ui32LastSent == ui32Packet)
            {
                //
                // Yes - if necessary, send a zero-length packet back to the
                // host to complete the last transaction.
                //
                if(psBuffer->sPrivateData.ui32Flags & USB_BUFFER_FLAG_SEND_ZLP)
                {
                    psBuffer->sPrivateData.ui32LastSent = 0;
                    psBuffer->pfnTransfer(psBuffer->pvHandle,
                                      psBuffer->sPrivateData.sRingBuf.pui8Buf,
                                      0, true);
                }
            }
        }

        //
        // Don't update the ring buffer read index yet.  We do this once we are
        // sure the packet was correctly transmitted.
        //
    }
}