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

📄 ui_ethernet.c

📁 Luminary Micro BLDC motor control software
💻 C
📖 第 1 页 / 共 5 页
字号:

    //
    // Return OK.
    //
    return(ERR_OK);
}

//*****************************************************************************
//
//! Receive a UDP packet from lwIP for motor control processing.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the UDB control structure.
//! \param p is the pointer to the PBUF structure containing the packet data.
//! \param addr is the source (remote) IP address for this packet.
//! \param port is the source (remote) port for this packet.
//!
//! This function is called when the lwIP TCP/IP stack has an incoming
//! UDP packet to be processed.
//!
//! \return This function will return an lwIP defined error code..
//
//*****************************************************************************
static void
UIEthernetReceiveUDP(void *arg, struct udp_pcb *pcb, struct pbuf *p,
        struct ip_addr *addr, u16_t port)
{
    unsigned char *pucData = p->payload;
    unsigned char ucTemp = 0;
    struct pbuf *p_out;

    //
    // Make sure the packet has enough data for us to process.
    //
    if(p->len < 4)
    {
        pbuf_free(p);
        return;
    }

    //
    // Check the first byte of the packet for TAG_CMD.
    //
    if(pucData[0] != TAG_CMD)
    {
        pbuf_free(p);
        return;
    }

    //
    // Check the second byte for valid length.
    //
    if(pucData[1] != 4)
    {
        pbuf_free(p);
        return;
    }

    //
    // Check the third byte for valid command.
    //
    if(pucData[2] != CMD_DISCOVER_TARGET)
    {
        pbuf_free(p);
        return;
    }

    //
    // Verify the checksum.
    //
    ucTemp = pucData[0] + pucData[1] + pucData[2] + pucData[3];
    if(ucTemp != 0)
    {
        pbuf_free(p);
        return;
    }

    //
    // Increment the packet counter.
    //
    g_ulEthernetRXCount++;

    //
    // Free the incoming pbuf ... we're done with it.
    //
    pbuf_free(p);

    //
    // Build a UDP Response Packet.
    // Byte  0: TAG_STATUS
    // Byte  1: 10
    // Byte  2: CMD_DISCOVER_TARGET
    // Byte  3: Board Type (e.g. RESP_ID_TARGET_BLDC)
    // Byte  4: Board ID (e.g. Configuration Switch Settings)
    // Byte  5: IP Address Octet 1
    // Byte  6: IP Address Octet 2
    // Byte  7: IP Address Octet 3
    // Byte  8: IP Address Octet 4
    // Byte  9: Checksum
    //
    p_out = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
    if(p_out == NULL)
    {
        return;
    }
    pucData= p_out->payload;
    pucData[0] = TAG_STATUS;
    pucData[1] = 10;
    pucData[2] = CMD_DISCOVER_TARGET;
    pucData[3] = (unsigned char)(g_ulUITargetType & 0xff);
    pucData[4] = g_ucBoardID;
    if(g_psTelnetPCB == NULL)
    {
        *(unsigned long *)&pucData[5] = 0;
    }
    else
    {
        *(unsigned long *)&pucData[5] = g_psTelnetPCB->remote_ip.addr;
    }

    //
    // Calcuate and fill in the checksum.
    //
    for(ucTemp = 0, pucData[10] = 0; ucTemp < 10; ucTemp++)
    {
        pucData[10] -= pucData[ucTemp];
    }

    //
    // Send the response.
    //
    udp_sendto(pcb, p_out, addr, port);
    pbuf_free(p_out);

    //
    // We're done.
    //
    return;
}

//*****************************************************************************
//
//! Receive a TCP packet from lwIP for motor control processing.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the TCP control structure.
//! \param p is the pointer to the PBUF structure containing the packet data.
//! \param err is used to indicate if any errors are associated with the
//! incoming packet.
//!
//! This function is called when the lwIP TCP/IP stack has an incoming
//! packet to be processed.
//!
//! \return This function will return an lwIP defined error code..
//
//*****************************************************************************
static err_t
UIEthernetReceive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct pbuf *q;
    unsigned long ulIdx;
    unsigned char *pucData;

    //
    // Process the incoming packet.
    // 
    if((err == ERR_OK) && (p != NULL))
    {
        //
        // Increment the packet counter.
        //
        g_ulEthernetRXCount++;

        //
        // Accept the packet from TCP.
        // 
        tcp_recved(pcb, p->tot_len);

        //
        // Process the packet.
        //
        for(q = p, pucData = q->payload; q != NULL; q = q->next)
        {
            for(ulIdx = 0; ulIdx < q->len; ulIdx++)
            {
                //
                // Copy the next character into the receive buffer.
                //
                g_pucUIEthernetReceive[g_ulUIEthernetReceiveWrite] =
                    pucData[ulIdx];

                //
                // Increment the receive buffer write pointer.
                //
                g_ulUIEthernetReceiveWrite =
                    (g_ulUIEthernetReceiveWrite + 1) % UIETHERNET_MAX_RECV;

                //
                // Scan the receive buffer for command packets if it is full.
                //
                if(((g_ulUIEthernetReceiveWrite + 1) % UIETHERNET_MAX_RECV) ==
                    g_ulUIEthernetReceiveRead)
                {
                    UIEthernetScanReceive();
                }
            }
        }

        //
        // Scan the receive buffer for command packets.
        //
        UIEthernetScanReceive();

        //
        // Free the pbuf.
        //
        pbuf_free(p);
    }

    //
    // If a null packet is passed in, close the connection.
    //
    else if((err == ERR_OK) && (p == NULL))
    {
        UIEthernetClose(pcb);
    }

    //
    // Return okay.
    //
    return ERR_OK;
}

