]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/commitdiff
several functions modified for more general use and declarations added to header...
authorJan Dolezal <pm.jenik@gmail.com>
Sat, 10 Aug 2013 21:33:51 +0000 (23:33 +0200)
committerJan Dolezal <pm.jenik@gmail.com>
Sat, 10 Aug 2013 21:33:51 +0000 (23:33 +0200)
rpp/include/rpp/eth.h
rpp/src/rpp/eth.c

index c920601a57e359e3a4659ef9d041c7ea9327cd01..57f9d17fc51004fa9e5e683fa2ffba8f75b14881 100644 (file)
 #ifndef __RPP_ETH_H
 #define __RPP_ETH_H
 
+#include <stdio.h>
+
 #include "os/os.h"
 #include "lwip/netif.h"
 
-/* this MAC address is used when user doesn't put the address to postInit function */
+/* this MAC address is used when user put NULL on the right place when calling postInit function */
 #define RPP_MAC_ADDR {0x12,0x34,0x56,0x78,0x9a,0xbc}
 #if STATIC_IP_ADDRESS
 #define RPP_IP_ADDR        0xC0A8F701 /* 192.168.247.1   IP4_ADDR(rppip, 192,168,0,10);       */
 #define MACADDR_NOT_SET    -3
 #define PHY_LINK_DOWN      -4
 
-#define NETIF_ADD_ERR      -10 /* could be one of previous */
+#define NETIF_ADD_ERR      -10 /* could be one of previous, except PHY_LINK_DOWN - currently */
 #define DHCP_MEM_ERR       -11
 #define DHCP_BIND_TIMEOUT  -12
 
+#define rpp_debug_printf rpp_sci_printf
+
 /**
  * ETH module system startup initialization.
  *
  */
 int8_t rpp_eth_init();
 
-
 /**
  * ETH module application initialization.
  *
  * Call this method before using eth module.
- * This method blocks on autonegotiation till it's complete and creates tasks
- * for lwIP (including lwIP init) and for receiving. Sets IP address using
+ * This method waits for a while on autonegotiation till it's complete, if not completed
+ * in predefined time it continues with creating tasks for lwIP (including lwIP init),
+ * for receiving and for handling transmission buffer descriptors. Sets IP address using
  * predefined static IP or DHCP. Before calling this method you must call rpp_eth_init() first.
  *
  * @param instNum number of EMAC instance
@@ -67,11 +71,63 @@ int8_t rpp_eth_init();
  */
 int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray);
 
-//Generic API
+// Helper routines/functions for command processor and other applications
+
+/**
+ * Uses MDIO module to read link status of PHY attached to #instNum network interface
+ *
+ * @param instNum Number of network interface
+ */
+uint32_t rpp_eth_phylinkstat(uint32_t instNum);
+
+/**
+ * configures whether rpp_eth_get_macAddrStr() creates string with big or small latin letters
+ */
+#define MAC_BIG_LETTERS 1
+/**
+ * Fills macStr field with MAC address of given network interface instance as 'string'
+ *
+ * @note 18 bytes will be filled {2 chars per 6 mac bytes + 5 semicolons + 1 null termination}
+ *
+ * @param instNum Number of network interface
+ * @param *macStr field where null terminated string will be inserted
+ */
+void rpp_eth_get_macAddrStr(uint32_t instNum, uint8_t *macStr);
+
+/**
+ * Fills ipStr field with IP address in ip_addr_t as 'string'
+ *
+ * @note up to 16 bytes will be filled {1-3 * 4 IP fields + 3 dots + 1 null termination}
+ *
+ * @param ip ip address to be converted
+ * @param ipStr pointer to string where ip will be filled as text
+ */
+inline void rpp_eth_getIPDecimalStr(ip_addr_t ip, uint8_t *ipStr);
 
 /**
- * Handles too short packets, preserves the integrity of the transmission,
- * calls rpp_et_send_raw()
+ * Fills ip.addr with converted ipstr. Checks for correct format of IP string
+ * x.x.x.x where x = [0..9]. When FAILURE is returned struct ip was not modified.
+ *
+ * @param ip struct to be filled
+ * @param ipstr string to be converted
+ *
+ * @return SUCCESS when succesfully converted
+ *         FAILURE when wrong format of IP string
+ */
+err_t rpp_eth_stringToIP(ip_addr_t * ip, uint8_t * ipstr);
+
+/**
+ * Returns struct describing network interface
+ *
+ * @param instNum instance number of network interface
+ *
+ * @return pointer to struct netif
+ */
+struct netif *rpp_eth_get_netif(uint32_t instNum);
+
+/**
+ * Adjusts packet (pbuf) length and send it within critical section
+ * using rpp_eth_send_raw()
  *
  * @param netif lwIP network interface describing struct
  * @param p buffer for data to be sent
@@ -90,6 +146,9 @@ err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p);
  * Receives raw data and sends them upward to lwIP stack.
  * Handles rx emac descriptors.
  *
+ * @note when using OS tasks (!NO_SYS) this function is used as
+ *       task, otherwise (NO_SYS) this is called from RX ISR.
+ *
  * @param arg netif
  */
 void rpp_eth_recv_raw(void *arg);
