]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/commitdiff
Temporary
authorJan Dolezal <pm.jenik@gmail.com>
Thu, 8 Aug 2013 13:54:07 +0000 (15:54 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 8 Aug 2013 14:58:34 +0000 (16:58 +0200)
rpp/include/rpp/eth.h
rpp/include/rpp/rpp.h
rpp/include/rpp/sci.h
rpp/src/rpp/eth.c
rpp/src/rpp/sci.c

index 835e035e2d6e48b9241a9309da8453e6fd3cf610..c920601a57e359e3a4659ef9d041c7ea9327cd01 100644 (file)
@@ -58,6 +58,7 @@ int8_t rpp_eth_init();
  *
  * @param instNum number of EMAC instance
  * @param macArray address assigned to link layer - when NULL RPP_MAC_ADDR is used
+ * @param waitTicksForPHYAneg maximum amount of ticks it will wait for autonegotiation
  *
  * @return SUCCESS if init successful.
  *         NETIF_ADD_ERR if lwip netif was not succesfully initialized or on low hw init error.
index 4ef66ca8593fc1f579699b85fbc923fb6181824e..a172a5f222152bc5cc7baf5adf90bbbf99dcf2e8 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef __RPP_RPP_H
 #define __RPP_RPP_H
 
+extern void rpp_printf(const char* string, ...);
+
 /* Base includes */
 #include "base.h"
 
index a716cac02b9f690b3e14a3812b8c16a5d74ad75d..9cca71238bb036f9f8247247aa7967f907f77390 100644 (file)
@@ -179,6 +179,7 @@ int8_t rpp_sci_flush(boolean_t buff);
  *          completely written.
  */
 int32_t rpp_sci_printf(const char* format, ...);
+int32_t __rpp_sci_printf(const char* format, va_list args);
 
 
 /**
index 43379050b7e0d70f8bad3fd8c58dc1738e1c932d..c9d1437fe32d2ab01a285239654cfc92909d8db6 100644 (file)
 
 #define MAX_TRANSFER_UNIT         1500 /* take in account oversized frames */
 #define PBUF_LEN_MAX              MAX_TRANSFER_UNIT
-#define MAX_RX_PBUF_ALLOC         10
+#define MAX_RX_PBUF_ALLOC         15 /* no need to limit it here -> better to do it in lwipopts.h */
 #define MIN_PKT_LEN               60
 
 /* Define those to better describe the network interface. */
@@ -222,6 +222,7 @@ struct hdkif {
   struct rxch rxch;
 #if !NO_SYS
   sys_sem_t goRX;
+  uint32_t waitTicksForPHYAneg;
 #endif
 };
 
@@ -406,7 +407,7 @@ int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
     if(postInitialized) {
         return FAILURE;
     }
-
+    int8_t retVal = SUCCESS;
     struct netif *netif = &hdkNetIF[instNum];
     u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
 
@@ -453,52 +454,61 @@ int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
 
     netif_set_default(netif);
 
-#if !NO_SYS
     hdkif = (struct hdkif *) netif->state;
+#if !NO_SYS
     /* ----- freeRTOS elements ----- */
     /* TODO: rewrite these to functions from sys_arch.* for compatibility with other systems then freeRTOS */
     /* semaphore blocking receive task (rpp_eth_recv_raw) from receive operation, till RX interrupt occurs and notify it */
     vSemaphoreCreateBinary(hdkif->goRX);
     /* run task rpp_eth_recv_raw */
-    xTaskCreate( rpp_eth_recv_raw, "RXHandler", 500, netif, 1, NULL );
+    xTaskCreate( rpp_eth_recv_raw, "RXHandler", 500, netif, 0, NULL );
     /* ----- end - freeRTOS ----- */
 #endif /* !NO_SYS */
 
+    if(rpp_eth_linkstat(hdkif->inst_num))
+    {
+       rpp_sci_printf((const char *)"cable connected\r\n");
 #if STATIC_IP_ADDRESS
-    netif_set_up(netif);
+       netif_set_up(netif);
 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
-    if(dhcp_start(netif) != ERR_OK)
-    {
+       if(dhcp_start(netif) != ERR_OK)
+       {
 #ifdef DEBUG
-       rpp_sci_printf((const char *) "dhcp mem err\r\n");
+               rpp_sci_printf((const char *) "dhcp mem err\r\n");
 #endif
-       return DHCP_MEM_ERR;
-    }
+               return DHCP_MEM_ERR;
+       }
 #ifdef DEBUG
-    rpp_sci_printf((const char *) "binding DHCP\r");
+       rpp_sci_printf((const char *) "binding DHCP\r");
 #endif
-    while((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--));
+       while((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--));
 #ifdef DEBUG
-    if(!dhcpBindWait)
-       rpp_sci_printf((const char *) "dhcp binding timeout...\r\n");
+       if(!dhcpBindWait)
+               rpp_sci_printf((const char *) "dhcp binding timeout...\r\n");
 #endif
 #else /* LWIP_DHCP-LWIP_AUTOIP FIXME: there should be some kind of waiting till ip is assigned */
-    autoip_start(netif);
+       autoip_start(netif);
 #endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
-#ifdef DEBUG/*
-    rpp_sci_printf((const char *) "Address: ");
-    rpp_eth_printIPDecimal(netif->ip_addr);
-    rpp_sci_printf((const char *) "\r\nNetmask: ");
-    rpp_eth_printIPDecimal(netif->netmask);
-    rpp_sci_printf((const char *) "\r\nGateway: ");
-    rpp_eth_printIPDecimal(netif->gw);
-    rpp_sci_printf((const char *) "\r\n");*/
-    /* rpp_eth_print_IPAddr(instNum); */
+#ifdef DEBUG
+       rpp_sci_printf((const char *) "Address: ");
+       rpp_eth_printIPDecimal(netif->ip_addr);
+       rpp_sci_printf((const char *) "\r\nNetmask: ");
+       rpp_eth_printIPDecimal(netif->netmask);
+       rpp_sci_printf((const char *) "\r\nGateway: ");
+       rpp_eth_printIPDecimal(netif->gw);
+       rpp_sci_printf((const char *) "\r\n");
+       /* rpp_eth_print_IPAddr(instNum); */
 #endif
+    }
+    else
+    {
+       rpp_sci_printf((const char *)"cable not connected\r\n");
+        retVal = PHY_LINK_DOWN;
+    }
     /* ----- end - lwIP stuff ----- */
 
     postInitialized = TRUE;
-       return SUCCESS;
+       return retVal;
 }
 
 err_t rpp_eth_lwip_init(struct netif *netif)
