Exemplo n.º 1
0
void stellaris_usbc_init(void)
{
	LTRACE_ENTRY;

	SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
	SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);

	SysCtlUSBPLLEnable();

	GPIOPinTypeUSBAnalog(GPIO_PORTD_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);

	USBDevMode(USB0_BASE);
	USBPHYPowerOn(USB0_BASE);

#if LOCAL_TRACE
	usbc_dump_regs();

	printf("addr %lu\n", USBDevAddrGet(USB0_BASE));
	printf("ep0 status 0x%lx\n", USBEndpointStatus(USB0_BASE, USB_EP_0));
#endif

	NVIC_EnableIRQ(INT_USB0 - 16);
	USBIntDisableControl(USB0_BASE, USB_INTCTRL_ALL);

	LTRACE_EXIT;
}
Exemplo n.º 2
0
static void ep0_irq(void)
{
	uint status = USBEndpointStatus(USB0_BASE, USB_EP_0);

	LTRACEF("ep0 status 0x%x\n", status);

	/* delay setting the address until the ack as completed */
	if (pending_addr_change) {
		LTRACEF("pending addr change\n");
		USBDevAddrSet(USB0_BASE, addr);
		pending_addr_change = false;
	}

	if (status & USB_DEV_EP0_OUT_PKTRDY) {
		LTRACEF("pktrdy\n");

		uchar buf[sizeof(struct usb_setup)];
		ulong avail = sizeof(buf);

		if (USBEndpointDataGet(USB0_BASE, USB_EP_0, buf, &avail) < 0 || avail != sizeof(buf)) {
			LTRACEF("short setup packet, size %lu\n", avail);
		} else {
			union usb_callback_args args;
			args.setup = (void *)buf;
			usb_callback(USB_CB_SETUP_MSG, &args);
		}
	}
	if (status & USB_DEV_EP0_SENT_STALL) {
		LTRACEF("stall complete\n");
		USBDevEndpointStallClear(USB0_BASE, USB_EP_0, 0);
	}
}
Exemplo n.º 3
0
//*****************************************************************************
//
// Receives notifications related to data sent to 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 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 tBoolean
ProcessDataToHost(const tUSBDBulkDevice *psDevice, unsigned int ulStatus, 
                                                    unsigned int ulIndex)
{
    tBulkInstance *psInst;
    unsigned int ulEPStatus;
    unsigned int ulSize;

    //
    // Get a pointer to our instance data.
    //
    psInst = psDevice->psPrivateBulkData;

    //
    // Get the endpoint status to see why we were called.
    //
    ulEPStatus = USBEndpointStatus(psInst->ulUSBBase, psInst->ucINEndpoint);

    //
    // Clear the status bits.
    //
    USBDevEndpointStatusClear(psInst->ulUSBBase, psInst->ucINEndpoint,
                              ulEPStatus);

    //
    // Our last transmission completed.  Clear our state back to idle and
    // see if we need to send any more data.
    //
    psInst->eBulkTxState = BULK_STATE_IDLE;

    //
    // Notify the client that the last transmission completed.
    //
    ulSize = psInst->usLastTxSize;
    psInst->usLastTxSize = 0;
    psDevice->pfnTxCallback(psDevice->pvTxCBData, USB_EVENT_TX_COMPLETE,
                            ulSize, (void *)0);

    return (true);
}
Exemplo n.º 4
0
//*****************************************************************************
//
//! Determines whether a packet is available and, if so, the size of the
//! buffer required to read it.
//!
//! \param pvInstance is the pointer to the device instance structure as
//! returned by USBDBulkInit().
//!
//! This function may be used to determine if a received packet remains to be
//! read and allows the application to determine the buffer size needed to
//! read the data.
//!
//! \return Returns 0 if no received packet remains unprocessed or the
//! size of the packet if a packet is waiting to be read.
//
//*****************************************************************************
unsigned int
USBDBulkRxPacketAvailable(void *pvInstance)
{
    unsigned int ulEPStatus;
    unsigned int ulSize;
    tBulkInstance *psInst;

    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)
    {
        //
        // Yes - a packet is waiting.  How big is it?
        //
        ulSize = USBEndpointDataAvail(psInst->ulUSBBase, psInst->ucOUTEndpoint);

        return (ulSize);
    }
    else
    {
        //
        // There is no packet waiting to be received.
        //
        return (0);
    }
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
//*****************************************************************************
//
//! 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);
}