📄 cs8900_enet_if_driver.c
字号:
* Notes: None
*
**********************************************************************/
#ifdef IRQACTIVE
__irq void enet_isr (void)
#else
void enet_isr (void)
#endif
{
UNS_16 enet_status;
// Read the interrupt status queue to determine cause of interrupt
enet_status = enet_read_port (isq);
// Loop through all events until none are left
while (enet_status != 0)
{
// Perform processing based on event in ethernet status
switch (enet_status & REGNUM_MASK)
{
case RRXEVENT:
// Receive event interrupt
enet_rx_event (enet_status);
break;
case RTXEVENT:
// Transmit event interrupt
// enet_tx_event (enet_status);
break;
case RBUFEVENT:
// Buffer event interrupt
// enet_buf_event (enet_status);
break;
case RRXMISS:
// RX frame missed overflow interrupt
break;
case RTXCOL:
// TX frame collision counter overflow interrupt
break;
default:
// No other interrupt types
break;
}
// Get next status - by default, this will also clear any
// unprocessed messages in the controller
enet_status = enet_read_port (isq);
}
enet_int_clear();
}
/*****************************************************************************
* Main functions - Data tansmission
****************************************************************************/
/**********************************************************************
*
* Function: enet_build_packet
*
* Purpose:
* Builds an ethernet packet from the data and destination address.
*
* Processing:
*
* Parameters:
* buffer: Pointer to message buffer to packetize
* mlen : Length of the message buffer
* dest : Destination address to send packet
* packet: Pointer of where to return constructed packet
*
* Outputs: None
*
* Returns: The length of the packet in bytes
*
* Notes: None
*
**********************************************************************/
INT_32 enet_build_packet (char *buffer,
INT_32 mlen,
UNS_8 *daddr,
char *packet)
{
INT_32 j;
buffer_t *pt = (buffer_t *) packet;
// Move source and destination address into packet
for (j = 0; j < 6; j++)
{
pt->daddr [j] = daddr [j];
pt->saddr [j] = enetaddr [j];
}
// Move length into packet
pt->datalen = (UNS_16) mlen;
// Move data into packet
for (j = 0; j < mlen; j++)
{
pt->buffer [j] = buffer [j];
}
// Return size of the constructed packet (data size + length field +
// source and destination address fields)
return (mlen + 6 + 6 + 2);
}
/**********************************************************************
*
* Function: enet_send_packet
*
* Purpose:
* Sends a pre-built packet out over ethernet.
*
* Processing:
*
*
* Parameters:
* None
*
* Outputs:
* None
*
* Returns:
* Nothing
*
* Notes:
* None
*
**********************************************************************/
void enet_send_packet (char *packet, INT_32 plen)
{
UNS_16 temp, *tpacketptr;
INT_32 j;
// Write the TX command word to the controller
enet_write_port (txcmd, (TXCMD | TX_START_ALL));
// Write the size of the packet to the controller (in bytes)
plen = plen + (plen & 0x1);
enet_write_port (txlen, (UNS_16) plen);
// Check bus status register
enet_set_pp_addr (&enet_pp_data->stco_regs.reg18_busst, 0);
temp = 0;
while (temp != RDY4TXNOW)
{
// Wait for TX buffer space to become available (not the best
// way to do this, but good for low level traffic)
temp = enet_read_data () & RDY4TXNOW;
}
// Controller is ready for data now so move it
// enet_set_pp_addr (&enet_pp_data->frame_regs.txfr_loc, 1);
tpacketptr = (UNS_16 *) packet;
for (j = 0; j < (plen / 2); j++)
{
// enet_write_data (tpacketptr [j]);
enet_write_port (txd0, tpacketptr [j]);
}
}
/**********************************************************************
*
* Function: enet_send
*
* Purpose: Queue a new data packet for transfer via ethernet.
*
* Processing:
*
* Parameters:
* buffer: Pointer to data buffer to send to destination
* mlen : Length of data buffer in bytes
* dest : Destination ethernet address
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_send (char *buffer, INT_32 mlen, UNS_8 *daddr)
{
char packet [1600];
char *txptr;
INT_32 j;
// Only send the packet if there is queue space available for it
if (tx.messages_queued < NUM_BUFS)
{
// Build the packet from the message data
mlen = enet_build_packet (buffer, mlen, daddr, packet);
// If the transmitter is idle, transmit the packet now
// otherwise, put it in the transmit queue
if (enet_txon == 0)
{
// Ready to transfer the packet now
enet_send_packet (packet, mlen);
#ifdef IRQACTIVE
// Transmitter state not valid during polling mode
enet_txon = 1;
#endif
}
else
{
// Put data packet in transmit queue
txptr = (char *) &tx.buffer [tx.next_message_in];
for (j = 0; j < mlen; j++)
{
txptr [j] = packet [j];
}
// Update incoming message queue to next pointer
tx.next_message_in++;
if (tx.next_message_in >= NUM_BUFS)
{
tx.next_message_in = 0;
}
// Updated queued packet counter
tx.messages_queued++;
}
}
}
/*****************************************************************************
* Main functions - Data reception
****************************************************************************/
/**********************************************************************
*
* Function: enet_packet_waiting
*
* Purpose:
* See if a data packet has been received via ethernet and queued.
*
* Processing:
*
* Parameters: None
*
* Outputs: None
*
* Returns: '1' if a packet is waiting processing, '0' otherwise.
*
* Notes: None
*
**********************************************************************/
INT_32 enet_packet_waiting (void)
{
// Return '1' if any packets are waiting for processing inside the
// RX message queue
return (rx.messages_queued != 0);
}
/**********************************************************************
*
* Function: enet_get_packet
*
* Purpose: Get the next ethernet packet off the receive queue.
*
* Processing:
*
* Parameters: None
*
* Outputs: None
*
* Returns:
* size of packet if it was moved into the buffer, '0' otherwise.
*
* Notes:
* call enet_clear_queued_msg to update receive buffer parameters
*
**********************************************************************/
INT_32 enet_get_packet (char *buffer)
{
INT_32 moved = 0;
INT_32 j;
char *bptr = (char *) &rx.buffer [rx.next_message_out];
// Check to see if any packets are waiting for processing
if (rx.messages_queued != 0)
{
// Copy packet from the RX queue to the provided buffer
moved = rx.psize [rx.next_message_out];
for (j = 0; j < moved; j++)
{
buffer [j] = bptr [j];
}
}
return moved;
}
/**********************************************************************
*
* Function: enet_get_saddr
*
* Purpose: Get the source address of the queued ethernet packet.
*
* Processing:
*
* Parameters:
* saddr: Pointer of where to return the source address
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_get_saddr (char *saddr)
{
INT_32 j;
// Check to see if any packets are waiting for processing
if (rx.messages_queued != 0)
{
// Copy packet from the RX queue to the provided buffer
for (j = 0; j < 6; j++)
{
saddr [j] = rx.buffer [rx.next_message_out].saddr [j];
}
}
}
/**********************************************************************
*
* Function: enet_get_data
*
* Purpose: Get the data portion of the queued ethernet packet.
*
* Processing:
*
* Parameters:
* buffer: Pointer of where to return the data
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* call enet_clear_queued_msg to update receive buffer parameters
*
**********************************************************************/
void enet_get_data (char *buffer)
{
INT_32 j;
// Check to see if any packets are waiting for processing
if (rx.messages_queued != 0)
{
// Copy packet from the RX queue to the provided buffer
for (j = 0; j < rx.buffer [rx.next_message_out].datalen; j++)
{
buffer [j] = rx.buffer [rx.next_message_out].buffer [j];
}
}
}
/**********************************************************************
*
* Function: enet_rx_packet_data_size
*
* Purpose: Return the size of the data portion of the queued ethernet
* packet.
*
* Processing:
*
* Parameters: None
*
* Outputs: None
*
* Returns:
*
* Notes: Useful for runtime buffer size determination.
*
**********************************************************************/
UNS_16 enet_rx_packet_data_size(void)
{
// Check to see if any packets are waiting for processing
if (rx.messages_queued != 0)
{
return (rx.buffer[rx.next_message_out].datalen);
}
else
return 0;
}
/**********************************************************************
*
* Function: enet_get_length
*
* Purpose:
* Get the length of the queued ethernet packet (data portion).
*
* Processing:
*
* Parameters:
* buffer: Pointer of where to return the data
*
* Outputs: None
*
* Returns: The length of the data buffer in the packet
*
* Notes: None
*
**********************************************************************/
INT_32 enet_get_length (void)
{
INT_32 len = -1;
// Check to see if any packets are waiting for processing
if (rx.messages_queued != 0)
{
// Adjust size for source/dest addresses and length/type field
len = rx.psize[rx.next_message_out] - 6 - 6 - 2;
}
return len;
}
/**********************************************************************
*
* Function: enet_clear_queued_msg
*
* Purpose: Clears the last message out of the receive queue.
*
* Processing:
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_clear_queued_msg (void)
{
// Update queue pointers
if (rx.messages_queued > 0)
{
rx.next_message_out++;
if (rx.next_message_out >= NUM_BUFS)
{
rx.next_message_out = 0;
}
rx.messages_queued--;
}
}
/*****************************************************************************
* Main functions - information functions
****************************************************************************/
/**********************************************************************
*
* Function: enet_set_address
*
* Purpose: Sets the ethernet address.
*
* Processing:
* The ethernet address in the provided array is moved into the
* ethernet controller individual address registers.
*
* Parameters:
* eaddr: Pointer to the ethernet address array
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_set_address (UNS_8 *eaddr)
{
UNS_16 enet_vals [3];
INT_32 j;
// Convert ethernet address to 3 words
for (j = 0 ; j < 6; j = j + 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -