This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

"Hercules TMS570LS31x/21x Development Kit". I can't get IP with LWIP DHCP.

I am making an ethernet application using the lwip library with "Hercules TMS570LS31x/21x Development Kit".
If I give a static IP, I can get IP, I did not encounter any problems.
But if I want it to get an IP via DHCP, it rarely succeeds.
And I haven't seen it succeed in LocatorConfig either.
lwip library version: 1.4.1
downloaded the library from here: http://git.ti.com/hercules_examples/hercules_examples/trees/master/Application/LwIP

I did tests for a long time, but I could not identify the source of the problem, do you have any advice for me?
Thanks for your help.

The code I use is as follows.

sys_main.c
uint8 emacAddress[6U] = { 0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU };
uint32 emacPhyAddress = 1U;

int main(void)
{
    /* USER CODE BEGIN (3) */
    EMAC_LwIP_Init();

    EMAC_LwIP_Main(emacAddress);

    while (1)
    {
    }
    /* USER CODE END */

    return 0;
}


lwip_functions.c
void EMAC_LwIP_Init(void)
{
    sciInit();
    /* Enable the interrupt generation in CPSR register */
    IntMasterIRQEnable();
    _enable_FIQ();
}

uint8_t EMAC_LwIP_Main(uint8_t *macAddress)
{
    unsigned int ipAddr;
    struct in_addr devIPAddress;

    /* Initialze the lwIP library, using DHCP.*/
    ipAddr = lwIPInit(0, macAddress, 0, 0, 0, IPADDR_USE_DHCP);

    if (0 == ipAddr)
    {
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));
        sciDisplayText(sciREGx, txtErrorInit, sizeof(txtErrorInit));
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));

        return 0;
    }
    else
    {
        /* Convert IP Address to string */
        devIPAddress.s_addr = ipAddr;
        txtIPAddrItoA = (uint8_t*) inet_ntoa(devIPAddress);
        LocatorConfig(macAddress, "LaunchPad enet_lwip");
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));
        sciDisplayText(sciREGx, txtIPAddrTxt, sizeof(txtIPAddrTxt));
        sciDisplayText(sciREGx, txtIPAddrItoA, 16);
        sciDisplayText(sciREGx, txtCRLF, sizeof(txtCRLF));

        return 1;
    }
}


lwiplib.c
/**
 *
 * \brief Initializes the lwIP TCP/IP stack.
 *
 * \param instNum  The instance index of the EMAC module
 * \param macArray Pointer to the MAC Address
 * \param ipAddr   The IP address to be used 
 * \param netMask  The network mask to be used 
 * \param gwAddr   The Gateway address to be used 
 * \param ipMode   The IP Address Mode.
 *        ipMode can take the following values\n
 *             IPADDR_USE_STATIC - force static IP addressing to be used \n
 *             IPADDR_USE_DHCP - force DHCP with fallback to Link Local \n
 *             IPADDR_USE_AUTOIP - force  Link Local only
 *
 * This function performs initialization of the lwIP TCP/IP stack for the
 * HDK EMAC, including DHCP and/or AutoIP, as configured.
 *
 * \return IP Address.
 */
unsigned int lwIPInit(unsigned int instNum, unsigned char *macArray, unsigned int ipAddr, unsigned int netMask, unsigned int gwAddr, unsigned int ipMode)
{
    struct ip_addr ip_addr;
    struct ip_addr net_mask;
    struct ip_addr gw_addr;
    volatile unsigned char *state = NULL;
    unsigned int *ipAddrPtr;
    volatile unsigned int cnt = 0x3FFFFFFF;

    lwip_init();

    /* Setup the network address values. */
    if (ipMode == IPADDR_USE_STATIC)
    {
        ip_addr.addr = htonl(ipAddr);
        net_mask.addr = htonl(netMask);
        gw_addr.addr = htonl(gwAddr);
    }

    else
    {
        ip_addr.addr = 0;
        net_mask.addr = 0;
        gw_addr.addr = 0;
    }

    hdkif_macaddrset(instNum, macArray);

    /*
     ** Create, configure and add the Ethernet controller interface with
     ** default settings.  ip_input should be used to send packets directly to
     ** the stack. The lwIP will internaly call the hdkif_init function.
     */
    if (NULL == netif_add(&hdkNetIF[instNum], &ip_addr, &net_mask, &gw_addr, &instNum, hdkif_init, ip_input))
    {
        return 0;
    };

    netif_set_default(&hdkNetIF[instNum]);

    /* Start DHCP, if enabled. */
#if LWIP_DHCP
    if (ipMode == IPADDR_USE_DHCP)
    {
        unsigned int dhcp_flag = 0;
        unsigned int dhcp_tries = 5;
        unsigned int count;
        unsigned int delay;
        while (dhcp_tries--)
        {

            dhcp_start(&hdkNetIF[instNum]);

            count = 10;
            /* Check for DHCP completion for 'count' number of times, each for the given delay. */
            while (state == 0)
            {
                delay = 0x8FFFFFFU;
                while (delay--)
                    ;
                state = &(hdkNetIF[instNum].dhcp->state);
                uint8_t buf[20];
                sprintf(buf, "State: %d\n\r", *state);
                sciDisplayText(sciREGx, &buf[0], strlen(buf));
                if (DHCP_BOUND == *state)
                {
                    dhcp_flag = 1;
                    ipAddrPtr = (unsigned int*) &(hdkNetIF[instNum].ip_addr);
                    return (*ipAddrPtr);
                }
            }

        }
        /* In case of DHCP failure, return 0. */
        if (dhcp_flag == 0)
            return 0;
    }
#endif

    /* Start AutoIP, if enabled and DHCP is not. */
#if LWIP_AUTOIP
     if(ipMode == IPADDR_USE_AUTOIP)
     {
         autoip_start(&hdkNetIF[instNum]);
     }
 #endif

    if ((ipMode == IPADDR_USE_STATIC) || (ipMode == IPADDR_USE_AUTOIP))
    {
        /* Bring the interface up */
        netif_set_up(&hdkNetIF[instNum]);
    }

    ipAddrPtr = (unsigned int*) &(hdkNetIF[instNum].ip_addr);

    return (*ipAddrPtr);
}