index c9d1437fe32d2ab01a285239654cfc92909d8db6..d808a22c2861854726b6a348768ba7a8329db4e6 100644 (file)
 
 #define MAX_TRANSFER_UNIT         1500 /* take in account oversized frames */
 #define PBUF_LEN_MAX              MAX_TRANSFER_UNIT
-#define MAX_RX_PBUF_ALLOC         15 /* no need to limit it here -> better to do it in lwipopts.h */
+#define MAX_RX_PBUF_ALLOC         15 /* no need to limit it here -> it's better to do it in lwipopts.h */
 #define MIN_PKT_LEN               60
 
 /* Define those to better describe the network interface. */
@@ -240,67 +240,76 @@ static struct netif hdkNetIF[MAX_EMAC_INSTANCE];
 static boolean_t initialized = FALSE, postInitialized = FALSE;
 
 
-/******************************************************************************************************/
+/**********************************************testing functions**********************************************/
 
-uint32_t rpp_eth_linkstat(uint32_t instNum)
+uint32_t rpp_eth_phylinkstat(uint32_t instNum)
 {
        struct hdkif *hdkif = &hdkif_data[instNum];
        return PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 1);
 }
 
-/* prints MAC address assigned to EMAC instance reffered by instNum */
-void rpp_eth_print_macAddr(uint32_t instNum)
+#define BYTE_BUFF_SIZE 2
+#define OFFSET_MAC_LETTERS (MAC_BIG_LETTERS ? 'A' : 'a')
+/* puts string of MAC address assigned to EMAC instance reffered by instNum into *mac */
+void rpp_eth_get_macAddrStr(uint32_t instNum, uint8_t *macStr)
 {
-    u32_t temp;
+    uint8_t index, outindex = 0;
+    char buff[BYTE_BUFF_SIZE];
     struct hdkif *hdkif = &hdkif_data[instNum];
-    rpp_sci_printf((const char *) "MAC address: ");
-       for(temp = 0; temp < (MAC_ADDR_LEN-1); temp++) {
-           rpp_sci_printf((const char *) "%x:", hdkif->mac_addr[(MAC_ADDR_LEN - 1) - temp]);
+       for(index = 0; index < MAC_ADDR_LEN; index++) {
+               if(index)macStr[outindex++] = ':';
+        buff[0] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] >> 4);
+        buff[1] = (hdkif->mac_addr[(MAC_ADDR_LEN - 1) - index] & 0xf);
+               macStr[outindex++] = (buff[0]<10) ? (buff[0] + '0') : (buff[0] - '\012' + OFFSET_MAC_LETTERS);
+               macStr[outindex++] = (buff[1]<10) ? (buff[1] + '0') : (buff[1] - '\012' + OFFSET_MAC_LETTERS);
        }
-       rpp_sci_printf((const char *) "%x\r\n", hdkif->mac_addr[0]);
+       macStr[outindex] = '\0';
 }
 
