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

📄 udp.c

📁 AT91SAM9261的USB设备驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:


//------------------------------------------------------------------------------
//      Includes
//------------------------------------------------------------------------------

#include "common.h"
#include "device.h"
#include "board.h"
//#include "trace.h"
#include "usb.h"

#ifdef UDP

#define UDP_STATE_SHOULD_RECONNECT      0x10000000
#define UDP_EPTYPE_INDEX                8
#define UDP_EPDIR_INDEX                 10

#define ISR_MASK                      0x00003FFF

//------------------------------------------------------------------------------
//      Structures
//------------------------------------------------------------------------------

// \brief  Endpoint states
typedef enum {

    endpointStateDisabled,
    endpointStateIdle,
    endpointStateWrite,
    endpointStateRead,
    endpointStateHalted

} EndpointState_t;

//------------------------------------------------------------------------------
//      Macros
//------------------------------------------------------------------------------

// \brief  Clear flags in the UDP_CSR register and waits for synchronization
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \param  dFlags    Flags to clear
#define UDP_CLEAREPFLAGS(pUsb, bEndpoint, dFlags) { \
    while (!ISCLEARED(UDP_GetDriverInterface(pUsb)->UDP_CSR[bEndpoint], dFlags)) \
        CLEAR(UDP_GetDriverInterface(pUsb)->UDP_CSR[bEndpoint], dFlags); \
}

// \brief  Set flags in the UDP_CSR register and waits for synchronization
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \param  dFlags    Flags to clear
#define UDP_SETEPFLAGS(pUsb, bEndpoint, dFlags) { \
    while (ISCLEARED(UDP_GetDriverInterface(pUsb)->UDP_CSR[bEndpoint], dFlags)) \
        SET(UDP_GetDriverInterface(pUsb)->UDP_CSR[bEndpoint], dFlags); \
}

//------------------------------------------------------------------------------
//      Internal Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// \brief  Returns a pointer to the UDP controller interface used by an USB
//         driver
//
//         The pointer is cast to the correct type (AT91PS_UDP).
// \param  pUsb Pointer to a S_usb instance
// \return Pointer to the USB controller interface
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline AT91PS_UDP UDP_GetDriverInterface(const S_usb *pUsb)
{
    return (AT91PS_UDP) pUsb->pDriver->pInterface;
}

//------------------------------------------------------------------------------
// \brief  Enables the peripheral clock of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_EnableMCK(const S_usb *pUsb)
{
    AT91C_BASE_PMC->PMC_PCER = 1 << USB_GetDriverID(pUsb);
}

//------------------------------------------------------------------------------
// \brief  Disables the peripheral clock of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_DisableMCK(const S_usb *pUsb)
{
    AT91C_BASE_PMC->PMC_PCDR = 1 << USB_GetDriverID(pUsb);
}

//------------------------------------------------------------------------------
// \brief  Enables the 48MHz clock of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_EnableUDPCK(const S_usb *pUsb)
{
    SET(AT91C_BASE_PMC->PMC_SCER, USB_GetDriverPMC(pUsb));
}

//------------------------------------------------------------------------------
// \brief  Disables the 48MHz clock of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_DisableUDPCK(const S_usb *pUsb)
{
    SET(AT91C_BASE_PMC->PMC_SCDR, USB_GetDriverPMC(pUsb));
}

//------------------------------------------------------------------------------
// \brief  Enables the transceiver of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_EnableTransceiver(const S_usb *pUsb)
{
    CLEAR(UDP_GetDriverInterface(pUsb)->UDP_TXVC, AT91C_UDP_TXVDIS);
}

//------------------------------------------------------------------------------
// \brief  Disables the transceiver of the USB controller associated with
//         the specified USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
extern __inline void UDP_DisableTransceiver(const S_usb *pUsb)
{
    SET(UDP_GetDriverInterface(pUsb)->UDP_TXVC, AT91C_UDP_TXVDIS);
}

//------------------------------------------------------------------------------
// \brief  Invokes the callback associated with a finished transfer on an
//         endpoint
// \param  pEndpoint Pointer to a S_usb_endpoint instance
// \param  bStatus   Status code returned by the transfer operation
// \see    Status codes
// \see    S_usb_endpoint
//------------------------------------------------------------------------------
extern __inline void UDP_EndOfTransfer(S_usb_endpoint *pEndpoint,
                                       char bStatus)
{
    if ((pEndpoint->dState == endpointStateWrite)
        || (pEndpoint->dState == endpointStateRead)) {


        // Endpoint returns in Idle state
        pEndpoint->dState = endpointStateIdle;

        // Invoke callback is present
        if (pEndpoint->fCallback != 0) {

            pEndpoint->fCallback((unsigned int) pEndpoint->pArgument,
                                 (unsigned int) bStatus,
                                 pEndpoint->dBytesTransferred,
                                 pEndpoint->dBytesRemaining
                                 + pEndpoint->dBytesBuffered);
        }
    }
}

