//***************************************************************************** // // 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); }
//***************************************************************************** // // 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); }
//***************************************************************************** // //! 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); } }
//***************************************************************************** // //! 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); } }
//***************************************************************************** // // 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); }