-/* prints an IP address, where each byte is one of 4 fields in IPv4 IP address format */
-void rpp_eth_printIPDecimal(ip_addr_t ip)
+/* prepares an IP address to ipStr in form of null terminated string; each byte of ip is converted to one of 4 field in IPv4 IP address format 0xAABBCCDD -> "aaa.bbb.ccc.ddd" */
+inline void rpp_eth_getIPDecimalStr(ip_addr_t ip, uint8_t *ipStr)
 {
-       rpp_sci_printf((const char *) "%d.%d.%d.%d",(ip.addr >> 24),((ip.addr >> 16) & 0xff),((ip.addr >> 8) & 0xff),(ip.addr%256));
+       snprintf((char *)ipStr, 16, "%d.%d.%d.%d",(ip.addr >> 24),((ip.addr >> 16) & 0xff),((ip.addr >> 8) & 0xff),(ip.addr & 0xff));
 }
 
 /* @param ip will be filled accroding to content of ipstr */
 err_t rpp_eth_stringToIP(ip_addr_t * ip, uint8_t * ipstr)
 {
-       uint8_t index, tmp = 0, dots = 0;
+       uint8_t charProccessed, index = 0, dotindex = 0xff, tmp = 0, dots = 0, fldEdit = 0;
        uint32_t ipaddr = 0;
-/* TODO: checking chars for weird combinations,... */
-       for(index = 0; ipstr[index] != 0; index++)
+       for(charProccessed = ipstr[index]; (charProccessed >= '0' && charProccessed <= '9') || charProccessed == '.' ; charProccessed = ipstr[++index])
        {
-               if(ipstr[index] != '.' && ipstr[index] != 0)
-               {
-                       tmp = tmp*10 + ipstr[index] - '0';
-               }
-               else
+               if(charProccessed == '.')
                {
+                       if(++dotindex == index)
+                       {
+                               dots = 0;
+                               break;
+                       }
+                       dotindex = index;
+
                        ipaddr = (ipaddr << 8) + tmp;
-                       if(dots == 3)break;
+
                        dots++;
+                       if(dots > 3)break;
+
                        tmp = 0;
+                       fldEdit = FALSE;
+               }
+               else
+               {
+                       fldEdit = TRUE;
+                       tmp = tmp*10 + charProccessed - '0';
                }
        }
-       if(dots != 3)
+       if(dots != 3 || !fldEdit)
        {
-               ip->addr = 0;
-               return -1;
+               /* if unsuccesful, don't modify previous content */
+               return FAILURE;
        }
        ipaddr = (ipaddr << 8) + tmp;
        ip->addr = ipaddr;
-       return ERR_OK;
-}
-
-/* prints address, netmask and gateway in hex*/
-void rpp_eth_print_IPAddr(uint32_t instNum)
-{
-    struct netif *netif = &hdkNetIF[instNum];
-    rpp_sci_printf((const char *) "address: %x\r\nnetmask: %x\r\ngateway: %x\r\n",netif->ip_addr,netif->netmask,netif->gw);
+       return SUCCESS;
 }
 
 struct netif *rpp_eth_get_netif(uint32_t instNum)
@@ -308,12 +317,14 @@ struct netif *rpp_eth_get_netif(uint32_t instNum)
        return &hdkNetIF[instNum];
 }
 
-/******************************************************************************************************/
+/********************************************** forward declares **********************************************/
 
-/* forward declare */
+/*
+ * interface initializes
+ */
 err_t rpp_eth_lwip_init(struct netif *netif);
 
-/**
+/*
  * Initializes hw such as PHY, MDIO, EMAC, EMAC control module
  *
  * @return SUCCESS if initialization successful.\n
@@ -321,13 +332,15 @@ err_t rpp_eth_lwip_init(struct netif *netif);
  */
 err_t rpp_eth_hw_init(struct hdkif *hdkif);
 
-/**
+/*
  * Initializes hw, after lwIP was initialized and
  * OS was initialized in case OS is used.
  */
 err_t rpp_eth_hw_init_postInit(struct netif *netif);
 
-/**
+/********************************************** utility functions **********************************************/
+
+/*
 * Function to set the MAC address to the interface
 * @param   inst_num the instance number
 *
@@ -345,7 +358,9 @@ hdkif_macaddrset(u32_t inst_num, u8_t *mac_addr) {
     hdkif->mac_addr[temp] = mac_addr[(MAC_ADDR_LEN - 1) - temp];
   }
 #ifdef DEBUG
-  //rpp_eth_print_macAddr(inst_num);
+  uint8_t macStr[18];
+  rpp_eth_get_macAddrStr(inst_num, uint8_t *macStr);
+  rpp_debug_printf((const char *) "Setting MAC... %s\r\n", macStr);
 #endif
 }
 
@@ -370,7 +385,7 @@ hdkif_inst_config(struct hdkif *hdkif) {
   }
 }
 
-/******************************************************************************************************/
+/********************************************** initializing functions **********************************************/
 
 int8_t rpp_eth_init()
 {
@@ -410,6 +425,9 @@ int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
     int8_t retVal = SUCCESS;
     struct netif *netif = &hdkNetIF[instNum];
     u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
+#ifdef DEBUG
+    uint8_t ipString[16];
+#endif
 
     /* ----- lwIP stuff ----- */
     struct ip_addr ip_addr;
@@ -465,44 +483,42 @@ int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
     /* ----- end - freeRTOS ----- */
 #endif /* !NO_SYS */
 
-    if(rpp_eth_linkstat(hdkif->inst_num))
+    if(rpp_eth_phylinkstat(hdkif->inst_num))
     {
-       rpp_sci_printf((const char *)"cable connected\r\n");
+       rpp_debug_printf((const char *)"cable connected\r\n");
 #if STATIC_IP_ADDRESS
        netif_set_up(netif);
 #elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
        if(dhcp_start(netif) != ERR_OK)
        {
 #ifdef DEBUG
-               rpp_sci_printf((const char *) "dhcp mem err\r\n");
+               rpp_debug_printf((const char *) "dhcp mem err\r\n");
 #endif
                return DHCP_MEM_ERR;
        }
 #ifdef DEBUG
-       rpp_sci_printf((const char *) "binding DHCP\r");
+       rpp_debug_printf((const char *) "binding DHCP\r");
 #endif
        while((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--));
 #ifdef DEBUG
        if(!dhcpBindWait)
-               rpp_sci_printf((const char *) "dhcp binding timeout...\r\n");
+               rpp_debug_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);
 #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); */
+       rpp_eth_getIPDecimalStr(netif->ip_addr, ipString);
+       rpp_debug_printf((const char *) "Address: %s\r\n", ipString);
+       rpp_eth_getIPDecimalStr(netif->netmask, ipString);
+       rpp_debug_printf((const char *) "Netmask: %s\r\n", ipString);
+       rpp_eth_getIPDecimalStr(netif->gw, ipString);
+       rpp_debug_printf((const char *) "Gateway: %s\r\n", ipString);
 #endif
     }
     else
     {
-       rpp_sci_printf((const char *)"cable not connected\r\n");
+       rpp_debug_printf((const char *)"cable not connected\r\n");
         retVal = PHY_LINK_DOWN;
     }
     /* ----- end - lwIP stuff ----- */
