]> git.sur5r.net Git - freertos/commitdiff
Continue work on the SmartFusion demo web interface. The uIP task has been updated...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 17 Apr 2011 14:38:50 +0000 (14:38 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 17 Apr 2011 14:38:50 +0000 (14:38 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1363 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/phy.c
Demo/CORTEX_A2F200_SoftConsole/main-full.c
Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c

index 42214d835cfd991d370e317359903e0494dca330..014ce512ceb57f7bb89a2a1f84c5f38f5223f0ba 100644 (file)
@@ -14,6 +14,7 @@ extern "C" {
 #endif \r
 \r
 #include "FreeRTOS.h"\r
+#include "task.h"\r
 \r
 #include "crc32.h"\r
 \r
@@ -111,16 +112,15 @@ MSS_MAC_init
 )\r
 {\r
     const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS };\r
-\r
     int32_t a;\r
 \r
     /* Try to reset chip */\r
     MAC_BITBAND->CSR0_SWR = 1u;\r
-    \r
-    while ( 1u == MAC_BITBAND->CSR0_SWR )\r
+\r
+    do\r
     {\r
-        ;\r
-    }\r
+       vTaskDelay( 10 );\r
+    } while ( 1u == MAC_BITBAND->CSR0_SWR );\r
 \r
     /* Check reset values of some registers to constrol\r
      * base address validity */\r
@@ -145,7 +145,7 @@ MSS_MAC_init
 \r
     for( a = 0; a < TX_RING_SIZE; a++ )\r
     {\r
-        g_mss_mac.tx_descriptors[a].buffer_1 = (uint32_t)g_mss_mac.tx_buffers[a];\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
     }\r
     g_mss_mac.tx_descriptors[TX_RING_SIZE - 1].descriptor_1 |= TDES1_TER;\r
 \r
@@ -197,11 +197,7 @@ MSS_MAC_init
     /* Set default MAC address and reset mac filters */\r
        MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u );\r
        MSS_MAC_set_mac_filters( 0u, NULL_buffer );\r
-\r
-\r
-    /* Start receiving and transmission */\r
-    MAC_start_receiving();\r
-    MAC_start_transmission();\r
+       MAC_BITBAND->CSR6_RA = 1; /* Receive all. */\r
 }\r
 \r
 \r