locator.c
/*
** This function is called by the lwIP TCP/IP stack when it receives a UDP
** packet from the discovery port.  It produces the response packet, which is
** sent back to the querying client.
*/
static void LocatorReceive(void *arg, struct udp_pcb *pcb, struct pbuf *p,
                           struct ip_addr *addr, u16_t port)
{
    unsigned char *pucData;
    unsigned long ulIdx;

    /* Validate the contents of the datagram.*/
    pucData = p->payload;
    if((p->len != 4) || (pucData[0] != TAG_CMD) || (pucData[1] != 4) ||
       (pucData[2] != CMD_DISCOVER_TARGET) ||
       (pucData[3] != ((0 - TAG_CMD - 4 - CMD_DISCOVER_TARGET) & 0xff)))
    {
        pbuf_free(p);
        return;
    }

    pbuf_free(p);

    p = pbuf_alloc(PBUF_TRANSPORT, sizeof(locatorData), PBUF_RAM);
    if(p == NULL)
    {
        return;
    }

    /* Calcuate and fill in the checksum on the response packet.*/
    for(ulIdx = 0, locatorData[sizeof(locatorData) - 1] = 0;
        ulIdx < (sizeof(locatorData) - 1); ulIdx++)
    {
        locatorData[sizeof(locatorData) - 1] -=
            locatorData[ulIdx];
    }

    /* Copy the response packet data into the pbuf. */
    pucData = p->payload;
    for(ulIdx = 0; ulIdx < sizeof(locatorData); ulIdx++)
    {
        pucData[ulIdx] = locatorData[ulIdx];
    }

    /* Send the response.*/
    udp_sendto(pcb, p, addr, port);

    pbuf_free(p);
}
/*
** Initializes the locator service. Prepares the locator service to
** handle device discovery requests.  .
*/
void LocatorConfig(unsigned char *macArray, const char *appTitle)
{
    unsigned int idx;
    void *pcb;

    /* Clear out the response data.*/
    for(idx = 0; idx < 84; idx++)
    {
        locatorData[idx] = 0;
    }

    /* Fill in the header for the response data.*/
    locatorData[0] = TAG_STATUS;
    locatorData[1] = sizeof(locatorData);
    locatorData[2] = CMD_DISCOVER_TARGET;

    /* Fill in the MAC address for the response data. */
    locatorData[9] =  macArray[0];
    locatorData[10] = macArray[1];
    locatorData[11] = macArray[2];
    locatorData[12] = macArray[3];
    locatorData[13] = macArray[4];
    locatorData[14] = macArray[5];

    /* Create a new UDP port for listening to device locator requests.*/
    pcb = udp_new();
    udp_recv(pcb, LocatorReceive, NULL);
    udp_bind(pcb, IP_ADDR_ANY, 23);
    udp_connect(pcb, IP_ADDR_ANY, 23);

    /* Copy the application title string into the response data. */
    for(idx = 0; (idx < 64) && *appTitle; idx++)
    {
        locatorData[idx + 19] = *appTitle++;
    }

    /* Zero-fill the remainder of the space in the response data (if any).*/
    for(; idx < 64; idx++)
    {
        locatorData[idx + 19] = 0;
    }

}