⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.c

📁 iar 安装使用的方法。其中包括一些工程模板
💻 C
📖 第 1 页 / 共 5 页
字号:
        //
        if(ulFlags & USB_EP_AUTO_SET)
        {
            ulRegister |= USB_TXCSRH1_AUTOSET;
        }

        //
        // Configure the DMA mode.
        //
        if(ulFlags & USB_EP_DMA_MODE_1)
        {
            ulRegister |= USB_TXCSRH1_DMAEN | USB_TXCSRH1_DMAMOD;
        }
        else if(ulFlags & USB_EP_DMA_MODE_0)
        {
            ulRegister |= USB_TXCSRH1_DMAEN;
        }

        //
        // Enable isochronous mode if requested.
        //
        if((ulFlags & USB_EP_MODE_MASK) == USB_EP_MODE_ISOC)
        {
            ulRegister |= USB_TXCSRH1_ISO;
        }

        //
        // Write the transmit control value.
        //
        HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_TXCSRH1) =
            (unsigned char)ulRegister;

        //
        // Reset the Data toggle to zero.
        //
        HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_TXCSRL1) =
            USB_TXCSRL1_CLRDT;
    }
    else
    {
        //
        // Set the MaxPacketSize.
        //
        HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXMAXP1) =
            ulMaxPacketSize;

        //
        // The receive control value is zero unless options are enabled.
        //
        ulRegister = 0;

        //
        // Allow auto clearing of RxPktRdy when packet of size max packet
        // has been unloaded from the FIFO.
        //
        if(ulFlags & USB_EP_AUTO_CLEAR)
        {
            ulRegister = USB_RXCSRH1_AUTOCL;
        }

        //
        // Configure the DMA mode.
        //
        if(ulFlags & USB_EP_DMA_MODE_1)
        {
            ulRegister |= USB_RXCSRH1_DMAEN | USB_RXCSRH1_DMAMOD;
        }
        else if(ulFlags & USB_EP_DMA_MODE_0)
        {
            ulRegister |= USB_RXCSRH1_DMAEN;
        }

        //
        // Enable isochronous mode if requested.
        //
        if(USB_EP_MODE_ISOC & (ulFlags & USB_EP_MODE_MASK))
        {
            ulRegister |= USB_RXCSRH1_ISO;
        }

        //
        // Write the receive control value.
        //
        HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXCSRH1) =
            (unsigned char)ulRegister;

        //
        // Reset the Data toggle to zero.
        //
        HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXCSRL1) =
            USB_RXCSRL1_CLRDT;
    }
}

//*****************************************************************************
//
//! Sets the FIFO configuration for an endpoint.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param ulFIFOAddress is the starting address for the FIFO.
//! \param ulFIFOSize is the size of the FIFO in bytes.
//! \param ulFlags specifies what information to set in the FIFO configuration.
//!
//! This function will set the starting FIFO RAM address and size of the FIFO
//! for a given endpoint.  Endpoint zero does not have a dynamically
//! configurable FIFO so this function should not be called for endpoint zero.
//! The \e ulFIFOSize parameter should be one of the values in the
//! \b USB_FIFO_SZ_ values.  If the endpoint is going to use double buffering
//! it should use the values with the \b _DB at the end of the value.  For
//! example, use \b USB_FIFO_SZ_16_DB to configure an endpoint to have a 16
//! byte double buffered FIFO.  If a double buffered FIFO is used, then the
//! actual size of the FIFO will be twice the size indicated by the
//! \e ulFIFOSize parameter.  This means that the \b USB_FIFO_SZ_16_DB value
//! will use 32 bytes of the USB controller's FIFO memory.
//!
//! The \e ulFIFOAddress value should be a multiple of 8 bytes and directly
//! indicates the starting address in the USB controller's FIFO RAM.  For
//! example, a value of 64 indicates that the FIFO should start 64 bytes into
//! the USB controller's FIFO memory.  The \e ulFlags value specifies whether
//! the endpoint's OUT or IN FIFO should be configured.  If in host mode, use
//! \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode use
//! \b USB_EP_DEV_OUT or \b USB_EP_DEV_IN.
//!
//! \return None.
//
//*****************************************************************************
void
USBFIFOConfigSet(unsigned long ulBase, unsigned long ulEndpoint,
                 unsigned long ulFIFOAddress, unsigned long ulFIFOSize,
                 unsigned long ulFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == USB0_BASE);
    ASSERT((ulEndpoint == USB_EP_1) || (ulEndpoint == USB_EP_2) ||
           (ulEndpoint == USB_EP_3));

    //
    // See if the transmit or receive FIFO is being configured.
    //
    if(ulFlags & (USB_EP_HOST_OUT | USB_EP_DEV_IN))
    {
        //
        // Set the transmit FIFO location and size for this endpoint.
        //
        USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_TXFIFOSZ, ulFIFOSize, 1);
        USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_TXFIFOADD,
                      ulFIFOAddress >> 3, 2);
    }
    else
    {
        //
        // Set the receive FIFO location and size for this endpoint.
        //
        USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_RXFIFOSZ, ulFIFOSize, 1);
        USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_RXFIFOADD,
                      ulFIFOAddress >> 3, 2);
    }
}