@@ -266,9 +262,6 @@ MSS_MAC_configure
         ((((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? MSS_MAC_LINK_STATUS_100MB : 0u ) |\r
         (((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? MSS_MAC_LINK_STATUS_FDX : 0u )) );\r
 \r
-    MAC_start_transmission();\r
-    MAC_start_receiving();\r
-\r
     MSS_MAC_auto_setup_link();\r
 }\r
 \r
@@ -460,10 +453,8 @@ MSS_MAC_tx_packet
         {\r
                pacLen = (uint16_t)MSS_TX_BUFF_SIZE;\r
         }\r
-        MAC_memcpy(\r
-               (uint8_t*)\r
-               g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1,\r
-               pacData, (uint32_t)pacLen );\r
+\r
+        g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) pacData;\r
 \r
         /* update counters */\r
         desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0;\r
index dd1ca43b59ad46d75058f06a6b6f37fcbf5a486c..9fb08984a6874e3a0c521cbc37b195c7a706807d 100644 (file)
@@ -20,6 +20,9 @@ extern "C" {
 \r
 #include "phy.h"\r
 \r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
 extern MAC_instance_t g_mss_mac;\r
 \r
 /***************************** MDIO FUNCTIONS *********************************/\r
@@ -267,7 +270,6 @@ void PHY_auto_negotiate( void )
 {\r
        int32_t a;\r
        uint16_t reg;\r
-    int32_t exit = 1;\r
 \r
        reg = MDIO_read( PHYREG_MIIMCR );\r
        MDIO_write( PHYREG_MIIMCR,\r
@@ -275,10 +277,12 @@ void PHY_auto_negotiate( void )
                MIIMCR_RESTART_AUTONEGOTIATION |\r
                reg) );\r
 \r
-       for(a=0; (a<1000) && (exit); a++) {\r
+       for( ;; ) {\r
                reg = MDIO_read( PHYREG_MIIMSR );\r
                if( (reg & MIIMSR_ANC) != 0 ) {\r
-                       exit = 0;\r
+                       break;\r
+               } else {\r
+                       vTaskDelay( 200 );\r
                }\r
        }\r
 }\r
index 06e48c471a412edf50bf43787882519b7bd5e0ff..0fcf0704642abe0c44124476f1169c84f653cfdc 100644 (file)
@@ -445,10 +445,6 @@ static void prvSetupHardware( void )
     NVIC_EnableIRQ( GPIO8_IRQn );\r
     MSS_GPIO_config( MSS_GPIO_8, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_NEGATIVE );\r
     MSS_GPIO_enable_irq( MSS_GPIO_8 );\r
-\r
-    /* Setup the EMAC and the NVIC for MAC interrupts. */\r
-    NVIC_SetPriority( EthernetMAC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );\r
-    NVIC_EnableIRQ( EthernetMAC_IRQn );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index 73ed4eefe761a2468ebe8f15b857bc67071aef0e..41c4b02a72d71b177afafccbd1a21ffbed1e7b66 100644 (file)
@@ -57,7 +57,8 @@
 /* Scheduler includes. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
-#include "semphr.h"\r
+#include "queue.h"\r
+#include "timers.h"\r
 \r
 /* uip includes. */\r
 #include "net/uip.h"\r
 /* Demo includes. */\r
 #include "ParTest.h"\r
 \r
-#include "EMAC.h"\r
+/* Hardware driver includes. */\r
+#include "mss_ethernet_mac_regs.h"\r
+#include "mss_ethernet_mac.h"\r
+\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
+\r
+static const unsigned char ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };\r
+\r
+#define uipARP_TIMER                           0\r
+#define uipPERIODIC_TIMER                      1\r
+\r
+#define uipEVENT_QUEUE_LENGTH          10\r
+\r
+#define uipETHERNET_RX_EVENT           0x01UL\r
+#define        uipETHERNET_TX_EVENT            0x02UL\r
+#define uipARP_TIMER_EVENT                     0x04UL\r
+#define uipPERIODIC_TIMER_EVENT                0x08UL\r
+#define uipAPPLICATION_SEND_EVENT      0x10UL\r
+\r
+#define uipDONT_BLOCK                          0UL\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
  */\r
 static void prvSetMACAddress( void );\r
 \r
+/*\r
+ * Perform any uIP initialisation required to ready the stack for http\r
+ * processing.
+ */\r
+static void prvInitialise_uIP( void );\r
+\r
+/*\r
+ * Handles Ethernet interrupt events.
+ */\r
+static void prvEMACEventListener( unsigned long ulISREvents );\r
+\r
+static void prvUIPTimerCallback( xTimerHandle xTimer );\r
+\r
+/*\r
+ * Initialise the MAC hardware.
+ */\r
+static void prvInitEmac( void );\r
+\r
+void vEMACWrite( void );\r
+\r
+unsigned long ulEMACRead( void );\r
+long lEMACWaitForLink( void );\r
+\r
 /*\r
  * Port functions required by the uIP stack.\r
  */\r
@@ -97,8 +142,10 @@ clock_time_t clock_time( void );
 \r
 /*-----------------------------------------------------------*/\r
 \r
-/* The semaphore used by the ISR to wake the uIP task. */\r
-xSemaphoreHandle xEMACSemaphore = NULL;\r
+/* The queue used to send TCP/IP events to the uIP stack. */\r
+xQueueHandle xEMACEventQueue = NULL;\r
+\r
+static unsigned long ulUIP_Events = 0UL;\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -117,32 +164,15 @@ clock_time_t clock_time( void )
 void vuIP_Task( void *pvParameters )\r
 {\r
 portBASE_TYPE i, xDoneSomething;\r
-uip_ipaddr_t xIPAddr;\r
-struct timer periodic_timer, arp_timer;\r
+unsigned long ulNewEvent;\r
 \r
        ( void ) pvParameters;\r
 \r
-       /* Initialise the uIP stack. */\r
-       timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );\r
-       timer_set( &arp_timer, configTICK_RATE_HZ * 10 );\r
-       uip_init();\r
-       uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
-       uip_sethostaddr( &xIPAddr );\r
-       uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );\r
-       uip_setnetmask( &xIPAddr );\r
-       prvSetMACAddress();\r
-       httpd_init();\r
-\r
-       /* Create the semaphore used to wake the uIP task. */\r
-       vSemaphoreCreateBinary( xEMACSemaphore );\r
+       /* Initialise the uIP stack, configuring for web server usage. */\r
+       prvInitialise_uIP();\r
 \r
        /* Initialise the MAC. */\r
-       vInitEmac();\r
-\r
-       while( lEMACWaitForLink() != pdPASS )\r
-    {\r
-        vTaskDelay( uipINIT_WAIT );\r
-    }\r
+       prvInitEmac();\r
 \r
        for( ;; )\r
        {\r
@@ -186,9 +216,10 @@ struct timer periodic_timer, arp_timer;
                        }\r
                }\r
 \r
-               if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )\r
+               if( ( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL ) && ( uip_buf != NULL ) )\r
                {\r
-                       timer_reset( &periodic_timer );\r
+                       ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;\r
+\r
                        for( i = 0; i < UIP_CONNS; i++ )\r
                        {\r
                                uip_periodic( i );\r
@@ -204,9 +235,9 @@ struct timer periodic_timer, arp_timer;
                        }\r
 \r
                        /* Call the ARP timer function every 10 seconds. */\r
-                       if( timer_expired( &arp_timer ) )\r
+                       if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )\r
                        {\r
-                               timer_reset( &arp_timer );\r
+                               ulUIP_Events &= ~uipARP_TIMER_EVENT;\r
                                uip_arp_timer();\r
                        }\r
                        \r
