📄 ser2enet.c
字号:
//
// See if the Ethernet receive interrupt occurred.
//
if(ulTemp & ETH_INT_RX)
{
//
// Indicate that the Ethernet receive intererupt occurred.
//
HWREGBITW(&g_ulFlags, FLAG_RXPKT) = 1;
//
// Disable the receive interrupt.
//
EthernetIntDisable(ETH_BASE, ETH_INT_RX);
}
//
// See if the Ethernet transmit interrupt occurred.
//
if(ulTemp & ETH_INT_TX)
{
//
// Disable the transmit interrupt.
//
EthernetIntDisable(ETH_BASE, ETH_INT_TX);
}
}
//*****************************************************************************
//
//! Handles the UART interrupt.
//!
//! This function is called when the UART generates an interrupt. An interrupt
//! will be generated when data is received and when the transmit FIFO becomes
//! half empty. The transmit and receive FIFOs are processed as appropriate.
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntHandler(void)
{
unsigned long ulStatus;
unsigned char ucChar;
//
// Get the cause of the interrupt.
//
ulStatus = UARTIntStatus(UART0_BASE, true);
//
// Clear the cause of the interrupt.
//
UARTIntClear(UART0_BASE, ulStatus);
//
// See if there is data to be processed in the receive FIFO.
//
if(ulStatus & (UART_INT_RT | UART_INT_RX))
{
//
// Loop while there are characters available in the receive FIFO.
//
while(UARTCharsAvail(UART0_BASE))
{
//
// Get the next character from the receive FIFO.
//
ucChar = UARTCharGet(UART0_BASE);
//
// See if this character is 0xff and there is space for two
// characters in the receive FIFO.
//
if((ucChar == 0xff) &&
(((g_ulRXWrite + 1) % UART_BUF_SIZE) != g_ulRXRead) &&
(((g_ulRXWrite + 2) % UART_BUF_SIZE) != g_ulRXRead))
{
//
// Write the 0xff into the receive FIFO twice since 0xff is the
// interpret as command (IAC) byte for telnet, and a doubled
// 0xff is interpreted as a single 0xff byte.
//
g_pucRXBuffer[g_ulRXWrite] = ucChar;
g_ulRXWrite = (g_ulRXWrite + 1) % UART_BUF_SIZE;
g_pucRXBuffer[g_ulRXWrite] = ucChar;
g_ulRXWrite = (g_ulRXWrite + 1) % UART_BUF_SIZE;
}
//
// See if the character is not 0xff adn there is space for a
// character in the receive FIFO.
//
if((ucChar != 0xff) &&
(((g_ulRXWrite + 1) % UART_BUF_SIZE) != g_ulRXRead))
{
g_pucRXBuffer[g_ulRXWrite] = ucChar;
g_ulRXWrite = (g_ulRXWrite + 1) % UART_BUF_SIZE;
}
}
//
// Set a flag indicating that there are newly received characters that
// need to be handled.
//
HWREGBITW(&g_ulFlags, FLAG_RXUART) = 1;
}
//
// See if there is space to be filled in the transmit FIFO.
//
if(ulStatus & UART_INT_TX)
{
//
// Loop while there is space in the transmit FIFO and characters to be
// sent.
//
while((g_ulTXRead != g_ulTXWrite) && UARTSpaceAvail(UART0_BASE))
{
//
// Write the next character into the transmit FIFO.
//
UARTCharPut(UART0_BASE, g_pucTXBuffer[g_ulTXRead]);
//
// Advance the read offset.
//
g_ulTXRead = (g_ulTXRead + 1) % UART_BUF_SIZE;
}
}
}
//*****************************************************************************
//
//! Sends a character to the UART.
//!
//! \param ucChar is the character to be sent.
//!
//! This function sends a character to the UART. The character will either be
//! directly written into the UART FIFO or into the UART transmit buffer, as
//! appropriate.
//!
//! \return None.
//
//*****************************************************************************
static void
UARTSend(unsigned char ucChar)
{
//
// Disable the UART transmit interrupt while determining how to handle this
// character. Failure to do so could result in the loss of this character,
// or stalled output due to this character being placed into the UART
// transmit buffer but never transferred out into the UART FIFO.
//
UARTIntDisable(UART0_BASE, UART_INT_TX);
//
// See if the transmit buffer is empty and there is space in the FIFO.
//
if((g_ulTXRead == g_ulTXWrite) && UARTSpaceAvail(UART0_BASE))
{
//
// Write this character directly into the FIFO.
//
UARTCharPut(UART0_BASE, ucChar);
}
//
// See if there is room in the transmit buffer.
//
else if(((g_ulTXWrite + 1) % UART_BUF_SIZE) != g_ulTXRead)
{
//
// Put this character into the transmit buffer.
//
g_pucTXBuffer[g_ulTXWrite] = ucChar;
//
// Increment the transmit buffer write pointer.
//
g_ulTXWrite = (g_ulTXWrite + 1) % UART_BUF_SIZE;
}
//
// Enable the UART transmit interrupt.
//
UARTIntEnable(UART0_BASE, UART_INT_TX);
}
//*****************************************************************************
//
//! Closes an existing Ethernet connection.
//!
//! \param pcb is the pointer to the TCP control structure.
//!
//! This function is called when the the TCP connection should be closed.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetClose(struct tcp_pcb *pcb)
{
//
// Clear out all of the TCP callbacks.
//
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_err(pcb, NULL);
tcp_poll(pcb, NULL, 1);
//
// Clear the telnet data structure pointer, to indicate that
// we are no longer connected.
//
g_psTelnetPCB = NULL;
//
// Close the TCP connection.
//
tcp_close(pcb);
}
//*****************************************************************************
//
//! Processes a telnet WILL request.
//!
//! \param ucOption is the telnet option in question.
//!
//! This function will handle a WILL request for a telnet option. If it is an
//! option that is known by the telnet server, a DO response will be generated
//! if the option is not already enabled. For unknown options, a DONT response
//! will always be generated.
//!
//! The response (if any) is written into the telnet transmit buffer.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetProcessWill(unsigned char ucOption)
{
unsigned long ulIdx;
//
// Loop through the known options.
//
for(ulIdx = 0; ulIdx < (sizeof(g_psOptions) / sizeof(g_psOptions[0]));
ulIdx++)
{
//
// See if this option matches the option in question.
//
if(g_psOptions[ulIdx].ucOption == ucOption)
{
//
// See if the WILL flag for this option has already been set.
//
if(HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_WILL) == 0)
{
//
// Set the WILL flag for this option.
//
HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_WILL) = 1;
//
// Send a DO response to this option.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_DO;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//
// Return without any further processing.
//
return;
}
}
//
// This option is not recognized, so send a DONT response.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_DONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//*****************************************************************************
//
//! Processes a telnet WONT request.
//!
//! \param ucOption is the telnet option in question.
//!
//! This function will handle a WONT request for a telnet option. If it is an
//! option that is known by the telnet server, a DONT response will be
//! generated if the option is not already disabled. For unknown options, a
//! DONT response will always be generated.
//!
//! The response (if any) is written into the telnet transmit buffer.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetProcessWont(unsigned char ucOption)
{
unsigned long ulIdx;
//
// Loop through the known options.
//
for(ulIdx = 0; ulIdx < (sizeof(g_psOptions) / sizeof(g_psOptions[0]));
ulIdx++)
{
//
// See if this option matches the option in question.
//
if(g_psOptions[ulIdx].ucOption == ucOption)
{
//
// See if the WILL flag for this option is currently set.
//
if(HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_WILL) == 1)
{
//
// Clear the WILL flag for this option.
//
HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_WILL) = 0;
//
// Send a DONT response to this option.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_DONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//
// Return without any further processing.
//
return;
}
}
//
// This option is not recognized, so send a DONT response.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_DONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//*****************************************************************************
//
//! Processes a telnet DO request.
//!
//! \param ucOption is the telnet option in question.
//!
//! This function will handle a DO request for a telnet optoin. If it is an
//! option that is known by the telnet server, a WILL response will be
//! generated if the option is not already enabled. For unknown options, a
//! WONT response will always be generated.
//!
//! The response (if any) is written into the telnet transmit buffer.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetProcessDo(unsigned char ucOption)
{
unsigned long ulIdx;
//
// Loop through the known options.
//
for(ulIdx = 0; ulIdx < (sizeof(g_psOptions) / sizeof(g_psOptions[0]));
ulIdx++)
{
//
// See if this option matches the option in question.
//
if(g_psOptions[ulIdx].ucOption == ucOption)
{
//
// See if the DO flag for this option has already been set.
//
if(HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_DO) == 0)
{
//
// Set the DO flag for this option.
//
HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_DO) = 1;
//
// Send a WILL response to this option.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_WILL;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//
// Return without any further processing.
//
return;
}
}
//
// This option is not recognized, so send a WONT response.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_WONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//*****************************************************************************
//
//! Processes a telnet DONT request.
//!
//! \param ucOption is the telnet option in question.
//!
//! This funciton will handle a DONT request for a telnet option. If it is an
//! option that is known by the telnet server, a WONT response will be
//! generated if the option is not already disabled. For unknown options, a
//! WONT resopnse will always be generated.
//!
//! The response (if any) is written into the telnet transmit buffer.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetProcessDont(unsigned char ucOption)
{
unsigned long ulIdx;
//
// Loop through the known options.
//
for(ulIdx = 0; ulIdx < (sizeof(g_psOptions) / sizeof(g_psOptions[0]));
ulIdx++)
{
//
// See if this option matches the option in question.
//
if(g_psOptions[ulIdx].ucOption == ucOption)
{
//
// See if the DO flag for this option is currently set.
//
if(HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_DO) == 1)
{
//
// Clear the DO flag for this option.
//
HWREGBITB(&(g_psOptions[ulIdx].ucFlags), OPT_FLAG_DO) = 0;
//
// Send a WONT response to this option.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_WONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -