//***************************************************************************** // //! Reads a packet of data received from the USB host via the bulk data //! interface. //! //! \param pvInstance is the pointer to the device instance structure as //! returned by USBDBulkInit(). //! \param pcData points to a buffer into which the received data will be //! written. //! \param ulLength is the size of the buffer pointed to by pcData. //! \param bLast indicates whether the client will make a further call to //! read additional data from the packet. //! //! This function reads up to \e ulLength bytes of data received from the USB //! host into the supplied application buffer. If the driver detects that the //! entire packet has been read, it is acknowledged to the host. //! //! The \e bLast parameter is ignored in this implementation since the end of //! a packet can be determined without relying upon the client to provide //! this information. //! //! \return Returns the number of bytes of data read. // //***************************************************************************** unsigned int USBDBulkPacketRead(void *pvInstance, unsigned char *pcData, unsigned int ulLength, tBoolean bLast) { unsigned int ulEPStatus, ulPkt; unsigned int ulCount; tBulkInstance *psInst; int iRetcode; ASSERT(pvInstance); // // Get our instance data pointer // psInst = ((tUSBDBulkDevice *)pvInstance)->psPrivateBulkData; // // Does the relevant endpoint FIFO have a packet waiting for us? // ulEPStatus = USBEndpointStatus(psInst->ulUSBBase, psInst->ucOUTEndpoint); if(ulEPStatus & USB_DEV_RX_PKT_RDY) { // // How many bytes are available for us to receive? // ulPkt = USBEndpointDataAvail(psInst->ulUSBBase, psInst->ucOUTEndpoint); // // Get as much data as we can. // ulCount = ulLength; iRetcode = USBEndpointDataGet(psInst->ulUSBBase, psInst->ucOUTEndpoint, pcData, &ulCount); // // Did we read the last of the packet data? // if(ulCount == ulPkt) { // // Clear the endpoint status so that we know no packet is // waiting. // USBDevEndpointStatusClear(psInst->ulUSBBase, psInst->ucOUTEndpoint, ulEPStatus); // // Acknowledge the data, thus freeing the host to send the // next packet. // USBDevEndpointDataAck(psInst->ulUSBBase, psInst->ucOUTEndpoint, true); // // Clear the flag we set to indicate that a packet read is // pending. // SetDeferredOpFlag(&psInst->usDeferredOpFlags, BULK_DO_PACKET_RX, false); } // // If all went well, tell the caller how many bytes they got. // if(iRetcode != -1) { return (ulCount); } } // // No packet was available or an error occurred while reading so tell // the caller no bytes were returned. // return (0); }
//***************************************************************************** // // Receives notifications related to data received from the host. // // \param psDevice is the device instance whose endpoint is to be processed. // \param ulStatus is the USB interrupt status that caused this function to // be called. // // This function is called from HandleEndpoints for all interrupts signaling // the arrival of data on the bulk OUT endpoint (in other words, whenever the // host has sent us a packet of data). We inform the client that a packet // is available and, on return, check to see if the packet has been read. If // not, we schedule another notification to the client for a later time. // // \return Returns \b true on success or \b false on failure. // //***************************************************************************** static tBoolean ProcessDataFromHost(const tUSBDBulkDevice *psDevice, unsigned int ulStatus, unsigned int ulIndex) { unsigned int ulEPStatus; unsigned int ulSize; tBulkInstance *psInst; // // Get a pointer to our instance data. // psInst = psDevice->psPrivateBulkData; // // Get the endpoint status to see why we were called. // ulEPStatus = USBEndpointStatus(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint); // // Clear the status bits. // USBDevEndpointStatusClear(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint, ulEPStatus); // // Has a packet been received? // if(ulEPStatus & USB_DEV_RX_PKT_RDY) { // // Set the flag we use to indicate that a packet read is pending. This // will be cleared if the packet is read. If the client doesn't read // the packet in the context of the USB_EVENT_RX_AVAILABLE callback, // the event will be signaled later during tick processing. // SetDeferredOpFlag(&psInst->usDeferredOpFlags, BULK_DO_PACKET_RX, true); // // How big is the packet we've just been sent? // ulSize = USBEndpointDataAvail(psInst->ulUSBBase, psInst->ucOUTEndpoint); // // The receive channel is not blocked so let the caller know // that a packet is waiting. The parameters are set to indicate // that the packet has not been read from the hardware FIFO yet. // psDevice->pfnRxCallback(psDevice->pvRxCBData, USB_EVENT_RX_AVAILABLE, ulSize, (void *)0); } else { // // No packet was received. Some error must have been reported. Check // and pass this on to the client if necessary. // if(ulEPStatus & USB_RX_ERROR_FLAGS) { // // This is an error we report to the client so... // psDevice->pfnRxCallback(psDevice->pvRxCBData, USB_EVENT_ERROR, (ulEPStatus & USB_RX_ERROR_FLAGS), (void *)0); } return (false); } return (true); }
//***************************************************************************** // // Receives notifications related to data received from the host. // // \param psBulkDevice is the device instance whose endpoint is to be // processed. // \param ui32Status is the USB interrupt status that caused this function to // be called. // // This function is called from HandleEndpoints for all interrupts signaling // the arrival of data on the bulk OUT endpoint (in other words, whenever the // host has sent us a packet of data). We inform the client that a packet // is available and, on return, check to see if the packet has been read. If // not, we schedule another notification to the client for a later time. // // \return Returns \b true on success or \b false on failure. // //***************************************************************************** static bool ProcessDataFromHost(tUSBDBulkDevice *psBulkDevice, uint32_t ui32Status) { uint32_t ui32EPStatus; uint32_t ui32Size; tBulkInstance *psInst; // // Get a pointer to the bulk device instance data pointer // psInst = &psBulkDevice->sPrivateData; // // Get the endpoint status to see why we were called. // ui32EPStatus = MAP_USBEndpointStatus(USB0_BASE, psInst->ui8OUTEndpoint); // // Clear the status bits. // MAP_USBDevEndpointStatusClear(USB0_BASE, psInst->ui8OUTEndpoint, ui32EPStatus); // // Has a packet been received? // if(ui32EPStatus & USB_DEV_RX_PKT_RDY) { // // Set the flag we use to indicate that a packet read is pending. This // will be cleared if the packet is read. If the client does not read // the packet in the context of the USB_EVENT_RX_AVAILABLE callback, // the event will be signaled later during tick processing. // SetDeferredOpFlag(&psInst->ui16DeferredOpFlags, BULK_DO_PACKET_RX, true); // // How big is the packet we have just received? // ui32Size = MAP_USBEndpointDataAvail(psInst->ui32USBBase, psInst->ui8OUTEndpoint); // // The receive channel is not blocked so let the caller know // that a packet is waiting. The parameters are set to indicate // that the packet has not been read from the hardware FIFO yet. // psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData, USB_EVENT_RX_AVAILABLE, ui32Size, (void *)0); } else { // // No packet was received. Some error must have been reported. Check // and pass this on to the client if necessary. // if(ui32EPStatus & USB_RX_ERROR_FLAGS) { // // This is an error we report to the client so allow the callback // to handle it. // psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData, USB_EVENT_ERROR, (ui32EPStatus & USB_RX_ERROR_FLAGS), (void *)0); } return(false); } return(true); }