Author Topic: Important note about LPC23xx and LPC24xxx Ethernet  (Read 16266 times)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3238
    • View Profile
    • uTasker
Important note about LPC23xx and LPC24xxx Ethernet
« on: January 25, 2010, 01:10:01 AM »
Hi All

While working with the new LPC17XX, which has the same Ethernet controller built in as the LPC23XX and LPC24XX I was rather concerned about the quite poor performance of the Ethernet interface. After a series of tests to try to understand the reason why it was sometimes losing transmission frames I identified that the way that the TxConsumeIndex and TxProduceIndex was operating was not correct.

Basically the TxProduceIndex is maintained by the software and the TxConsumeIndex by the hardware. By checking these values it can be identified whether the Ethernet transmitter buffers have space to add Ethernet frames or not. If ever the Ethernet controller has not sent the first frame in a queue of Ethernet frames, the software waits a short time before it finally can add the new frame's data or else gives up since the buffers have been blocked for too long. In fact one would not normally expect the software to have to wait, especially when several tx buffers are available.

But things were not working as expected as could be seen by the fact that sometimes the TxConsumeIndex was not counting. Generally it was being incremented after a delay of around 2.6ms and not at the speed that the Ethernet frames were being transmitted. It was even possible to cause an infinity loop if the expected sequence was waited for (without an escape path on long delays).

Finally I found that this became more noticeable when the number of tx buffers was decreased. With 3 rx buffers and 7 tx buffers it wasn't really noticed. [note that the first LPC23XX chips have a bug which means that the number of rx buffers is limited to a maximum of 5 and so the number of tx buffers was always set fairly high. In the case of the LPC24xx this limit is no longer applicable but the project set up was not correct - it was using proportionally too many tx buffers: 3 rx and 7 tx, whereas the inverse was probably desired]. In the LPC17XX case I realised that the rx/tx ratio was inverted and after its 'optimisation' I then realised that something was not right...

So to cut a long story short, the TxConsumeIndex was doing some very strange things which obviously didn't allow it to be used as intended because it would sometimes incorrectly recognise full buffers and could cause loss of transmissions. But it turns out that this strangeness can be completely removed if the end of frame interrupt is enabled (the tx interrupt is not needed and is in fact disabled) in the buffer descriptor belonging to the frame buffer. Once set, the TxConsumeIndex was being incremented correctly and also without the 2.6ms delay (it was in the us range as expected). With the 7 rx and 3 tx buffer ratio (this uses the 16k of the available LAN RAM in a favorable way since more rx buffers is generally better) the performance was then correspondingly better.

Therefore I suggest all users of the LPC23xx and LPC24xx to verify the following changes in their projects.

1) In app_hw_lpc23xx.h !!only LPC24XX users or those who are sure that the LPC23xx chips don't have the Ethernet buffer errata!!
    #define LAN_RX_BUF_COUNT          7                                  // rx buffer space defined to be 7 times the full buffer
    #define LAN_TX_BUF_COUNT          3

2) In lpc23xx.c in the routine fnStartEthTx() add the TX_LAN_INTERRUPT_ON_DONE flag:

    LPC23XX_RX_BD *ptrBd = (LPC23XX_RX_BD *)EMAC_TxDescriptor;
    ptrBd += EMAC_TxProduceIndex;
    ptrBd->bd_details = (TX_LAN_INTERRUPT_ON_DONE | TX_LAST_FRAG | TX_APPEND_CRC | TX_PAD_FRAME | (DataLen - 1)); // {18}

This should optimise and improve performance generally.

In the case of the LPC24XX there is a further error which was solved during this work concerting Port 2 edge interrupts:
In LPC23XX.c:

#ifdef _LPC24XX
    static void ( *gpio_handlers_2[32] )( void ) = {0};                  // {19} a handler for each possible port 2 pin

    static void ( *gpio_handlers_2[14] )( void ) = {0};                  // a handler for each possible port 2 pin

The LPC24XX has 32 pins on Port 2 (the LPC23XX has only 14) and so the number of interrupt handlers for the port should correspond. The Olimex LPC-2478-STK uses Port 2-25 as PHY interrupt and the interrupt was potentially corrupting RAM and leading to a data abort.



Offline aaronlawrence

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Important note about LPC23xx and LPC24xxx Ethernet
« Reply #1 on: March 23, 2010, 11:41:44 PM »
Important note: in combination with some TCP bugs we are investigating, this can result in the socket transmit permanently stopping! It is NOT just a performance issue.

Offline cstrahm

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Important note about LPC23xx and LPC24xxx Ethernet
« Reply #2 on: June 01, 2010, 04:33:19 AM »
Last year when I checked uTasker it really wasn't working yet on these MCUs.  I have found the LPC23XX to be very good MCUs for Enet.  The Enet core works flawless.  I get about 2-3 MegaBytes/sec with the lwIP stack.  Is the uTasker stack working now on these?  So what kind of TCP throughput is anyone getting with the LPC23XX and the uTasker stack?

Offline aaronlawrence

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Important note about LPC23xx and LPC24xxx Ethernet
« Reply #3 on: June 03, 2010, 12:08:19 AM »
uTasker TCP/IP works on LPC23xx reasonably well.

But flawless is a strong word ... NXP only just added an errata item about failure to increment one of the Ethernet counters after the first or second packet transmitted. And they had some horrendous bugs on the earlier revisions of the silicon.

Also I am having some problems with transmitted packets going missing, and failure to maintain connection on a LAN with lots of traffic, which could well be LPC limitations (they don't seem to be uTasker problems).

Offline aaronlawrence

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Important note about LPC23xx and LPC24xxx Ethernet
« Reply #4 on: July 30, 2010, 02:40:07 AM »
To be specific about our problem.
lost packets such as those described here, should be retransmitted by TCP. However, there are or were some bugs in uTasker TCP such that retransmits didn't happen.
In our case it was because data was being received continually. This was incorrectly resetting the TCP retransmit timer, so it never fired. Hence, TCP transmit was stuck.