📄 ui_ethernet.c
字号:
//
// 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 + -