]> git.sur5r.net Git - freertos/commitdiff
Continue work on the SmartFusion web server demo.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 18 Apr 2011 18:11:03 +0000 (18:11 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 18 Apr 2011 18:11:03 +0000 (18:11 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1365 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h
Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h
Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c

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