//*****************************************************************************
//
//! Returns the FIFO configuration for an endpoint.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param pulFIFOAddress is the starting address for the FIFO.
//! \param pulFIFOSize is the size of the FIFO in bytes.
//! \param ulFlags specifies what information to retrieve from the FIFO
//! configuration.
//!
//! This function will return the starting address and size of the FIFO for a
//! given endpoint.  Endpoint zero does not have a dynamically configurable
//! FIFO so this function should not be called for endpoint zero.  The
//! \e ulFlags parameter specifies whether the endpoint's OUT or IN FIFO should
//! be read.  If in host mode, the \e ulFlags parameter should be
//! \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode the
//! \e ulFlags parameter should be either \b USB_EP_DEV_OUT or
//! \b USB_EP_DEV_IN.
//!
//! \return None.
//
//*****************************************************************************
void
USBFIFOConfigGet(unsigned long ulBase, unsigned long ulEndpoint,
                 unsigned long *pulFIFOAddress, unsigned long *pulFIFOSize,
                 unsigned long ulFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == USB0_BASE);
    ASSERT((ulEndpoint == USB_EP_1) || (ulEndpoint == USB_EP_2) ||
           (ulEndpoint == USB_EP_3));

    //
    // See if the transmit or receive FIFO is being configured.
    //
    if(ulFlags & (USB_EP_HOST_OUT | USB_EP_DEV_IN))
    {
        //
        // Get the transmit FIFO location and size for this endpoint.
        //
        *pulFIFOAddress = (USBIndexRead(ulBase, ulEndpoint >> 4,
                                        (unsigned long)USB_O_TXFIFOADD,
                                        2)) << 3;
        *pulFIFOSize = USBIndexRead(ulBase, ulEndpoint >> 4,
                                    (unsigned long)USB_O_TXFIFOSZ, 1);

    }
    else
    {
        //
        // Get the receive FIFO location and size for this endpoint.
        //
        *pulFIFOAddress = (USBIndexRead(ulBase, ulEndpoint >> 4,
                                        (unsigned long)USB_O_RXFIFOADD,
                                        2)) << 3;
        *pulFIFOSize = USBIndexRead(ulBase, ulEndpoint >> 4,
                                    (unsigned long)USB_O_RXFIFOSZ, 1);
    }
}

//*****************************************************************************
//
//! Retrieves data from the given endpoint's FIFO.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param pucData is a pointer to the data area used to return the data from
//! the FIFO.
//! \param pulSize is initially the size of the buffer passed into this call
//! via the \e pucData parameter.  It will be set to the amount of data
//! returned in the buffer.
//!
//! This function will return the data from the FIFO for the given endpoint.
//! The \e pulSize parameter should indicate the size of the buffer passed in
//! the \e pulData parameter.  The data in the \e pulSize parameter will be
//! changed to match the amount of data returned in the \e pucData parameter.
//! If a zero byte packet was received this call will not return a error but
//! will instead just return a zero in the \e pulSize parameter.  The only
//! error case occurs when there is no data packet available.
//!
//! \return This call will return 0, or -1 if no packet was received.
//
//*****************************************************************************
long
USBEndpointDataGet(unsigned long ulBase, unsigned long ulEndpoint,
                   unsigned char *pucData, unsigned long *pulSize)
{
    unsigned long ulRegister, ulByteCount, ulFIFO;

    //
    // Check the arguments.
    //
    ASSERT(ulBase == USB0_BASE);
    ASSERT((ulEndpoint == USB_EP_0) || (ulEndpoint == USB_EP_1) ||
           (ulEndpoint == USB_EP_2) || (ulEndpoint == USB_EP_3));

    //
    // Get the address of the receive status register to use, based on the
    // endpoint.
    //
    if(ulEndpoint == USB_EP_0)
    {
        ulRegister = USB_O_CSRL0;
    }
    else
    {
        ulRegister = USB_O_RXCSRL1 + EP_OFFSET(ulEndpoint);
    }

    //
    // Don't allow reading of data if the RxPktRdy bit is not set.
    //
    if((HWREGH(ulBase + ulRegister) & USB_CSRL0_RXRDY) == 0)
    {
        //
        // Can't read the data because none is available.
        //
        *pulSize = 0;

        //
        // Return a failure since there is no data to read.
        //
        return(-1);
    }

    //
    // Get the byte count in the FIFO.
    //
    ulByteCount = HWREGH(ulBase + USB_O_COUNT0 + ulEndpoint);

    //
    // Make sure that the buffer is large enough.
    //
    ASSERT(ulByteCount <= *pulSize);

    //
    // Return the number of bytes loaded into the buffer.
    //
    *pulSize = ulByteCount;

    //
    // Calculate the FIFO address.
    //
    ulFIFO = ulBase + USB_O_FIFO0 + (ulEndpoint >> 2);

    //
    // Read the data out of the FIFO.
    //
    for(; ulByteCount > 0; ulByteCount--)
    {
        //
        // Write out a word at a time while we can.
        //
        *pucData++ = HWREGB(ulFIFO);
    }

    //
    // Success.
    //
    return(0);
}

//*****************************************************************************
//
//! Acknowledge that data was read from the given endpoint's FIFO in device
//! mode.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param bIsLastPacket indicates if this is the last packet.
//!
//! This function acknowledges that the data was read from the endpoint's FIFO.
//! The \e bIsLastPacket parameter is set to a \b true value if this is the
//! last in a series of data packets on endpoint zero.  The \e bIsLastPacket
//! parameter is not used for endpoints other than endpoint zero.  This call
//! can be used if processing is required between reading the data and
//! acknowledging that the data has been read.
//!
//! \note This function should only be called in device mode.
//!
//! \return None.
//
//*****************************************************************************
void
USBDevEndpointDataAck(unsigned long ulBase, unsigned long ulEndpoint,
                      tBoolean bIsLastPacket)
{
    //
    // Check the arguments.
    //
    ASSERT(ulBase == USB0_BASE);
    ASSERT((ulEndpoint == USB_EP_0) || (ulEndpoint == USB_EP_1) ||
           (ulEndpoint == USB_EP_2) || (ulEndpoint == USB_EP_3));

    //
    // Determine which endpoint is being acked.
    //
    if(ulEndpoint == USB_EP_0)
    {
        //
        // Clear RxPktRdy, and optionally DataEnd, on endpoint zero.
        //
        HWREGB(ulBase + USB_O_CSRL0) =
            USB_CSRL0_RXRDYC | (bIsLastPacket ? USB_CSRL0_DATAEND : 0);
    }
    else
    {
        //
        // Clear RxPktRdy on all other endpoints.
        //
        HWREGB(ulBase + USB_O_RXCSRL1 + EP_OFFSET(ulEndpoint)) &=
            ~(USB_RXCSRL1_RXRDY);
    }
}

//*****************************************************************************
//
//! Acknowledge that data was read from the given endpoint's FIFO in host
//! mode.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//!
//! This function acknowledges that the data was read from the e

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -