mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Continue work on the SmartFusion web server demo.
This commit is contained in:
parent
9ebdc099d1
commit
fd20ed4d17
|
@ -51,6 +51,12 @@ extern "C" {
|
|||
#define MAC_TIME_OUT (-6)
|
||||
#define MAC_TOO_SMALL_PACKET (-7)
|
||||
|
||||
/* Allocating this many buffers will always ensure there is one free as, even
|
||||
though TX_RING_SIZE is set to two, the two Tx descriptors will only ever point
|
||||
to the same buffer. */
|
||||
#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE
|
||||
#define macBUFFER_SIZE 1500
|
||||
|
||||
/***************************************************************/
|
||||
MAC_instance_t g_mss_mac;
|
||||
|
||||
|
@ -75,6 +81,7 @@ static const int8_t ErrorMessages[][MAX_ERROR_MESSAGE_WIDTH] = {
|
|||
static MAC_instance_t* NULL_instance;
|
||||
static uint8_t* NULL_buffer;
|
||||
static MSS_MAC_callback_t NULL_callback;
|
||||
unsigned char *uip_buf = NULL;
|
||||
|
||||
/**************************** INTERNAL FUNCTIONS ******************************/
|
||||
|
||||
|
@ -95,6 +102,20 @@ static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n);
|
|||
static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n);
|
||||
static void MAC_memset_All(MAC_instance_t *s, uint32_t c);
|
||||
|
||||
static unsigned char *MAC_obtain_buffer( void );
|
||||
static void MAC_release_buffer( unsigned char *pcBufferToRelease );
|
||||
|
||||
#if( TX_RING_SIZE != 2 )
|
||||
#error This uIP Ethernet driver required TX_RING_SIZE to be set to 2
|
||||
#endif
|
||||
|
||||
/* Buffers that will dynamically be allocated to/from the Tx and Rx descriptors. */
|
||||
static unsigned char ucMACBuffers[ macNUM_BUFFERS ][ macBUFFER_SIZE ];
|
||||
|
||||
/* Each array position indicated whether or not the buffer of the same index
|
||||
is currently allocated to a descriptor (pdFALSE) or is free for use (pdTRUE). */
|
||||
static unsigned char ucMACBufferFree[ macNUM_BUFFERS ];
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes the Ethernet Controller.
|
||||
* This function will prepare the Ethernet Controller for first time use in a
|
||||
|
@ -114,6 +135,12 @@ MSS_MAC_init
|
|||
const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS };
|
||||
int32_t a;
|
||||
|
||||
/* To start with all buffers are free. */
|
||||
for( a = 0; a < macNUM_BUFFERS; a++ )
|
||||
{
|
||||
ucMACBufferFree[ a ] = pdTRUE;
|
||||
}
|
||||
|
||||
/* Try to reset chip */
|
||||
MAC_BITBAND->CSR0_SWR = 1u;
|
||||
|
||||
|
@ -139,13 +166,19 @@ MSS_MAC_init
|
|||
/* Give the ownership to the MAC */
|
||||
g_mss_mac.rx_descriptors[a].descriptor_0 = RDES0_OWN;
|
||||
g_mss_mac.rx_descriptors[a].descriptor_1 = (MSS_RX_BUFF_SIZE << RDES1_RBS1_OFFSET);
|
||||
g_mss_mac.rx_descriptors[a].buffer_1 = (uint32_t)g_mss_mac.rx_buffers[a];
|
||||
|
||||
/* Allocate a buffer to the descriptor, then mark the buffer as in use
|
||||
(not free). */
|
||||
g_mss_mac.rx_descriptors[a].buffer_1 = ( unsigned long ) &( ucMACBuffers[ a ][ 0 ] );
|
||||
ucMACBufferFree[ a ] = pdFALSE;
|
||||
}
|
||||
g_mss_mac.rx_descriptors[RX_RING_SIZE-1].descriptor_1 |= RDES1_RER;
|
||||
|
||||
for( a = 0; a < TX_RING_SIZE; a++ )
|
||||
{
|
||||
g_mss_mac.tx_descriptors[a].buffer_1 = ( unsigned long ) NULL; /* _RB_ used to be "(uint32_t)g_mss_mac.tx_buffers[a];" but set to NULL now to implement a zero copy scheme. */
|
||||
/* Buffers only get allocated to the Tx buffers when something is
|
||||
actually tranmitted. */
|
||||
g_mss_mac.tx_descriptors[a].buffer_1 = ( unsigned long ) NULL;
|
||||
}
|
||||
g_mss_mac.tx_descriptors[TX_RING_SIZE - 1].descriptor_1 |= TDES1_TER;
|
||||
|
||||
|
@ -343,31 +376,13 @@ MSS_MAC_get_configuration( void )
|
|||
|
||||
|
||||
/***************************************************************************//**
|
||||
Sends a packet to the Ethernet Controller.
|
||||
Sends a packet from the uIP stack to the Ethernet Controller.
|
||||
The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet
|
||||
MAC. This function writes pacLen bytes of the packet contained in pacData into
|
||||
MAC. This function writes uip_len bytes of the packet contained in uip_buf into
|
||||
the transmit FIFO and then activates the transmitter for this packet. If space
|
||||
is available in the FIFO, the function will return once pacLen bytes of the
|
||||
is available in the FIFO, the function will return once pac_len bytes of the
|
||||
packet have been placed into the FIFO and the transmitter has been started.
|
||||
This function will not wait for the transmission to complete. If space is not
|
||||
available in FIFO, the function will keep trying until time_out expires. The
|
||||
function will wait for the transmission to complete when the time_out parameter
|
||||
is set to MSS_MAC_BLOCKING.
|
||||
|
||||
@param pacData
|
||||
The pacData parameter is a pointer to the packet data to be transmitted.
|
||||
|
||||
@param pacLen
|
||||
The pacLen parameter is the number of bytes in the packet to be transmitted.
|
||||
|
||||
@param time_out
|
||||
The time_out parameter is the timeout value for the transmission in milliseconds.
|
||||
The time_out parameter value can be one of the following values:
|
||||
• Unsigned integer greater than 0 and less than 0x01000000
|
||||
• MSS_MAC_BLOCKING – there will be no timeout.
|
||||
• MSS_MAC_NONBLOCKING – the function will return immediately if the MSS Ethernet
|
||||
MAC does not have any available transmit descriptor. This would happen when
|
||||
several packets are already queued into the MSS Ethernet MAC transmit descriptor FIFO.
|
||||
This function will not wait for the transmission to complete.
|
||||
|
||||
@return
|
||||
The function returns zero if a timeout occurs otherwise it returns size of the packet.
|
||||
|
@ -378,119 +393,101 @@ MSS_MAC_get_configuration( void )
|
|||
int32_t
|
||||
MSS_MAC_tx_packet
|
||||
(
|
||||
const uint8_t *pacData,
|
||||
uint16_t pacLen,
|
||||
uint32_t time_out
|
||||
unsigned short usLength
|
||||
)
|
||||
{
|
||||
uint32_t desc;
|
||||
unsigned long ulDescriptor;
|
||||
int32_t error = MAC_OK;
|
||||
extern unsigned char *uip_buf;
|
||||
|
||||
ASSERT( MAC_test_instance() == MAC_OK );
|
||||
|
||||
ASSERT( pacData != NULL_buffer );
|
||||
ASSERT( uip_buf != NULL_buffer );
|
||||
|
||||
ASSERT( pacLen >= 12 );
|
||||
ASSERT( usLength >= 12 );
|
||||
|
||||
if( (g_mss_mac.flags & FLAG_EXCEED_LIMIT) == 0u )
|
||||
{
|
||||
ASSERT( pacLen <= MSS_MAX_PACKET_SIZE );
|
||||
ASSERT( usLength <= MSS_MAX_PACKET_SIZE );
|
||||
}
|
||||
|
||||
ASSERT( (time_out == MSS_MAC_BLOCKING) ||
|
||||
(time_out == MSS_MAC_NONBLOCKING) ||
|
||||
((time_out >= 1) && (time_out <= 0x01000000uL)) );
|
||||
|
||||
if( time_out == MSS_MAC_NONBLOCKING )
|
||||
{
|
||||
/* Check if current descriptor is free */
|
||||
if(((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
|
||||
{
|
||||
error = MAC_BUFFER_IS_FULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Check if second descriptor is free, if it is then the first must
|
||||
also be free. */
|
||||
if(((g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
|
||||
{
|
||||
/* Wait until descriptor is free */
|
||||
if( time_out != MSS_MAC_BLOCKING ) {
|
||||
MAC_set_time_out( time_out );
|
||||
}
|
||||
|
||||
while( (((g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
|
||||
&& (error == MAC_OK) )
|
||||
{
|
||||
/* transmit poll demand */
|
||||
MAC->CSR1 = 1u;
|
||||
|
||||
if(time_out != MSS_MAC_BLOCKING){
|
||||
if(MAC_get_time_out() == 0u) {
|
||||
error = MAC_TIME_OUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
error = MAC_BUFFER_IS_FULL;
|
||||
}
|
||||
|
||||
if( error == MAC_OK ) {
|
||||
/* Assumed TX_RING_SIZE == 2. */
|
||||
for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ )
|
||||
{
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 = 0u;
|
||||
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u;
|
||||
if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_AC;
|
||||
}
|
||||
|
||||
if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC;
|
||||
/* Every buffer can hold a full frame so they are always first and last
|
||||
descriptor */
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_LS | TDES1_FS;
|
||||
|
||||
/* set data size */
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= usLength;
|
||||
|
||||
/* reset end of ring */
|
||||
g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
|
||||
|
||||
if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
|
||||
{
|
||||
usLength = (uint16_t)MSS_TX_BUFF_SIZE;
|
||||
}
|
||||
|
||||
/* The data buffer is assigned to the Tx descriptor. */
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].buffer_1 = ( unsigned long ) uip_buf;
|
||||
|
||||
/* update counters */
|
||||
desc = g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0;
|
||||
if( (desc & TDES0_LO) != 0u ) {
|
||||
g_mss_mac.statistics.tx_loss_of_carrier++;
|
||||
}
|
||||
if( (desc & TDES0_NC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_no_carrier++;
|
||||
}
|
||||
if( (desc & TDES0_LC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_late_collision++;
|
||||
}
|
||||
if( (desc & TDES0_EC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_excessive_collision++;
|
||||
}
|
||||
if( (desc & TDES0_UF) != 0u ) {
|
||||
g_mss_mac.statistics.tx_underflow_error++;
|
||||
}
|
||||
g_mss_mac.statistics.tx_collision_count +=
|
||||
(desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;
|
||||
|
||||
/* Give ownership of descriptor to the MAC */
|
||||
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0 = TDES0_OWN;
|
||||
|
||||
g_mss_mac.tx_desc_index = 0;
|
||||
}
|
||||
|
||||
/* Every buffer can hold a full frame so they are always first and last
|
||||
descriptor */
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS;
|
||||
|
||||
/* set data size */
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= pacLen;
|
||||
|
||||
/* reset end of ring */
|
||||
g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
|
||||
|
||||
/* copy data into buffer */
|
||||
if( pacLen > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
|
||||
{
|
||||
pacLen = (uint16_t)MSS_TX_BUFF_SIZE;
|
||||
}
|
||||
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) pacData;
|
||||
|
||||
/* update counters */
|
||||
desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0;
|
||||
if( (desc & TDES0_LO) != 0u ) {
|
||||
g_mss_mac.statistics.tx_loss_of_carrier++;
|
||||
}
|
||||
if( (desc & TDES0_NC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_no_carrier++;
|
||||
}
|
||||
if( (desc & TDES0_LC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_late_collision++;
|
||||
}
|
||||
if( (desc & TDES0_EC) != 0u ) {
|
||||
g_mss_mac.statistics.tx_excessive_collision++;
|
||||
}
|
||||
if( (desc & TDES0_UF) != 0u ) {
|
||||
g_mss_mac.statistics.tx_underflow_error++;
|
||||
}
|
||||
g_mss_mac.statistics.tx_collision_count +=
|
||||
(desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;
|
||||
|
||||
/* Give ownership of descriptor to the MAC */
|
||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0 = RDES0_OWN;
|
||||
|
||||
g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE;
|
||||
|
||||
/* Start transmission */
|
||||
MAC_start_transmission();
|
||||
|
||||
/* transmit poll demand */
|
||||
MAC->CSR1 = 1u;
|
||||
}
|
||||
|
||||
|
||||
/* Start transmission */
|
||||
MAC_start_transmission();
|
||||
|
||||
/* transmit poll demand */
|
||||
MAC->CSR1 = 1u;
|
||||
|
||||
|
||||
|
||||
if (error == MAC_OK)
|
||||
{
|
||||
error = (int32_t)pacLen;
|
||||
/* The buffer uip_buf was pointing to is now under the control of the
|
||||
MAC (it is being transmitted). Set uip_buf to point to a free buffer. */
|
||||
uip_buf = MAC_obtain_buffer();
|
||||
error = (int32_t)usLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -535,24 +532,11 @@ MSS_MAC_rx_pckt_size
|
|||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Receives a packet from the Ethernet Controller.
|
||||
* Receives a packet from the Ethernet Controller into the uIP stack.
|
||||
* This function reads a packet from the receive FIFO of the controller and
|
||||
* places it into pacData. If time_out parameter is zero the function will return
|
||||
* immediately (after the copy operation if data is available. Otherwise the function
|
||||
* will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING
|
||||
* value is given as time_out, function will wait for the reception to complete.
|
||||
*
|
||||
* @param instance Pointer to a MAC_instance_t structure
|
||||
* @param pacData The pointer to the packet data.
|
||||
* @param pacLen The pacLen parameter is the size in bytes of the pacData
|
||||
* buffer where the received data will be copied.
|
||||
* @param time_out Time out value in milli seconds for receiving.
|
||||
* if value is #MSS_MAC_BLOCKING, there will be no time out.
|
||||
* if value is #MSS_MAC_NONBLOCKING, function will return immediately
|
||||
* if there is no packet waiting.
|
||||
* Otherwise value must be greater than 0 and smaller than
|
||||
* 0x01000000.
|
||||
* @return Size of packet if packet fits in pacData.
|
||||
* places it into uip_buf.
|
||||
|
||||
* @return Size of packet if packet fits in uip_buf.
|
||||
* 0 if there is no received packet.
|
||||
* @see MAC_rx_pckt_size()
|
||||
* @see MAC_tx_packet()
|
||||
|
@ -560,42 +544,16 @@ MSS_MAC_rx_pckt_size
|
|||
int32_t
|
||||
MSS_MAC_rx_packet
|
||||
(
|
||||
unsigned char **pacData,
|
||||
uint16_t pacLen,
|
||||
uint32_t time_out
|
||||
void
|
||||
)
|
||||
{
|
||||
uint16_t frame_length=0u;
|
||||
int8_t exit=0;
|
||||
|
||||
ASSERT( MAC_test_instance() == MAC_OK );
|
||||
ASSERT( (time_out == MSS_MAC_BLOCKING) ||
|
||||
(time_out == MSS_MAC_NONBLOCKING) ||
|
||||
((time_out >= 1) && (time_out <= 0x01000000UL)) );
|
||||
|
||||
|
||||
MAC_dismiss_bad_frames();
|
||||
|
||||
/* wait for a packet */
|
||||
if( time_out != MSS_MAC_BLOCKING ) {
|
||||
if( time_out == MSS_MAC_NONBLOCKING ) {
|
||||
MAC_set_time_out( 0u );
|
||||
} else {
|
||||
MAC_set_time_out( time_out );
|
||||
}
|
||||
}
|
||||
|
||||
while( ((g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &
|
||||
RDES0_OWN) != 0u) && (exit == 0) )
|
||||
{
|
||||
if( time_out != MSS_MAC_BLOCKING )
|
||||
{
|
||||
if( MAC_get_time_out() == 0u ) {
|
||||
exit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(exit == 0)
|
||||
if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) == 0u )
|
||||
{
|
||||
frame_length = ( (
|
||||
g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>
|
||||
|
@ -604,14 +562,21 @@ MSS_MAC_rx_packet
|
|||
/* strip crc */
|
||||
frame_length -= 4u;
|
||||
|
||||
if( frame_length > pacLen ) {
|
||||
if( frame_length > macBUFFER_SIZE ) {
|
||||
return MAC_NOT_ENOUGH_SPACE;
|
||||
}
|
||||
|
||||
*pacData = ( unsigned char * ) g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1;
|
||||
/* uip_buf is about to point to the buffer that contains the received
|
||||
data, mark the buffer that uip_buf is currently pointing to as free
|
||||
again. */
|
||||
MAC_release_buffer( uip_buf );
|
||||
uip_buf = ( unsigned char * ) g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1;
|
||||
|
||||
/* The buffer the Rx descriptor was pointing to is now in use by the
|
||||
uIP stack - allocate a new buffer to the Rx descriptor. */
|
||||
g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 = ( unsigned long ) MAC_obtain_buffer();
|
||||
|
||||
MSS_MAC_prepare_rx_descriptor();
|
||||
|
||||
}
|
||||
return ((int32_t)frame_length);
|
||||
}
|
||||
|
@ -1444,10 +1409,10 @@ static void MAC_memset_All(MAC_instance_t *s, uint32_t c)
|
|||
MAC_memset( s->mac_address, (uint8_t)c, 6u );
|
||||
MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );
|
||||
s->phy_address = (uint8_t)c;
|
||||
for(count = 0; count<RX_RING_SIZE ;count++)
|
||||
{
|
||||
MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
|
||||
}
|
||||
// for(count = 0; count<RX_RING_SIZE ;count++)
|
||||
// {
|
||||
// MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
|
||||
// }
|
||||
s->rx_desc_index =c;
|
||||
for(count = 0; count<RX_RING_SIZE ;count++)
|
||||
{
|
||||
|
@ -1475,10 +1440,10 @@ static void MAC_memset_All(MAC_instance_t *s, uint32_t c)
|
|||
s->statistics.tx_no_carrier = c;
|
||||
s->statistics.tx_underflow_error = c;
|
||||
s->time_out_value = c;
|
||||
for(count = 0; count < TX_RING_SIZE ;count++)
|
||||
{
|
||||
MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );
|
||||
}
|
||||
// for(count = 0; count < TX_RING_SIZE ;count++)
|
||||
// {
|
||||
// MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );
|
||||
// }
|
||||
s->tx_desc_index = c;
|
||||
for(count = 0; count < TX_RING_SIZE ;count++)
|
||||
{
|
||||
|
@ -1505,6 +1470,59 @@ static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n)
|
|||
}
|
||||
}
|
||||
|
||||
void MSS_MAC_TxBufferCompleted( void )
|
||||
{
|
||||
unsigned char *pxTransmittedBuffer;
|
||||
|
||||
/* Was it the second transmission that has completed? */
|
||||
if( ( g_mss_mac.tx_descriptors[ 1 ].descriptor_0 & TDES0_OWN ) == 0UL )
|
||||
{
|
||||
pxTransmittedBuffer = ( unsigned char * ) g_mss_mac.tx_descriptors[ 1 ].buffer_1;
|
||||
|
||||
/* The buffer has been transmitted and is no longer in use. */
|
||||
MAC_release_buffer( pxTransmittedBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *MAC_obtain_buffer( void )
|
||||
{
|
||||
long lIndex;
|
||||
unsigned char *pcReturn = NULL;
|
||||
|
||||
/* Find and return the address of a buffer that is not being used. Mark
|
||||
the buffer as now in use. */
|
||||
for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )
|
||||
{
|
||||
if( ucMACBufferFree[ lIndex ] == pdTRUE )
|
||||
{
|
||||
pcReturn = &( ucMACBuffers[ lIndex ][ 0 ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
configASSERT( pcReturn );
|
||||
return pcReturn;
|
||||
}
|
||||
|
||||
void MAC_release_buffer( unsigned char *pucBufferToRelease )
|
||||
{
|
||||
long lIndex;
|
||||
|
||||
/* uip_buf is going to point to a different buffer - first ensure the buffer
|
||||
it is currently pointing to is marked as being free again. */
|
||||
for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )
|
||||
{
|
||||
if( pucBufferToRelease == &( ucMACBuffers[ lIndex ][ 0 ] ) )
|
||||
{
|
||||
/* This is the buffer in use, mark it as being free. */
|
||||
ucMACBufferFree[ lIndex ] = pdTRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -342,37 +342,26 @@ MSS_MAC_get_configuration
|
|||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sends a packet to the Ethernet Controller.
|
||||
* This function writes pacLen bytes of the packet contained in pacData into the
|
||||
* transmit FIFO of the controller and then activates the transmitter for this
|
||||
* packet. If space is available in FIFO, the function will return once lBufLen
|
||||
* bytes of the packet have been placed into the FIFO and the transmitter has been
|
||||
* started. The function will not wait for the transmission to complete. If space
|
||||
* is not available in FIFO, the function will keep trying till time_out expires,
|
||||
* if MSS_MAC_BLOCKING value is given as time_out, function will wait for the
|
||||
* transmission to complete.
|
||||
*
|
||||
* @param pacData the pointer to the packet data to be transmitted.
|
||||
* @param pacLen number of bytes in the packet to be transmitted.
|
||||
* @param time_out Time out value for transmision.
|
||||
* If value is #MSS_MAC_BLOCKING, there will be no time out.
|
||||
* If value is #MSS_MAC_NONBLOCKING, function will return immediately
|
||||
* on buffer full case.
|
||||
* Otherwise value must be greater than 0 and smaller than
|
||||
* 0x01000000.
|
||||
* @return Returns 0 if time out occurs otherwise returns size
|
||||
* of the packet.
|
||||
* @see MAC_rx_packet()
|
||||
Sends a packet from the uIP stack to the Ethernet Controller.
|
||||
The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet
|
||||
MAC. This function writes uip_len bytes of the packet contained in uip_buf into
|
||||
the transmit FIFO and then activates the transmitter for this packet. If space
|
||||
is available in the FIFO, the function will return once pac_len bytes of the
|
||||
packet have been placed into the FIFO and the transmitter has been started.
|
||||
This function will not wait for the transmission to complete.
|
||||
|
||||
@return
|
||||
The function returns zero if a timeout occurs otherwise it returns size of the packet.
|
||||
|
||||
@see MAC_rx_packet()
|
||||
*/
|
||||
|
||||
int32_t
|
||||
MSS_MAC_tx_packet
|
||||
(
|
||||
const uint8_t *pacData,
|
||||
uint16_t pacLen,
|
||||
uint32_t time_out
|
||||
unsigned short usLength
|
||||
);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Returns available packet's size.
|
||||
*
|
||||
|
@ -401,25 +390,11 @@ MSS_MAC_prepare_rx_descriptor
|
|||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Receives a packet from the Ethernet Controller.
|
||||
* Receives a packet from the Ethernet Controller into the uIP stack.
|
||||
* This function reads a packet from the receive FIFO of the controller and
|
||||
* places it into pacData. If time_out parameter is zero the function will return
|
||||
* immediately (after the copy operation if data is available. Otherwise the function
|
||||
* will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING
|
||||
* value is given as time_out, function will wait for the reception to complete.
|
||||
*
|
||||
* @param pacData The pointer to the buffer where received packet data will
|
||||
* be copied. Memory for the buffer should be allocated prior
|
||||
* to calling this function.
|
||||
* @param pacLen Size of the buffer, which the received data will be copied in,
|
||||
* given in number of bytes.
|
||||
* @param time_out Time out value in milli seconds for receiving.
|
||||
* if value is #MSS_MAC_BLOCKING, there will be no time out.
|
||||
* if value is #MSS_MAC_NONBLOCKING, function will return immediately
|
||||
* if there is no packet waiting.
|
||||
* Otherwise value must be greater than 0 and smaller than
|
||||
* 0x01000000.
|
||||
* @return Size of packet if packet fits in pacData.
|
||||
* places it into uip_buf.
|
||||
|
||||
* @return Size of packet if packet fits in uip_buf.
|
||||
* 0 if there is no received packet.
|
||||
* @see MAC_rx_pckt_size()
|
||||
* @see MAC_tx_packet()
|
||||
|
@ -427,9 +402,7 @@ MSS_MAC_prepare_rx_descriptor
|
|||
int32_t
|
||||
MSS_MAC_rx_packet
|
||||
(
|
||||
uint8_t **pacData,
|
||||
uint16_t pacLen,
|
||||
uint32_t time_out
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
|
@ -587,6 +560,23 @@ MSS_MAC_get_statistics
|
|||
mss_mac_statistics_id_t stat_id
|
||||
);
|
||||
|
||||
/*
|
||||
* Ensure uip_buf is pointing to a valid and free buffer before any transmissions
|
||||
* initiated by the uIP stack occur.
|
||||
*/
|
||||
unsigned char *MSS_MAC_GetTxDescriptor( void );
|
||||
|
||||
/*
|
||||
* A buffer is no longer required by the application. Hand it back to the
|
||||
* control of the MAC hardware.
|
||||
*/
|
||||
void MSS_MAC_ReleaseBuffer( unsigned char *pucBuffer );
|
||||
|
||||
/*
|
||||
* The double Tx has completed. Hand back the Tx buffer to the control of
|
||||
* the MAC hardware.
|
||||
*/
|
||||
void MSS_MAC_TxBufferCompleted( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -65,12 +65,12 @@ typedef struct {
|
|||
|
||||
/* transmit related info: */
|
||||
uint32_t tx_desc_index; /**< index of the transmit descriptor getting used*/
|
||||
uint8_t tx_buffers[TX_RING_SIZE][MSS_TX_BUFF_SIZE];/**< array of transmit buffers*/
|
||||
// uint8_t tx_buffers[TX_RING_SIZE][MSS_TX_BUFF_SIZE];/**< array of transmit buffers*/
|
||||
MAC_descriptor_t tx_descriptors[TX_RING_SIZE];/**< array of transmit descriptors*/
|
||||
|
||||
/* receive related info: */
|
||||
uint32_t rx_desc_index; /**< index of the receive descriptor getting used*/
|
||||
uint8_t rx_buffers[RX_RING_SIZE][MSS_RX_BUFF_SIZE+4];/**< array of receive buffers*/
|
||||
// uint8_t rx_buffers[RX_RING_SIZE][MSS_RX_BUFF_SIZE+4];/**< array of receive buffers*/
|
||||
MAC_descriptor_t rx_descriptors[RX_RING_SIZE];/**< array of receive descriptors*/
|
||||
|
||||
uint8_t phy_address; /**< MII address of the connected PHY*/
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
/* The buffer used by the uIP stack to both receive and send. This points to
|
||||
one of the Ethernet buffers when its actually in use. */
|
||||
unsigned char *uip_buf = NULL;
|
||||
extern unsigned char *uip_buf;
|
||||
|
||||
static const unsigned char ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
|
||||
|
||||
|
@ -131,7 +131,6 @@ static void prvInitEmac( void );
|
|||
|
||||
void vEMACWrite( void );
|
||||
|
||||
unsigned long ulEMACRead( void );
|
||||
long lEMACWaitForLink( void );
|
||||
|
||||
/*
|
||||
|
@ -163,7 +162,7 @@ clock_time_t clock_time( void )
|
|||
|
||||
void vuIP_Task( void *pvParameters )
|
||||
{
|
||||
portBASE_TYPE i, xDoneSomething;
|
||||
portBASE_TYPE i;
|
||||
unsigned long ulNewEvent;
|
||||
|
||||
( void ) pvParameters;
|
||||
|
@ -176,47 +175,52 @@ unsigned long ulNewEvent;
|
|||
|
||||
for( ;; )
|
||||
{
|
||||
xDoneSomething = pdFALSE;
|
||||
|
||||
/* Is there received data ready to be processed? */
|
||||
uip_len = ( unsigned short ) ulEMACRead();
|
||||
|
||||
if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
|
||||
if( ( ulUIP_Events & uipETHERNET_TX_EVENT ) != 0UL )
|
||||
{
|
||||
/* Standard uIP loop taken from the uIP manual. */
|
||||
if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
|
||||
{
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
ulUIP_Events &= ~uipETHERNET_TX_EVENT;
|
||||
MSS_MAC_TxBufferCompleted();
|
||||
}
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if( uip_len > 0 )
|
||||
{
|
||||
uip_arp_out();
|
||||
vEMACWrite();
|
||||
}
|
||||
|
||||
xDoneSomething = pdTRUE;
|
||||
}
|
||||
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
|
||||
{
|
||||
uip_arp_arpin();
|
||||
if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL )
|
||||
{
|
||||
ulUIP_Events &= ~uipETHERNET_RX_EVENT;
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if( uip_len > 0 )
|
||||
/* Is there received data ready to be processed? */
|
||||
uip_len = MSS_MAC_rx_packet();
|
||||
|
||||
if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
|
||||
{
|
||||
/* Standard uIP loop taken from the uIP manual. */
|
||||
if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
|
||||
{
|
||||
vEMACWrite();
|
||||
uip_arp_ipin();
|
||||
uip_input();
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if( uip_len > 0 )
|
||||
{
|
||||
uip_arp_out();
|
||||
vEMACWrite();
|
||||
}
|
||||
}
|
||||
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
|
||||
{
|
||||
uip_arp_arpin();
|
||||
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if( uip_len > 0 )
|
||||
{
|
||||
vEMACWrite();
|
||||
}
|
||||
}
|
||||
|
||||
xDoneSomething = pdTRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL ) && ( uip_buf != NULL ) )
|
||||
if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )
|
||||
{
|
||||
ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;
|
||||
|
||||
|
@ -233,18 +237,16 @@ unsigned long ulNewEvent;
|
|||
vEMACWrite();
|
||||
}
|
||||
}
|
||||
|
||||
/* Call the ARP timer function every 10 seconds. */
|
||||
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
|
||||
{
|
||||
ulUIP_Events &= ~uipARP_TIMER_EVENT;
|
||||
uip_arp_timer();
|
||||
}
|
||||
|
||||
xDoneSomething = pdTRUE;
|
||||
}
|
||||
|
||||
if( xDoneSomething == pdFALSE )
|
||||
|
||||
/* Call the ARP timer function every 10 seconds. */
|
||||
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
|
||||
{
|
||||
ulUIP_Events &= ~uipARP_TIMER_EVENT;
|
||||
uip_arp_timer();
|
||||
}
|
||||
|
||||
if( ulUIP_Events == pdFALSE )
|
||||
{
|
||||
xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
|
||||
ulUIP_Events |= ulNewEvent;
|
||||
|
@ -359,14 +361,17 @@ unsigned long ulUIPEvents = 0UL;
|
|||
|
||||
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_SEND ) != 0UL )
|
||||
{
|
||||
/* Handle send event. */
|
||||
ulUIPEvents |= uipETHERNET_TX_EVENT;
|
||||
ulUIP_Events |= uipETHERNET_TX_EVENT;
|
||||
}
|
||||
|
||||
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_RECEIVED ) != 0UL )
|
||||
{
|
||||
/* Wake the uIP task as new data has arrived. */
|
||||
ulUIPEvents |= uipETHERNET_RX_EVENT;
|
||||
}
|
||||
|
||||
if( ulUIPEvents != 0UL )
|
||||
{
|
||||
xQueueSendFromISR( xEMACEventQueue, &ulUIPEvents, &lHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
|
@ -376,7 +381,6 @@ unsigned long ulUIPEvents = 0UL;
|
|||
|
||||
static void prvInitEmac( void )
|
||||
{
|
||||
unsigned long ulMACCfg;
|
||||
const unsigned char ucPHYAddress = 1;
|
||||
|
||||
MSS_MAC_init( ucPHYAddress );
|
||||
|
@ -391,13 +395,21 @@ const unsigned char ucPHYAddress = 1;
|
|||
|
||||
void vEMACWrite( void )
|
||||
{
|
||||
MSS_MAC_tx_packet( uip_buf, uip_len, 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
const long lMaxAttempts = 10;
|
||||
long lAttempt;
|
||||
const portTickType xShortDelay = ( 10 / portTICK_RATE_MS );
|
||||
|
||||
unsigned long ulEMACRead( void )
|
||||
{
|
||||
return MSS_MAC_rx_packet( &uip_buf, ( MSS_RX_BUFF_SIZE + 4 ), 0UL );
|
||||
for( lAttempt = 0; lAttempt < lMaxAttempts; lAttempt++ )
|
||||
{
|
||||
if( MSS_MAC_tx_packet( uip_len ) != 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
vTaskDelay( xShortDelay );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue