//***************************************************************************** // // 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. // } }
//***************************************************************************** // // 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. // } }