@@ -512,11 +522,15 @@ err_t rpp_eth_lwip_init(struct netif *netif)
     /*netif->num = instNum; - auto-initiated when netif_add is called */
 
     /* netif->state contained instNum, we replace it with corresponding hdkif */
-    netif->state = &hdkif_data[instNum];
+    struct hdkif *hdkif = &hdkif_data[instNum];
+    netif->state = hdkif;
 
     netif->name[0] = IFNAME0;
     netif->name[1] = IFNAME1;
 
+
+    hdkif->waitTicksForPHYAneg = 4000;
+
     /*
      * Initialize the snmp variables and counters inside the struct netif.
      * The last argument should be replaced with your link speed, in units
@@ -524,7 +538,6 @@ err_t rpp_eth_lwip_init(struct netif *netif)
     */
     NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
 
-    netif->input = ethernet_input;
     /* We directly use etharp_output() here to save a function call.
      * You can instead declare yo_SKIP_TO_HWur own function an call etharp_output()
      * from it if you have to do some checks before sending (e.g. if link
@@ -627,6 +640,7 @@ err_t rpp_eth_hw_init(struct hdkif *hdkif)
 
 err_t rpp_eth_hw_init_postInit(struct netif *netif)
 {
+       volatile unsigned int autonegFinishWait = 0x3FFFFFFF; /* for 80MHz aproximately 13s */
     uint16_t regContent;
     uint32_t num_bd, pbuf_cnt = 0;
     volatile struct emac_tx_bd *curr_txbd, *last_txbd;