@@ -215,11 +246,8 @@ struct timer periodic_timer, arp_timer;
                \r
                if( xDoneSomething == pdFALSE )\r
                {\r
-                       /* We did not receive a packet, and there was no periodic\r
-                       processing to perform.  Block for a fixed period.  If a packet\r
-                       is received during this period we will be woken by the ISR\r
-                       giving us the Semaphore. */\r
-                       xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 20 );\r
+                       xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );\r
+                       ulUIP_Events |= ulNewEvent;\r
                }\r
        }\r
 }\r
@@ -281,4 +309,130 @@ char *c;
                }\r
        }\r
 }\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitialise_uIP( void )\r
+{\r
+uip_ipaddr_t xIPAddr;\r
+xTimerHandle xARPTimer, xPeriodicTimer;\r
+\r
+       uip_init();\r
+       uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );\r
+       uip_sethostaddr( &xIPAddr );\r
+       uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );\r
+       uip_setnetmask( &xIPAddr );\r
+       prvSetMACAddress();\r
+       httpd_init();\r
+\r
+       /* Create the queue used to sent TCP/IP events to the uIP stack. */\r
+       xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) );\r
+\r
+       /* Create and start the uIP timers. */\r
+       xARPTimer = xTimerCreate(       ( const signed char * const ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */\r
+                                                               ( 500 / portTICK_RATE_MS ), /* Timer period. */\r
+                                                               pdTRUE, /* Autor-reload. */\r
+                                                               ( void * ) uipARP_TIMER,\r
+                                                               prvUIPTimerCallback\r
+                                                       );\r
+\r
+       xPeriodicTimer = xTimerCreate(  ( const signed char * const ) "PeriodicTimer",\r
+                                                                       ( 5000 / portTICK_RATE_MS ),\r
+                                                                       pdTRUE, /* Autor-reload. */\r
+                                                                       ( void * ) uipPERIODIC_TIMER,\r
+                                                                       prvUIPTimerCallback\r
+                                                               );\r
+\r
+       configASSERT( xARPTimer );\r
+       configASSERT( xPeriodicTimer );\r
+\r
+       xTimerStart( xARPTimer, portMAX_DELAY );\r
+       xTimerStart( xPeriodicTimer, portMAX_DELAY );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvEMACEventListener( unsigned long ulISREvents )\r
+{\r
+long lHigherPriorityTaskWoken = pdFALSE;\r
+unsigned long ulUIPEvents = 0UL;\r
+\r
+       configASSERT( xEMACEventQueue );\r
+\r
+       if( ( ulISREvents & MSS_MAC_EVENT_PACKET_SEND ) != 0UL )\r
+       {\r
+               /* Handle send event. */\r
+               ulUIPEvents |= 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
+               xQueueSendFromISR( xEMACEventQueue, &ulUIPEvents, &lHigherPriorityTaskWoken );\r
+       }\r
+\r
+       portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitEmac( void )\r
+{\r
+unsigned long ulMACCfg;\r
+const unsigned char ucPHYAddress = 1;\r
+\r
+       MSS_MAC_init( ucPHYAddress );\r
+\r
+       MSS_MAC_set_callback( prvEMACEventListener );\r
+\r
+    /* Setup the EMAC and the NVIC for MAC interrupts. */\r
+    NVIC_SetPriority( EthernetMAC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );\r
+    NVIC_EnableIRQ( EthernetMAC_IRQn );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vEMACWrite( void )\r
+{\r
+       MSS_MAC_tx_packet( uip_buf, uip_len, 0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulEMACRead( void )\r
+{\r
+       return MSS_MAC_rx_packet( &uip_buf, ( MSS_RX_BUFF_SIZE + 4 ), 0UL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+long lEMACWaitForLink( void )\r
+{\r
+long lReturn = pdFAIL;\r
+unsigned long ulStatus;\r
+\r
+       ulStatus = MSS_MAC_link_status();\r
+       if( ( ulStatus & ( unsigned long ) MSS_MAC_LINK_STATUS_LINK ) != 0UL )\r
+       {\r
+               lReturn = pdPASS;\r
+       }\r
+\r
+       return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
+static void prvUIPTimerCallback( xTimerHandle xTimer )\r
+{\r
+static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;\r
+static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;\r
+\r
+       /* This is a time callback, so calls to xQueueSend() must not attempt to\r
+       block. */\r
+       switch( ( int ) pvTimerGetTimerID( xTimer ) )\r
+       {\r
+               case uipARP_TIMER               :       xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );\r
+                                                                       break;\r
+\r
+               case uipPERIODIC_TIMER  :       xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );\r
+                                                                       break;\r
+\r
+               default                                 :       /* Should not get here. */\r
+                                                                       break;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r