lwip LPC176x EMAC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

lwip LPC176x EMAC

953 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nkarakotas on Wed Dec 21 07:37:55 MST 2011
Hi,

After using uIP I decided to try out lwip as it's designed for 32 bit and offer better performance. Im having a few problems with the EMAC drivers. I keep on receiving corrupted packets unless there is somewhere problems when copying the data to the pbuf. Below is the EMAC.c and the part of the ethernetif.c. Does anyone have any clues?

Regards

static void ethernetif_input( void * pvParameters )
{

    struct ethernetif   *ethernetif;
    struct eth_hdr      *ethhdr;
    struct pbuf         *p;
    struct netif *netif;


    netif = (struct netif*) pvParameters;

    for( ;; )
    {
        do
        {
            ethernetif = netif->state;

            /* move received packet into a new pbuf */
            p = low_level_input( netif );

            if( p == NULL )
            {
                /* No packet could be read.  Wait a for an interrupt to tell us
                there is more data available. */
                vEMACWaitForInput();
            }

        } while( p == NULL );

        /* points to packet payload, which starts with an Ethernet header */
        ethhdr = p->payload;

        switch( htons( ethhdr->type ) )
        {
            /* IP packet? */
            case ETHTYPE_IP:
            case ETHTYPE_ARP:
                 if (netif->input(p, netif)!=ERR_OK){
                     LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
                     pbuf_free(p);
                     p = NULL;
                 }
                 break;
        }


    }
}
static struct pbuf *low_level_input( struct netif *netif )
{

    struct pbuf             *p = NULL;
    static xSemaphoreHandle xRxSemaphore = NULL;

    /* Parameter not used. */
    ( void ) netif;

    if( xRxSemaphore == NULL )
        vSemaphoreCreateBinary( xRxSemaphore );

    /* Access to the emac is guarded using a semaphore. */
       if( xSemaphoreTake( xRxSemaphore, netifGUARD_BLOCK_TIME ) )
    {
        if( EMAC_CheckReceiveIndex() == TRUE )
        {

            p = EMAC_ReadPacketBuffer( NULL );

            if(p != NULL){

                #if LINK_STATS
                    lwip_stats.link.recv++;
                #endif /* LINK_STATS */

            }
            else
            {
                // drop packet();
                #if LINK_STATS
                    lwip_stats.link.memerr++;
                    lwip_stats.link.drop++;
                #endif /* LINK_STATS */
            }
        }

        xSemaphoreGive( xRxSemaphore );
    }

    return p;
}
Part of [B]emac.c[/B]
/*--------------------------- rx_descr_init ---------------------------------*/
/*********************************************************************//**
 * @brief       Initializes RX Descriptor
 * @param[in]   None
 * @return      None
 ***********************************************************************/
static void rx_descr_init (void)
{

    uint32_t i;

    for (i = 0; i < EMAC_NUM_RX_FRAG; i++)
    {
        RX_DESC_PACKET(i)  = RX_BUF(i);
        RX_DESC_CTRL(i)    = EMAC_RCTRL_INT | (EMAC_ETH_FRAG_SIZE-1);
        RX_STAT_INFO(i)    = 0;
        RX_STAT_HASHCRC(i) = 0;
    }

    /* Set EMAC Receive Descriptor Registers. */
    LPC_EMAC->RxDescriptor    = RX_DESC_BASE;
    LPC_EMAC->RxStatus        = RX_STAT_BASE;
    LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG-1;

    /* Rx Descriptors Point to 0 */
    LPC_EMAC->RxConsumeIndex  = 0;
}

struct pbuf* EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
{

    struct pbuf* p;
    uint32_t size;
    uint32_t Index;

    /* init p pointer */
    p = NULL;

    Index = LPC_EMAC->RxConsumeIndex;

    if(Index != LPC_EMAC->RxProduceIndex)
    {
        size = (RX_STAT_INFO(Index) & 0x7ff)+1;
        if (size > EMAC_ETH_FRAG_SIZE) size = EMAC_ETH_FRAG_SIZE;

        /* allocate buffer */
        p = pbuf_alloc(PBUF_LINK, size, PBUF_RAM);
        if (p != NULL)
        {
            struct pbuf* q;
            uint8_t *ptr;

            ptr = (uint8_t*)RX_BUF(Index);
            for (q = p; q != NULL; q= q->next)
            {
                memcpy(q->payload, ptr, q->len);
                ptr += q->len;
            }
        }

        /* move Index to the next */
        if(++Index > LPC_EMAC->RxDescriptorNumber)
            Index = 0;

        /* set consume index */
        LPC_EMAC->RxConsumeIndex = Index;
    }


    return p;
}

void ENET_IRQHandler( void )
{
unsigned long ulStatus;
long lHigherPriorityTaskWoken = pdFALSE;

    ulStatus = LPC_EMAC->IntStatus;

    /* Clear the interrupt. */
    LPC_EMAC->IntClear = ulStatus;

    if( ulStatus & EMAC_INT_RX_DONE )
    {
        /* Ensure the uIP task is not blocked as data has arrived. */
        xSemaphoreGiveFromISR( xSemaphore, &lHigherPriorityTaskWoken );
    }

    if( ulStatus & EMAC_INT_TX_DONE )
    {
        EMAC_UpdateTxProduceIndex();
    }

    portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}


DEBUG OUTPUT:
netif_set_ipaddr: netif address being changed
netif: IP address of interface 192.168.1.16
netif: netmask of interface 255.255.255.0
netif: GW address of interface 192.168.1.30
netif: added interface em IP addr 192.168.1.16 netmask 255.255.255.0 gw 192.168.1.30
pbuf_alloc(length=64)
pbuf_alloc(length=64) == 0x10005e8c
tcpip_thread: PACKET 0x10001a10
IP packet dropped due to bad version number 15
IP header:
+-------------------------------+
|15 |15 |  0xff |     65535     | (v, hl, tos, len)
+-------------------------------+
|    65535      |000|      26   | (id, flags, offset)
+-------------------------------+
|  146  |  224  |    0x824b     | (ttl, proto, chksum)
+-------------------------------+
|    8  |    6  |    0  |    1  | (src)
+-------------------------------+
|    8  |    0  |    6  |    4  | (dest)
+-------------------------------+
pbuf_free(0x10005e8c)
pbuf_free: deallocating 0x10005e8c
0 Kudos
5 Replies

542 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ex-kayoda on Tue Jun 12 01:23:15 MST 2012

Quote: alpha
Does anyone have a port for lpc17xx, better still for lpc1769 with LAN8720?




There are several examples in your Example folder (like RDB1768cmsis2), a lot of them can detect LAN8720 or DP83848 and work with both of them:

  if ((phy_id != DP83848C_ID) && (phy_id != LAN8720_ID))
0 Kudos

542 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by alpha on Mon Jun 11 20:14:29 MST 2012

Quote: NXP_Europe
If you aren't aware of it, you may want to have a look at the LWIP port for the LPC17xx available on lpcware.com here:

http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

This is not the final release, but looking at the links on the right-hand side there is some useful information on configuring lwip, etc.



Hi this post seems to be from last year but the website still does not show a lpc17xx port. It only shows the port for LPC177x_8x or LPC18xx/43xx. However the information/docs on lwIP at the webpage is quite good.

Does anyone have a port for lpc17xx, better still for lpc1769 with LAN8720?
0 Kudos

542 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nkarakotas on Thu Dec 22 08:43:55 MST 2011
Hi,

Yes I have looked at it. But when using many references you get lost. It also not in using an OS. The nice thing is the zero copy buffers implemented. In time I will have a proper working port.

Regards,
Nick
0 Kudos

542 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_Europe on Thu Dec 22 07:52:32 MST 2011
If you aren't aware of it, you may want to have a look at the LWIP port for the LPC17xx available on lpcware.com here:

http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

This is not the final release, but looking at the links on the right-hand side there is some useful information on configuring lwip, etc.
0 Kudos

542 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nkarakotas on Thu Dec 22 07:09:33 MST 2011
Hi,

After double checking everything I was sure I was receiving packets but most frequently they where ARP packets and the tcp_input function wasnt parsing them. In code it was casting the p->payload to an IP struct, but was an ARP packet thus giving this error. After setting the correct flags below, the ARP messages are parsed ok.

/* device capabilities */
  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
0 Kudos