mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -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_TIME_OUT (-6)
|
||||||
#define MAC_TOO_SMALL_PACKET (-7)
|
#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;
|
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 MAC_instance_t* NULL_instance;
|
||||||
static uint8_t* NULL_buffer;
|
static uint8_t* NULL_buffer;
|
||||||
static MSS_MAC_callback_t NULL_callback;
|
static MSS_MAC_callback_t NULL_callback;
|
||||||
|
unsigned char *uip_buf = NULL;
|
||||||
|
|
||||||
/**************************** INTERNAL FUNCTIONS ******************************/
|
/**************************** 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_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n);
|
||||||
static void MAC_memset_All(MAC_instance_t *s, uint32_t c);
|
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.
|
* Initializes the Ethernet Controller.
|
||||||
* This function will prepare the Ethernet Controller for first time use in a
|
* 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 };
|
const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS };
|
||||||
int32_t a;
|
int32_t a;
|
||||||
|
|
||||||
|
/* To start with all buffers are free. */
|
||||||
|
for( a = 0; a < macNUM_BUFFERS; a++ )
|
||||||
|
{
|
||||||
|
ucMACBufferFree[ a ] = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to reset chip */
|
/* Try to reset chip */
|
||||||
MAC_BITBAND->CSR0_SWR = 1u;
|
MAC_BITBAND->CSR0_SWR = 1u;
|
||||||
|
|
||||||
|
@ -139,13 +166,19 @@ MSS_MAC_init
|
||||||
/* Give the ownership to the MAC */
|
/* Give the ownership to the MAC */
|
||||||
g_mss_mac.rx_descriptors[a].descriptor_0 = RDES0_OWN;
|
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].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;
|
g_mss_mac.rx_descriptors[RX_RING_SIZE-1].descriptor_1 |= RDES1_RER;
|
||||||
|
|
||||||
for( a = 0; a < TX_RING_SIZE; a++ )
|
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;
|
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
|
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
|
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.
|
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
|
This function will not wait for the transmission to complete.
|
||||||
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.
|
|
||||||
|
|
||||||
@return
|
@return
|
||||||
The function returns zero if a timeout occurs otherwise it returns size of the packet.
|
The function returns zero if a timeout occurs otherwise it returns size of the packet.
|
||||||
|
@ -378,86 +393,62 @@ MSS_MAC_get_configuration( void )
|
||||||
int32_t
|
int32_t
|
||||||
MSS_MAC_tx_packet
|
MSS_MAC_tx_packet
|
||||||
(
|
(
|
||||||
const uint8_t *pacData,
|
unsigned short usLength
|
||||||
uint16_t pacLen,
|
|
||||||
uint32_t time_out
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t desc;
|
uint32_t desc;
|
||||||
|
unsigned long ulDescriptor;
|
||||||
int32_t error = MAC_OK;
|
int32_t error = MAC_OK;
|
||||||
|
extern unsigned char *uip_buf;
|
||||||
|
|
||||||
ASSERT( MAC_test_instance() == MAC_OK );
|
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 )
|
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) ||
|
/* Check if second descriptor is free, if it is then the first must
|
||||||
(time_out == MSS_MAC_NONBLOCKING) ||
|
also be free. */
|
||||||
((time_out >= 1) && (time_out <= 0x01000000uL)) );
|
if(((g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN )
|
||||||
|
|
||||||
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;
|
error = MAC_BUFFER_IS_FULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( error == MAC_OK ) {
|
if( error == MAC_OK ) {
|
||||||
|
/* Assumed TX_RING_SIZE == 2. */
|
||||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u;
|
for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ )
|
||||||
|
{
|
||||||
|
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 = 0u;
|
||||||
|
|
||||||
if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
|
if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {
|
||||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC;
|
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_AC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Every buffer can hold a full frame so they are always first and last
|
/* Every buffer can hold a full frame so they are always first and last
|
||||||
descriptor */
|
descriptor */
|
||||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS;
|
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_LS | TDES1_FS;
|
||||||
|
|
||||||
/* set data size */
|
/* set data size */
|
||||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= pacLen;
|
g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= usLength;
|
||||||
|
|
||||||
/* reset end of ring */
|
/* reset end of ring */
|
||||||
g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
|
g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;
|
||||||
|
|
||||||
/* copy data into buffer */
|
if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
|
||||||
if( pacLen > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */
|
|
||||||
{
|
{
|
||||||
pacLen = (uint16_t)MSS_TX_BUFF_SIZE;
|
usLength = (uint16_t)MSS_TX_BUFF_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) pacData;
|
/* The data buffer is assigned to the Tx descriptor. */
|
||||||
|
g_mss_mac.tx_descriptors[ ulDescriptor ].buffer_1 = ( unsigned long ) uip_buf;
|
||||||
|
|
||||||
/* update counters */
|
/* update counters */
|
||||||
desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0;
|
desc = g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0;
|
||||||
if( (desc & TDES0_LO) != 0u ) {
|
if( (desc & TDES0_LO) != 0u ) {
|
||||||
g_mss_mac.statistics.tx_loss_of_carrier++;
|
g_mss_mac.statistics.tx_loss_of_carrier++;
|
||||||
}
|
}
|
||||||
|
@ -477,20 +468,26 @@ MSS_MAC_tx_packet
|
||||||
(desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;
|
(desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;
|
||||||
|
|
||||||
/* Give ownership of descriptor to the MAC */
|
/* 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_descriptors[ ulDescriptor ].descriptor_0 = TDES0_OWN;
|
||||||
|
|
||||||
g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE;
|
g_mss_mac.tx_desc_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Start transmission */
|
/* Start transmission */
|
||||||
MAC_start_transmission();
|
MAC_start_transmission();
|
||||||
|
|
||||||
/* transmit poll demand */
|
/* transmit poll demand */
|
||||||
MAC->CSR1 = 1u;
|
MAC->CSR1 = 1u;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (error == MAC_OK)
|
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
|
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
|
* 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
|
* places it into uip_buf.
|
||||||
* 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
|
* @return Size of packet if packet fits in uip_buf.
|
||||||
* 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.
|
|
||||||
* 0 if there is no received packet.
|
* 0 if there is no received packet.
|
||||||
* @see MAC_rx_pckt_size()
|
* @see MAC_rx_pckt_size()
|
||||||
* @see MAC_tx_packet()
|
* @see MAC_tx_packet()
|
||||||
|
@ -560,42 +544,16 @@ MSS_MAC_rx_pckt_size
|
||||||
int32_t
|
int32_t
|
||||||
MSS_MAC_rx_packet
|
MSS_MAC_rx_packet
|
||||||
(
|
(
|
||||||
unsigned char **pacData,
|
void
|
||||||
uint16_t pacLen,
|
|
||||||
uint32_t time_out
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint16_t frame_length=0u;
|
uint16_t frame_length=0u;
|
||||||
int8_t exit=0;
|
|
||||||
|
|
||||||
ASSERT( MAC_test_instance() == MAC_OK );
|
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();
|
MAC_dismiss_bad_frames();
|
||||||
|
|
||||||
/* wait for a packet */
|
if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) == 0u )
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
frame_length = ( (
|
frame_length = ( (
|
||||||
g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>
|
g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >>
|
||||||
|
@ -604,14 +562,21 @@ MSS_MAC_rx_packet
|
||||||
/* strip crc */
|
/* strip crc */
|
||||||
frame_length -= 4u;
|
frame_length -= 4u;
|
||||||
|
|
||||||
if( frame_length > pacLen ) {
|
if( frame_length > macBUFFER_SIZE ) {
|
||||||
return MAC_NOT_ENOUGH_SPACE;
|
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();
|
MSS_MAC_prepare_rx_descriptor();
|
||||||
|
|
||||||
}
|
}
|
||||||
return ((int32_t)frame_length);
|
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_address, (uint8_t)c, 6u );
|
||||||
MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );
|
MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );
|
||||||
s->phy_address = (uint8_t)c;
|
s->phy_address = (uint8_t)c;
|
||||||
for(count = 0; count<RX_RING_SIZE ;count++)
|
// for(count = 0; count<RX_RING_SIZE ;count++)
|
||||||
{
|
// {
|
||||||
MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
|
// MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );
|
||||||
}
|
// }
|
||||||
s->rx_desc_index =c;
|
s->rx_desc_index =c;
|
||||||
for(count = 0; count<RX_RING_SIZE ;count++)
|
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_no_carrier = c;
|
||||||
s->statistics.tx_underflow_error = c;
|
s->statistics.tx_underflow_error = c;
|
||||||
s->time_out_value = c;
|
s->time_out_value = c;
|
||||||
for(count = 0; count < TX_RING_SIZE ;count++)
|
// for(count = 0; count < TX_RING_SIZE ;count++)
|
||||||
{
|
// {
|
||||||
MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );
|
// MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );
|
||||||
}
|
// }
|
||||||
s->tx_desc_index = c;
|
s->tx_desc_index = c;
|
||||||
for(count = 0; count < TX_RING_SIZE ;count++)
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -342,37 +342,26 @@ MSS_MAC_get_configuration
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* Sends a packet to the Ethernet Controller.
|
Sends a packet from the uIP stack to the Ethernet Controller.
|
||||||
* This function writes pacLen bytes of the packet contained in pacData into the
|
The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet
|
||||||
* transmit FIFO of the controller and then activates the transmitter for this
|
MAC. This function writes uip_len bytes of the packet contained in uip_buf into
|
||||||
* packet. If space is available in FIFO, the function will return once lBufLen
|
the transmit FIFO and then activates the transmitter for this packet. If space
|
||||||
* bytes of the packet have been placed into the FIFO and the transmitter has been
|
is available in the FIFO, the function will return once pac_len bytes of the
|
||||||
* started. The function will not wait for the transmission to complete. If space
|
packet have been placed into the FIFO and the transmitter has been started.
|
||||||
* is not available in FIFO, the function will keep trying till time_out expires,
|
This function will not wait for the transmission to complete.
|
||||||
* if MSS_MAC_BLOCKING value is given as time_out, function will wait for the
|
|
||||||
* transmission to complete.
|
@return
|
||||||
*
|
The function returns zero if a timeout occurs otherwise it returns size of the packet.
|
||||||
* @param pacData the pointer to the packet data to be transmitted.
|
|
||||||
* @param pacLen number of bytes in the packet to be transmitted.
|
@see MAC_rx_packet()
|
||||||
* @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()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
MSS_MAC_tx_packet
|
MSS_MAC_tx_packet
|
||||||
(
|
(
|
||||||
const uint8_t *pacData,
|
unsigned short usLength
|
||||||
uint16_t pacLen,
|
|
||||||
uint32_t time_out
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* Returns available packet's size.
|
* 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
|
* 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
|
* places it into uip_buf.
|
||||||
* 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
|
* @return Size of packet if packet fits in uip_buf.
|
||||||
* 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.
|
|
||||||
* 0 if there is no received packet.
|
* 0 if there is no received packet.
|
||||||
* @see MAC_rx_pckt_size()
|
* @see MAC_rx_pckt_size()
|
||||||
* @see MAC_tx_packet()
|
* @see MAC_tx_packet()
|
||||||
|
@ -427,9 +402,7 @@ MSS_MAC_prepare_rx_descriptor
|
||||||
int32_t
|
int32_t
|
||||||
MSS_MAC_rx_packet
|
MSS_MAC_rx_packet
|
||||||
(
|
(
|
||||||
uint8_t **pacData,
|
void
|
||||||
uint16_t pacLen,
|
|
||||||
uint32_t time_out
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -587,6 +560,23 @@ MSS_MAC_get_statistics
|
||||||
mss_mac_statistics_id_t stat_id
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,12 +65,12 @@ typedef struct {
|
||||||
|
|
||||||
/* transmit related info: */
|
/* transmit related info: */
|
||||||
uint32_t tx_desc_index; /**< index of the transmit descriptor getting used*/
|
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*/
|
MAC_descriptor_t tx_descriptors[TX_RING_SIZE];/**< array of transmit descriptors*/
|
||||||
|
|
||||||
/* receive related info: */
|
/* receive related info: */
|
||||||
uint32_t rx_desc_index; /**< index of the receive descriptor getting used*/
|
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*/
|
MAC_descriptor_t rx_descriptors[RX_RING_SIZE];/**< array of receive descriptors*/
|
||||||
|
|
||||||
uint8_t phy_address; /**< MII address of the connected PHY*/
|
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
|
/* 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. */
|
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 };
|
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 );
|
void vEMACWrite( void );
|
||||||
|
|
||||||
unsigned long ulEMACRead( void );
|
|
||||||
long lEMACWaitForLink( void );
|
long lEMACWaitForLink( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,7 +162,7 @@ clock_time_t clock_time( void )
|
||||||
|
|
||||||
void vuIP_Task( void *pvParameters )
|
void vuIP_Task( void *pvParameters )
|
||||||
{
|
{
|
||||||
portBASE_TYPE i, xDoneSomething;
|
portBASE_TYPE i;
|
||||||
unsigned long ulNewEvent;
|
unsigned long ulNewEvent;
|
||||||
|
|
||||||
( void ) pvParameters;
|
( void ) pvParameters;
|
||||||
|
@ -176,10 +175,18 @@ unsigned long ulNewEvent;
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
xDoneSomething = pdFALSE;
|
if( ( ulUIP_Events & uipETHERNET_TX_EVENT ) != 0UL )
|
||||||
|
{
|
||||||
|
ulUIP_Events &= ~uipETHERNET_TX_EVENT;
|
||||||
|
MSS_MAC_TxBufferCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL )
|
||||||
|
{
|
||||||
|
ulUIP_Events &= ~uipETHERNET_RX_EVENT;
|
||||||
|
|
||||||
/* Is there received data ready to be processed? */
|
/* Is there received data ready to be processed? */
|
||||||
uip_len = ( unsigned short ) ulEMACRead();
|
uip_len = MSS_MAC_rx_packet();
|
||||||
|
|
||||||
if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
|
if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
|
||||||
{
|
{
|
||||||
|
@ -197,8 +204,6 @@ unsigned long ulNewEvent;
|
||||||
uip_arp_out();
|
uip_arp_out();
|
||||||
vEMACWrite();
|
vEMACWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
xDoneSomething = pdTRUE;
|
|
||||||
}
|
}
|
||||||
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
|
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
|
||||||
{
|
{
|
||||||
|
@ -211,12 +216,11 @@ unsigned long ulNewEvent;
|
||||||
{
|
{
|
||||||
vEMACWrite();
|
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;
|
ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;
|
||||||
|
|
||||||
|
@ -233,6 +237,7 @@ unsigned long ulNewEvent;
|
||||||
vEMACWrite();
|
vEMACWrite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Call the ARP timer function every 10 seconds. */
|
/* Call the ARP timer function every 10 seconds. */
|
||||||
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
|
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
|
||||||
|
@ -241,10 +246,7 @@ unsigned long ulNewEvent;
|
||||||
uip_arp_timer();
|
uip_arp_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
xDoneSomething = pdTRUE;
|
if( ulUIP_Events == pdFALSE )
|
||||||
}
|
|
||||||
|
|
||||||
if( xDoneSomething == pdFALSE )
|
|
||||||
{
|
{
|
||||||
xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
|
xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
|
||||||
ulUIP_Events |= ulNewEvent;
|
ulUIP_Events |= ulNewEvent;
|
||||||
|
@ -359,14 +361,17 @@ unsigned long ulUIPEvents = 0UL;
|
||||||
|
|
||||||
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_SEND ) != 0UL )
|
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_SEND ) != 0UL )
|
||||||
{
|
{
|
||||||
/* Handle send event. */
|
ulUIP_Events |= uipETHERNET_TX_EVENT;
|
||||||
ulUIPEvents |= uipETHERNET_TX_EVENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_RECEIVED ) != 0UL )
|
if( ( ulISREvents & MSS_MAC_EVENT_PACKET_RECEIVED ) != 0UL )
|
||||||
{
|
{
|
||||||
/* Wake the uIP task as new data has arrived. */
|
/* Wake the uIP task as new data has arrived. */
|
||||||
ulUIPEvents |= uipETHERNET_RX_EVENT;
|
ulUIPEvents |= uipETHERNET_RX_EVENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulUIPEvents != 0UL )
|
||||||
|
{
|
||||||
xQueueSendFromISR( xEMACEventQueue, &ulUIPEvents, &lHigherPriorityTaskWoken );
|
xQueueSendFromISR( xEMACEventQueue, &ulUIPEvents, &lHigherPriorityTaskWoken );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +381,6 @@ unsigned long ulUIPEvents = 0UL;
|
||||||
|
|
||||||
static void prvInitEmac( void )
|
static void prvInitEmac( void )
|
||||||
{
|
{
|
||||||
unsigned long ulMACCfg;
|
|
||||||
const unsigned char ucPHYAddress = 1;
|
const unsigned char ucPHYAddress = 1;
|
||||||
|
|
||||||
MSS_MAC_init( ucPHYAddress );
|
MSS_MAC_init( ucPHYAddress );
|
||||||
|
@ -391,13 +395,21 @@ const unsigned char ucPHYAddress = 1;
|
||||||
|
|
||||||
void vEMACWrite( void )
|
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 )
|
for( lAttempt = 0; lAttempt < lMaxAttempts; lAttempt++ )
|
||||||
{
|
{
|
||||||
return MSS_MAC_rx_packet( &uip_buf, ( MSS_RX_BUFF_SIZE + 4 ), 0UL );
|
if( MSS_MAC_tx_packet( uip_len ) != 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTaskDelay( xShortDelay );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue