Friday, September 4, 2009

Serial to Ethernet Gateway Part 2

In this article, we will continue where we left off last week. After talking about the concept of ring buffer, how do we get the Serial data ? I have used serial interrupt to get data from the serial buffer. So whenever I get Serial data, the interrupt flag will be triggered. At this time, I have made the program to run an interrupt subroutine which gets data from the Serial Buffer and copy these data to anther designated buffer.

One question is what happens if the serial data buffer is full? In my design, whenever the serial buffer is full, we would send out all the data in the current serial buffer all at once. This ensures that none of the incoming serial data gets dropped due to the buffer is full.

Below is the code I have made. The first function is the interrupt subroutine, and the second function is to prepare the serial buffer for the LAN transfer buffer to send.



void ISR() interrupt 4 //ISR for UART
{
ES = 0; //Disable UART interrupt

if(RI) //Check for Receive Interrupt flag
{
RS232_RX_BUF[rs232_rx_write_idx] = SBUF; //write data from Serial buffer to uart rx buffer
rs232_rx_write_idx++; // increment write pointer
if(rs232_rx_write_idx >= MAX_RS232_BUF_SIZE) // check if write pointer is bigger than Maximum size of RS232_RX_BUF
{
rs232_rx_write_idx = 0; // reset write pointer to zero
}

if (rs232_rx_write_idx == rs232_rx_read_idx ) isfull = 1; // buffer is full, ignore new serial data
else
{
if (rs232_rx_write_idx == rs232_rx_read_idx ) isfull = 1; //buffer is full
}
RI = 0; // Disable Receive Interrupt flag
}
ES =1; //Enable UART Interrupt
}

uint16 rs232_to_lan()
{
uint16 xdata safe_read; // local read pointer
uint16 xdata safe_write; // local write pointer
uint16 xdata length; // length of data to be read
uint16 xdata count; // for loop counter

EA = 0; //disable all interrupt
safe_read = rs232_rx_read_idx; // get current value of read pointer
safe_write = rs232_rx_write_idx; // get current value of write pointer
EA = 1; //enable all interrupt

if(safe_write > safe_read)
{
length = safe_write - safe_read; // calculte the number of data to be read
}

else if(isfull == 1)
{
length = MAX_RS232_BUF_SIZE;
}
else
{
length = (MAX_RS232_BUF_SIZE - safe_read) + safe_write; // calculate the number of data to be read
}

for(count = 0; count <>
{
LAN_TX_BUF[lan_tx_write_idx] = RS232_RX_BUF[safe_read]; //write data from RS232 RX buffer to LAN TX buffer
safe_read++; //increase read pointer
if (safe_read >= MAX_RS232_BUF_SIZE) safe_read = 0; //RS232 RX buffer boundary check
lan_tx_write_idx++; //incread write pointer
if (lan_tx_write_idx >= MAX_BUF_SIZE) lan_tx_write_idx = 0; //LAN TX buffer boudary check
}

EA = 0; //disable all interrupt
rs232_rx_read_idx = safe_read; //return local readpointer to rs232 read pointer
EA = 1; //enable all interrupt
return length; //return length of data read
}

Thank you. I hope you enjoy my article. :)

No comments:

Post a Comment