//***************************************************************************** // // Receives notifications related to data sent to 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 originating // from the bulk IN endpoint (in other words, whenever data has been // transmitted to the USB host). We examine the cause of the interrupt and, // if due to completion of a transmission, notify the client. // // \return Returns \b true on success or \b false on failure. // //***************************************************************************** static bool ProcessDataToHost(tUSBDBulkDevice *psBulkDevice, uint32_t ui32Status) { tBulkInstance *psInst; uint32_t ui32EPStatus, ui32Size; // // 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(psInst->ui32USBBase, psInst->ui8INEndpoint); // // Clear the status bits. // MAP_USBDevEndpointStatusClear(psInst->ui32USBBase, psInst->ui8INEndpoint, ui32EPStatus); // // Our last transmission completed. Clear our state back to idle and // see if we need to send any more data. // psInst->iBulkTxState = eBulkStateIdle; // // Notify the client that the last transmission completed. // ui32Size = psInst->ui16LastTxSize; psInst->ui16LastTxSize = 0; psBulkDevice->pfnTxCallback(psBulkDevice->pvTxCBData, USB_EVENT_TX_COMPLETE, ui32Size, (void *)0); return(true); }
//***************************************************************************** // //! Reads a packet of data received from the USB host via the bulk data //! interface. //! //! \param pvBulkDevice is the pointer to the device instance structure as //! returned by USBDBulkInit(). //! \param pi8Data points to a buffer into which the received data will be //! written. //! \param ui32Length is the size of the buffer pointed to by pi8Data. //! \param bLast indicates whether the client will make a further call to //! read additional data from the packet. //! //! This function reads up to \e ui32Length 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. // //***************************************************************************** uint32_t USBDBulkPacketRead(void *pvBulkDevice, uint8_t *pi8Data, uint32_t ui32Length, bool bLast) { uint32_t ui32EPStatus, ui32Count, ui32Pkt; tBulkInstance *psInst; int32_t i32Retcode; ASSERT(pvBulkDevice); // // Get our instance data pointer // psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData; // // Does the relevant endpoint FIFO have a packet waiting for us? // ui32EPStatus = MAP_USBEndpointStatus(psInst->ui32USBBase, psInst->ui8OUTEndpoint); if(ui32EPStatus & USB_DEV_RX_PKT_RDY) { // // How many bytes are available for us to receive? // ui32Pkt = MAP_USBEndpointDataAvail(psInst->ui32USBBase, psInst->ui8OUTEndpoint); // // Get as much data as we can. // ui32Count = ui32Length; i32Retcode = MAP_USBEndpointDataGet(psInst->ui32USBBase, psInst->ui8OUTEndpoint, pi8Data, &ui32Count); // // Did we read the last of the packet data? // if(ui32Count == ui32Pkt) { // // Clear the endpoint status so that we know no packet is // waiting. // MAP_USBDevEndpointStatusClear(psInst->ui32USBBase, psInst->ui8OUTEndpoint, ui32EPStatus); // // Acknowledge the data, thus freeing the host to send the // next packet. // MAP_USBDevEndpointDataAck(psInst->ui32USBBase, psInst->ui8OUTEndpoint, true); // // Clear the flag we set to indicate that a packet read is // pending. // SetDeferredOpFlag(&psInst->ui16DeferredOpFlags, BULK_DO_PACKET_RX, false); } // // If all went well, tell the caller how many bytes they got. // if(i32Retcode != -1) { return(ui32Count); } } // // 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 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); }
//***************************************************************************** // // This function is called to handle the interrupts on the isochronous endpoint // for the audio device class. // //***************************************************************************** static void HandleEndpoints(void *pvAudioDevice, uint32_t ui32Status) { uint32_t ui32EPStatus; tAudioInstance *psInst; tUSBDAudioDevice *psAudioDevice; uint32_t ui32Size; ASSERT(pvAudioDevice != 0); // // The audio device structure pointer. // psAudioDevice = (tUSBDAudioDevice *)pvAudioDevice; // // Create a pointer to the audio instance data. // psInst = &psAudioDevice->sPrivateData; // // Read out the current endpoint status. // ui32EPStatus = MAP_USBEndpointStatus(USB0_BASE, psInst->ui8OUTEndpoint); // // See if there is a receive interrupt pending. // if(ui32Status & ((uint32_t)0x10000 << USBEPToIndex(psInst->ui8OUTEndpoint))) { // // Get the amount of data available in the FIFO. // ui32Size = USBEndpointDataAvail(psInst->ui32USBBase, psInst->ui8OUTEndpoint); // // Clear the status bits. // MAP_USBDevEndpointStatusClear(USB0_BASE, psInst->ui8OUTEndpoint, ui32EPStatus); // // Configure the next DMA transfer. // USBLibDMATransfer(psInst->psDMAInstance, psInst->ui8OUTDMA, psInst->sBuffer.pvData, ui32Size); } else if((USBLibDMAChannelStatus(psInst->psDMAInstance, psInst->ui8OUTDMA) == USBLIBSTATUS_DMA_COMPLETE)) { USBEndpointDMADisable(USB0_BASE, psInst->ui8OUTEndpoint, USB_EP_DEV_OUT); // // Acknowledge that the data was read, this will not cause a bus // acknowledgment. // MAP_USBDevEndpointDataAck(USB0_BASE, psInst->ui8OUTEndpoint, 0); // // Inform the callback of the new data. // psInst->sBuffer.pfnCallback(psInst->sBuffer.pvData, psInst->sBuffer.ui32Size, USBD_AUDIO_EVENT_DATAOUT); } }