@@ -671,7 +685,7 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
        rxch->active_head = (volatile struct emac_rx_bd*)(curr_txbd);
        rxch->free_head = NULL;
        rxch->freed_pbuf_len = 0;
-       num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd));
+       num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd)); /* when using 20B emac_bd structs, u can allocate one more ;) (405 together rx and tx and there is still 12 bytes remaining) */
        curr_rxbd = rxch->active_head;
        last_rxbd = curr_rxbd;
 
@@ -681,7 +695,6 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
        */
        while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {
            p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
-           pbuf_cnt++;
 
            if(p != NULL) {
                /* write the descriptors if there are enough numbers to hold the pbuf*/
@@ -703,21 +716,28 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
                /* free the allocated pbuf if no free descriptors are left */
                else {
                    pbuf_free(p);
-                       pbuf_cnt--;
                    break;
                }
            }
            else {
-               pbuf_cnt--;
                break;
            }
+           pbuf_cnt++;
        }
 
        last_rxbd->next = NULL;
+#ifdef DEBUG
+       rpp_sci_printf((const char *) "last_rxbd: 0x%x\r\n",last_rxbd);
+#endif
        rxch->active_tail = last_rxbd;
+       num_bd = (((uint32_t)rxch->active_tail - (uint32_t)rxch->active_head) / sizeof(struct emac_rx_bd) + 1);
+#ifdef DEBUG
+       rpp_sci_printf((const char *) "num of filled bds: %d\r\nnum of pbufs: %d\r\n", num_bd, pbuf_cnt);
+#endif
+
 
        /* for flow control - there could be set an interrupt when we reach preset amount of receive descriptors remaining - see RXBUFFERFLOWEN */
-       EMACNumFreeBufSet(hdkif->emac_base, CHANNEL, pbuf_cnt);
+       EMACNumFreeBufSet(hdkif->emac_base, CHANNEL, num_bd);
 
        /* set header descriptor pointers - this shows EMAC which descriptor is beginning one for writing received frames/packets  */
        EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32_t)rxch->active_head, CHANNEL);
@@ -750,11 +770,19 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
     for (regContent = 0; regContent < 8; regContent++) /* i..channel_number */
        EMACMACAddrSet(hdkif->emac_base, regContent, hdkif->mac_addr, EMAC_MACADDR_NO_MATCH_NO_FILTER);
 
-    /* wait for autonegotiation to be done - FIXME: add waitTicks type waiting */
-    while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE);
+    /* wait for autonegotiation to be done - XXX: autoneg still don't have to be done, you need to check if LINK is up in user app, using eth api fnc or netif api fnc */
+#if !NO_SYS
+    uint32_t timeToWake = hdkif->waitTicksForPHYAneg + sys_jiffies();
+    while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE && timeToWake > sys_jiffies())vTaskDelay(20); /* XXX: if init is not done at the startup, this might cause troubles */
+#else
+    while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE && autonegFinishWait--); /* wait till aneg done */
+#endif
 
 #ifdef DEBUG
-    rpp_sci_printf((const char *) "aneg finished \r\n");
+    if(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) != FALSE)
+       rpp_sci_printf((const char *) "aneg finished \r\n");
+    else
+       rpp_sci_printf((const char *) "aneg timeout \r\n");
 #endif
 
     /* check if phy link is up - it is when autoneg was completed succesfully */
@@ -792,6 +820,7 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
 
 err_t rpp_eth_send(struct netif * netif, struct pbuf *p)
 {
+       err_t retVal = SUCCESS;
        SYS_ARCH_DECL_PROTECT(lev);
 
        /**
@@ -815,12 +844,12 @@ err_t rpp_eth_send(struct netif * netif, struct pbuf *p)
        pbuf_ref(p);
 
        /* call the actual transmit function */
-       rpp_eth_send_raw(netif, p);
+       retVal = rpp_eth_send_raw(netif, p);
 
        /* Return to prior interrupt state and return. */
        SYS_ARCH_UNPROTECT(lev);
 
-       return SUCCESS;
+       return retVal;
 }
 
 err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p)
@@ -829,6 +858,7 @@ err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p)
        volatile struct emac_tx_bd *curr_bd, *active_head, *bd_end;
        struct hdkif *hdkif;
        struct txch *txch;
+       err_t retVal = SUCCESS;
 
     hdkif = (struct hdkif *) netif->state;
        txch = &(hdkif->txch);
@@ -886,7 +916,7 @@ err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p)
 
        txch->active_tail = bd_end;
 
-       return SUCCESS;
+       return retVal;
 }
 
 void rpp_eth_recv_raw(void *arg)
@@ -904,6 +934,8 @@ void rpp_eth_recv_raw(void *arg)
     for(;;)
     {
        sys_arch_sem_wait(&(hdkif->goRX), 0);
+       /* TODO: this place is candidate for LINKINT polling (if not solved through interrupt later) */
+       //xSemaphoreTake( hdkif->goRX, 0 );
 #endif
 
            /* Get the bd which contains the earliest filled data */
@@ -952,6 +984,7 @@ void rpp_eth_recv_raw(void *arg)
                        processed_bd = curr_bd;
                        ex_len += pbuf->len;
                        curr_bd = curr_bd->next;
+                       /* XXX: curr_bd here could be NULL */
                    } while((processed_bd->flags_pktlen & EMAC_DSC_FLAG_EOP) != EMAC_DSC_FLAG_EOP);
 
                    /**
@@ -988,7 +1021,22 @@ void rpp_eth_recv_raw(void *arg)
                     * from the upper layer
                     */
                    rxch->freed_pbuf_len += len_to_alloc;
-                   new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
+#if !NO_SYS
+                   /* if there is not enough pbufs predefined, we need application to process them and return them back to pool -> YIELD */
+                   /* XXX: this is not fixed in NO_SYS version - problem is when curr_bd is set to NULL (see above), and we don't obtain new_pbuf
+                    * from pool, then in *bd pointing to NULL might be such values (EMAC_DSC_FLAG_SOP == 1 &| EMAC_DSC_FLAG_OWNER == 0), that we
+                    * stay cycling around */
+                   do
+                   {
+#endif
+                           new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
+#if !NO_SYS
+                           if(new_pbuf != NULL)
+                               break;
+                           else
+                               taskYIELD();
+                   }while(1);
+#endif
 
                    /* Write the descriptors with the pbuf info till either of them expires */
                    if(new_pbuf != NULL)
@@ -999,7 +1047,7 @@ void rpp_eth_recv_raw(void *arg)
                        {
                            curr_bd->bufptr = (uint8_t *)(q->payload);
 
-                           /* no support for buf_offset. RXBUFFEROFFEST register is 0 */
+                           /* no support for buf_offset. RXBUFFEROFFSET register is 0 */
                            curr_bd->bufoff_len = (q->len) & 0xFFFF;
                            curr_bd->flags_pktlen = EMAC_DSC_FLAG_OWNER;
 
index 2a28b6b41e9cbfee5721914f9ac938f88b5e8c35..12e93a23df3941ac6599c9732f18193339c14ea7 100644 (file)
@@ -219,6 +219,37 @@ int32_t rpp_sci_printf(const char* format, ...)
     return length;
 }
 
+int32_t __rpp_sci_printf(const char* format, va_list argList)
+{
+    char str[MAX_BUFFER_LEN];
+    int length = -1;
+
+    length = vsnprintf(str, sizeof(str), format, argList);
+
+    va_end(argList);
+
+    if(length > 0) {
+        #if rppCONFIG_DRV == 1
+        // According to the C stdlib about vsnprintf:
+        // If the resulting string would be longer than n-1 characters, the
+        // remaining characters are discarded and not stored, but counted
+        // for the value returned by the function.
+        // In consequence we need to trim the value if larger than buffer.
+        if(length > sizeof(str)) {
+            length = sizeof(str);
+        }
+        if(drv_sci_send(
+                        (uint32_t)length,
+                        (uint8_t*)str,
+                        portMAX_DELAY) != SUCCESS) {
+            return -1;
+        }
+        #endif
+    }
+
+    return length;
+}
+
 
 int8_t rpp_sci_putc(uint8_t byte)
 {