//------------------------------------------------------------------------------
// \brief  Clears the correct RX flag in an endpoint status register
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \see    S_usb_endpoint
// \see    S_usb
//------------------------------------------------------------------------------
static void UDP_ClearRXFlag(const S_usb * pUsb,
                            unsigned char bEndpoint)
{
    S_usb_endpoint *pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);

    // Clear flag
    UDP_CLEAREPFLAGS(pUsb, bEndpoint, pEndpoint->dFlag);

    // Swap banks
    if (pEndpoint->dFlag == AT91C_UDP_RX_DATA_BK0) {

        if (pEndpoint->dNumFIFO > 1) {

            // Swap bank if in dual-fifo mode
            pEndpoint->dFlag = AT91C_UDP_RX_DATA_BK1;
        }
    }
    else {

        pEndpoint->dFlag = AT91C_UDP_RX_DATA_BK0;
    }
}

//------------------------------------------------------------------------------
// \brief  Transfers a data payload from the current tranfer buffer to the
//         endpoint FIFO.
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \return Number of bytes transferred
// \see    S_usb
//------------------------------------------------------------------------------
static unsigned int UDP_WritePayload(const S_usb * pUsb,
                                     unsigned char bEndpoint)
{
    AT91PS_UDP     pInterface = UDP_GetDriverInterface(pUsb);
    S_usb_endpoint *pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);
    unsigned int   dBytes;
    unsigned int   dCtr;

    // Get the number of bytes to send
    dBytes = min(pEndpoint->wMaxPacketSize, pEndpoint->dBytesRemaining);

    // Transfer one packet in the FIFO buffer
    for (dCtr = 0; dCtr < dBytes; dCtr++) {

        pInterface->UDP_FDR[bEndpoint] = *(pEndpoint->pData);
        pEndpoint->pData++;
    }

    pEndpoint->dBytesBuffered += dBytes;
    pEndpoint->dBytesRemaining -= dBytes;

    return dBytes;
}

//------------------------------------------------------------------------------
// \brief  Transfers a data payload from an endpoint FIFO to the current
//         transfer buffer.
// \param  pUsb        Pointer to a S_usb instance
// \param  bEndpoint   Index of endpoint
// \param  wPacketSize Size of received data packet
// \return Number of bytes transferred
// \see    S_usb
//------------------------------------------------------------------------------
static unsigned int UDP_GetPayload(const S_usb * pUsb,
                                   unsigned char bEndpoint,
                                   unsigned short wPacketSize)
{
    AT91PS_UDP     pInterface = UDP_GetDriverInterface(pUsb);
    S_usb_endpoint *pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);
    unsigned int   dBytes;
    unsigned int   dCtr;
    char ch;

    // Get number of bytes to retrieve
    dBytes = min(pEndpoint->dBytesRemaining, wPacketSize);

    // Retrieve packet
    for (dCtr = 0; dCtr < dBytes; dCtr++) {
		*pEndpoint->pData = (char) pInterface->UDP_FDR[bEndpoint];
        pEndpoint->pData++;
    }

    pEndpoint->dBytesRemaining -= dBytes;
    pEndpoint->dBytesTransferred += dBytes;
    pEndpoint->dBytesBuffered += wPacketSize - dBytes;

    return dBytes;
}

extern unsigned int g_menuzzz;
//------------------------------------------------------------------------------
// \brief  Transfers a received SETUP packet from endpoint 0 FIFO to the
//         S_usb_request structure of an USB driver
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
static void UDP_GetSetup(S_usb const *pUsb)
{
    char *pData = (char *) USB_GetSetup(pUsb);
    AT91PS_UDP pInterface = UDP_GetDriverInterface(pUsb);
    unsigned int dCtr;
    
    

    // Copy packet
    for (dCtr = 0; dCtr < 8; dCtr++) {

        *pData = (char) pInterface->UDP_FDR[0];
        //buff[dCtr] = *pData;
        pData++;
    }
    
    //if(g_menuzzz)
	 //   memcpy(pData,bufOK,8);
    
    
}

//------------------------------------------------------------------------------
// \brief  This function reset all endpoint transfer descriptors
// \param  pUsb Pointer to a S_usb instance
// \see    S_usb
//------------------------------------------------------------------------------
static void UDP_ResetEndpoints(const S_usb *pUsb)
{
    S_usb_endpoint *pEndpoint;
    unsigned char bEndpoint;

    // Reset the transfer descriptor of every endpoint
    for (bEndpoint = 0; bEndpoint < pUsb->dNumEndpoints; bEndpoint++) {

        pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);

        // Reset endpoint transfer descriptor
        pEndpoint->pData = 0;
        pEndpoint->dBytesRemaining = 0;
        pEndpoint->dBytesTransferred = 0;
        pEndpoint->dBytesBuffered = 0;
        pEndpoint->fCallback = 0;
        pEndpoint->pArgument = 0;

        // Configure endpoint characteristics
        pEndpoint->dFlag = AT91C_UDP_RX_DATA_BK0;
        pEndpoint->dState = endpointStateDisabled;
    }
}

//------------------------------------------------------------------------------
// \brief  Disable all endpoints (except control endpoint 0), aborting current
//         transfers if necessary.
// \param  pUsb Pointer to a S_usb instance
//------------------------------------------------------------------------------
static void UDP_DisableEndpoints(const S_usb *pUsb)
{
    S_usb_endpoint *pEndpoint;
    unsigned char bEndpoint;

    // For each endpoint, if it is enabled, disable it and invoke the callback
    // Control endpoint 0 is not disabled
    for (bEndpoint = 1; bEndpoint < pUsb->dNumEndpoints; bEndpoint++) {

        pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);
        UDP_EndOfTransfer(pEndpoint, USB_STATUS_RESET);
        pEndpoint->dState = endpointStateDisabled;
    }
}

//------------------------------------------------------------------------------
// \brief  Endpoint interrupt handler.
//
//         Handle IN/OUT transfers, received SETUP packets and STALLing
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \see    S_usb
//------------------------------------------------------------------------------
static void UDP_EndpointHandler(const S_usb *pUsb, unsigned char bEndpoint)
{
    S_usb_endpoint *pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);
    AT91PS_UDP pInterface = UDP_GetDriverInterface(pUsb);
    unsigned int dStatus = pInterface->UDP_CSR[bEndpoint];


    // Handle interrupts
    // IN packet sent
    if (ISSET(dStatus, AT91C_UDP_TXCOMP)) {


        // Check that endpoint was in Write state
        if (pEndpoint->dState == endpointStateWrite) {

            // End of transfer ?
            if ((pEndpoint->dBytesBuffered < pEndpoint->wMaxPacketSize)
                ||
                (!ISCLEARED(dStatus, AT91C_UDP_EPTYPE)
                 && (pEndpoint->dBytesRemaining == 0)
                 && (pEndpoint->dBytesBuffered == pEndpoint->wMaxPacketSize))) {


                pEndpoint->dBytesTransferred += pEndpoint->dBytesBuffered;
                pEndpoint->dBytesBuffered = 0;

                // Disable interrupt if this is not a control endpoint
                if (!ISCLEARED(dStatus, AT91C_UDP_EPTYPE)) {

                    SET(pInterface->UDP_IDR, 1 << bEndpoint);
                }

                UDP_EndOfTransfer(pEndpoint, USB_STATUS_SUCCESS);
            }
            else {

                // Transfer remaining data

                pEndpoint->dBytesTransferred += pEndpoint->wMaxPacketSize;
                pEndpoint->dBytesBuffered -= pEndpoint->wMaxPacketSize;

                // Send next packet
                if (pEndpoint->dNumFIFO == 1) {

                    // No double buffering
                    UDP_WritePayload(pUsb, bEndpoint);
                    UDP_SETEPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXPKTRDY);
                }
                else {

                    // Double buffering
                    UDP_SETEPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXPKTRDY);
                    UDP_WritePayload(pUsb, bEndpoint);
                }
            }
        }

        // Acknowledge interrupt
        UDP_CLEAREPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXCOMP);
    }
    // OUT packet received
    if (ISSET(dStatus, AT91C_UDP_RX_DATA_BK0)
        || ISSET(dStatus, AT91C_UDP_RX_DATA_BK1)) {


        // Check that the endpoint is in Read state

⌨️ 快捷键说明

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