@@ -551,7 +567,7 @@ err_t rpp_eth_lwip_init(struct netif *netif)
 err_t rpp_eth_hw_init(struct hdkif *hdkif)
 {
        /* FIXME: express initial index using defines */
-    uint8_t index = 80; /* initially used to hw reset of PHY connected to GIO pin 'rpp project only' */
+    uint8_t index = 80; /* Initially used to hw reset of PHY connected to GIO pin 'rpp project only'; 1us - according to PHY specification. */
     uint16_t regContent;
     uint32_t physAlive;
 
@@ -601,13 +617,13 @@ err_t rpp_eth_hw_init(struct hdkif *hdkif)
         if(!physAlive)
         {
 #ifdef DEBUG
-            rpp_sci_printf((const char *) "no phy found, phys: %d\r\n", physAlive);
+            rpp_debug_printf((const char *) "no phy found, phys: %d\r\n", physAlive);
 #endif
                return NO_PHY_ALIVE;
         }
 #else
 #ifdef DEBUG
-        rpp_sci_printf((const char *) "default phy not alive\r\n");
+        rpp_debug_printf((const char *) "default phy not alive\r\n");
 #endif
        return DFLT_PHY_NOT_ALIVE;
 #endif
@@ -655,7 +671,7 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
     txch = &(hdkif->txch);
 
 #ifdef DEBUG
-    rpp_sci_printf((const char *) "autoneg started - check on cable if it's connected!\r\n");
+    rpp_debug_printf((const char *) "autoneg started - check on cable if it's connected!\r\n");
 #endif
 
 
@@ -727,12 +743,12 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
 
        last_rxbd->next = NULL;
 #ifdef DEBUG
-       rpp_sci_printf((const char *) "last_rxbd: 0x%x\r\n",last_rxbd);
+       rpp_debug_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);
+       rpp_debug_printf((const char *) "num of filled bds: %d\r\nnum of pbufs: %d\r\n", num_bd, pbuf_cnt);
 #endif
 
 
@@ -780,16 +796,16 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
 
 #ifdef DEBUG
     if(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) != FALSE)
-       rpp_sci_printf((const char *) "aneg finished \r\n");
+       rpp_debug_printf((const char *) "aneg finished \r\n");
     else
-       rpp_sci_printf((const char *) "aneg timeout \r\n");
+       rpp_debug_printf((const char *) "aneg timeout \r\n");
 #endif
 
     /* check if phy link is up - it is when autoneg was completed succesfully */
 /*    if(!PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 3))
     {
 #ifdef DEBUG
-       rpp_sci_printf((const char *) "Link is down\r\n");
+       rpp_debug_printf((const char *) "Link is down\r\n");
 #endif
        return PHY_LINK_DOWN;
     }*/
@@ -803,7 +819,7 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
        EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
     } else {
 #ifdef DEBUG
-       rpp_sci_printf((const char *) "Unknown duplex mode\r\n");
+       rpp_debug_printf((const char *) "Unknown duplex mode\r\n");
 #endif
        return UNKN_DUPLEX_MODE;
     }
@@ -818,6 +834,8 @@ err_t rpp_eth_hw_init_postInit(struct netif *netif)
        return SUCCESS;
 }
 
+/********************************************** send and receive functions / ISRs **********************************************/
+
 err_t rpp_eth_send(struct netif * netif, struct pbuf *p)
 {
        err_t retVal = SUCCESS;