//*****************************************************************************
//
//! lwIP TCP/IP Polling/Timeout function.
//!
//! \param arg is not used in this implementation.
//! \param pcb is not used in this implementation.
//!
//! This function is called when the lwIP TCP/IP stack has no incoming or
//! outgoing data.  It can be used to reset an idle connection.
//!
//! \return This function will return an lwIP defined error code..
//
//*****************************************************************************
static err_t
UIEthernetPoll(void *arg, struct tcp_pcb *pcb)
{
    //
    // Check the connection timeout.
    //
    g_ulConnectionTimeout++;
    if(g_ulConnectionTimeoutParameter &&
       (g_ulConnectionTimeout > g_ulConnectionTimeoutParameter))
    {
        tcp_abort(g_psTelnetPCB);
        g_psTelnetPCB = NULL;
    }
    return ERR_OK;
}

//*****************************************************************************
//
//! lwIP TCP/IP error handling.
//!
//! \param arg is not used in this implementation.
//! \param err is not used in this implementation.
//!
//! This function is called when the lwIP TCP/IP stack has detected an
//! error.  The connection is no longer valid.
//!
//! \return This function will return an lwIP defined error code..
//
//*****************************************************************************
static void
UIEthernetError(void *arg, err_t err)
{
    //
    // Reset our connection.
    //
    g_psTelnetPCB = NULL;
}

//*****************************************************************************
//
//! Accept a TCP connection for motor control processing.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the TCP control structure.
//! \param err is not used in this implementation.
//!
//! This function is called when the lwIP TCP/IP stack has an incoming
//! connection request on the telnet port.
//!
//! \return This function will return an lwIP defined error code..
//
//*****************************************************************************
static err_t
UIEthernetAccept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    //
    // Check if already connected.
    //
    if(g_psTelnetPCB)
    {
        //
        // If we already have a connection, kill it and start over.
        //
        UIEthernetClose(g_psTelnetPCB);
    }

    //
    // Set the connection timeout to 0.
    //
    g_ulConnectionTimeout = 0;

    //
    // Set the connection as busy.
    //
    g_psTelnetPCB = pcb;

    //
    // Setup the TCP connection priority.
    //
    tcp_setprio(pcb, TCP_PRIO_MIN);

    //
    // Setup the TCP callback argument.
    //
    tcp_arg(pcb, NULL);

    //
    // Setup the TCP receive function.
    // 
    tcp_recv(pcb, UIEthernetReceive);

    //
    // Setup the TCP error function.
    //
    tcp_err(pcb, UIEthernetError);

    //
    // Setup the TCP polling function/interval.
    //
    tcp_poll(pcb, UIEthernetPoll, (1000/TCP_SLOW_INTERVAL));

    //
    // Setup the TCP sent callback function.
    //
    tcp_sent(pcb, UIEthernetSent);

    //
    // Return a success code.
    // 
    return ERR_OK;
}

//*****************************************************************************
//
//! Handles the Ethernet interrupt.
//!
//! This function is called when the Ethernet controller asserts an interrupt.
//! If a receive packet is indicated, the lwIP input handler will be called.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntHandler(void)
{
    unsigned long ulTemp;

    //
    // Read and Clear the interrupt.
    //
    ulTemp = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulTemp);

    //
    // Check and process incoming packets
    //
    ulTemp = 0;
    while(ethernetif_input(&g_EMAC_if) == true)
    {
        //
        // Limit to 10 packets at a time.
        //
        if(ulTemp++ > 10)
        {
            break;
        }
    }

    //
    // Send a real-time data packet, if one has been requested.
    //
    if(g_bSendRealTimeData)
    {
        UIEthernetTransmit(g_pucUIEthernetData);
        g_bSendRealTimeData = false;
    }

    //
    // Check and process the ARP timer.
    //
    if((g_ulEthernetTimer - g_ulARPTimer) >= ARP_TMR_INTERVAL)
    {
        g_ulARPTimer = g_ulEthernetTimer;
        ethar

⌨️ 快捷键说明

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