One of the first projects I published online a couple of years ago was about how to put together in a prototype board a simple circuit to interface a 10BaseT ethernet controller with a Microchip PIC18 microcontroller running the TCP/IP stack developed by Microchip. I called this project the PIC10T.
The original design for the PIC10T used the ENC28J60 standalone ethernet controller and a PIC18F4620, this article is an updated version of the original project page, which will cover in more detail the basic hardware design, some recommendations and troubleshooting tips for putting together your prototype.
On a separate article I describe how to build the firmware image using the Microchip TCP/IP Stack.
As you may probably know, the ENC28J60 was Microchip first incursion into the ethernet controller arena, the device includes all MAC and PHY IEEE 802.3 10Base-T functions, 8 Kbytes of dual access RAM and SPI serial interface, all in a convenient 28-pin package (SPDIP, SOIC, SSOP and QFN packages are available).
Not long ago, Microchip introduced two new devices the ENC424J600 and ENC624J600, both also standalone ethernet controllers but this time with MAC and PHY for 10/100-Base-T, larger RAM and parallel interface but only available in 44-pin TQFP and QFN packages and only 64-pin TQFP for the ENC624J600.
I'll most probably publish some projects showing how to use the ENC424/624J600 controllers but for now I'll stick with the ENC28J60. It is not probably the best performing ethernet controller in the market, the RAM memory and SPI interface impose some limits on throughput but given that it is the only ethernet controller in available in a DIP package and that it does not require any special components, it is the best choice to get your hands on introductory projects about embedded internetworking. Also for some applications that do not require to handle a lot of traffic the ENC28J60 is a great choice.
Before we jump into the circuit, there are some considerations to take into account for this design. I know that sometimes it may be boring, they may have errors, but take the time to at least browse through the datasheets of the components you are about to use, you don't need to read them in deep detail or memorize them, just get to know the components a little bit more, trust me, on the long run it will save you countless hours of troubleshooting and frustration.
Simple things such as a LDO voltage regulator may require a particular value/type of capacitor, pay attention to those details.
The ENC28J60 has a 3.3V supply, internally part of the logic works at a lower voltage and includes a voltage regulator requiring an external low ESR capacitor for it. If we are planning to interconnect the ENC28J60 to a PIC powered with 5V, we will obviously need a 3.3V voltage regulator. Take in account that the ENC28J60 may consume up to 180mA when choosing your voltage regulator, for this design I used a LM3940-3.3.
Some of the ENC28J60 pins such as CS, RESET, SDI, SCK are 5V tolerant, then we can connect them directly from the PIC, but we have to keep an eye on undershoots (more about it later).
The other way around, we only need one signal from the ENC28J60 to the PIC, SO or the serial output for the SPI interface. If you followed my recommendation and read the datasheets, you may have noticed that on Figure 2-4 of the ENC28J60 datasheet there is a block with a note that says "Level Shift Logic - Required only if the microcontroller is operating at 5V", what is that ?
The issue is that the maximum voltage the ENC28J60 will output as a high level (logic 1) on pins like SO will be Vdd-0.7, at 3.3V that equals to 2.6V. Now go to and take a look at the datasheet of the PIC you are trying to use and check what is the minimum voltage that the SDI pin requires to interpret that as a logic 1 or high level, I'll save you the trip, it is normally 0.8*Vdd, at 5V that is 4V, then as the note says we need something in there to convert the 2.6V from the ENC28J60 into at least 4V for the PIC.
Remember that we are working with signals that may be clocked up to 10MHz, and there are other parameters like rise and fall times that we must respect, then a simple transistor won't work very well, the ENC28J60 datasheet suggest to use a 74HCT08 (quad AND gate) or 74ACT125 (quad 3-state buffer), since I'm planning to share the SPI interface with other devices I chose the 74ACT125 of which for this project we will only use one of the four buffers, I'll leave you as homework to check the 74ACT125 datasheet to confirm that is the right device to use. If you are not scared of surface mount components, there are parts available that have a single gate such as the 74V1T125 which is what I used for the eIP-10 board produced by LJCV Electronics.
There is another detail on the SPI interface we must to keep an eye on. If you ever took a look at the schematics of the Microchip Ethernet PICTail or PICTail+ boards, you may have noticed a small resistor (actually 180ohms) in series with CS, SI and SCK, why is that ?
Take a look at the following graphic
Yes, we are working with digital electronics, but remember no matter what, analog signals keep being analog signals, there are several variables such as conductance, track length, spurious capacitance, etc, that influence how much of it you are going to get when working with short digital pulses, if you have an oscilloscope you can see them by yourself, what I'm talking about, overshoots and undershoots, particularly undershoots which are a very short train of pulses that generate on the falling edge of a digital signal which normally represent a transient negative voltage.
If you look again at the ENC28J60 datasheet, if you look at Section 16.0 on the list of Absolute Maximum Ratings you will see that for RESET, CS, SCK and SI the maximum voltages with respect of Vss are -0.3 to +6V, these pins have protection but if by any chance due to transient undershoots or overshoots exceed the maximum ratings the ENC28J60 may stop responding and you will spend hours scratching your head trying to find where is the bug on the firmware.
A large number of communication with the ENC28J60 related issues questions and reports on the Microchip Users forum, end being not firmware problems but hardware problems.
Adding the resistors (100-300Ω) is not mandatory, just recommended and this varies with each design.
You probably seen that the ENC28J60 has several pairs of Vdd-Vss pins, they are not connected internally, then on your circuit/prototype you must connect them all and each pair must have a 0.1µF ceramic bypass capacitor as close as possible to the pin.
There are more fine details with some components and that are a recurrent theme of questions asked in the forum...
The ethernet transformer or RJ45 jack with magnetics. The ethernet transformer is part of the circuit, and for this particular controller you must feed current to the differential output amplifier through the center tap of the TX transformer.
You can use a standalone transformer or a jack with integrated magnetics, some of these integrated jacks also include a pair of LEDs that you can use to show link status and network activity.
There are many brands and models of transformers and jacks with integrated magnetics that will work fine, but there are some characteristics that you must check:
- Both windings (TX and RX) must have a 1:1 turns ratio
- The primary of the TX transformer must have a pin to the center tap of it and not include a common mode choke in series (see figure below)
- Primary inductance of 350µH
- and at least 40dB of Common Mode Rejection from 0.1 to 10MHz
The crystal, it has to be 25.000 MHz, not 24 not 26, 25 MHz no more no less and as specified in the datasheet +/-50ppm. This has to do with the timing specifications of the IEEE 802.3 standard, if your ENC28J60 oscillator is running at a different frequency, it will have a very hard time to communicate with other IEEE 802.3 compliant devices.
Resistor values for RBIAS and the differential TX/RX signals. The differential output amplifier requires an external bias resistor (R17 in the schematic) which determines the shape of the output signal, a wrong value could cause deformation of the signal making the ENC28J60 unable to communicate with other devices on the network, latest revisions of the ENC28J60 (revisions B5 and later) require a 2.32KΩ 1% resistor, previous revisions 2.7KΩ 1%.
Unfortunately there is not an easy way to determine with revision of the ENC28J60 by just looking at the chip, there is no revision indication on the devices markings. Obviously if you have the chip connected to a microcontroller you can read the contents of the EREVID register or open a support ticket with Microchip and ask them if they can provide you the revision number based on the fabrication trace code printed on the chip, like "072544V".
Unless you are getting the chips from a distributor with old inventory, most chips today are revision B5 or later. Long time ago Microchip provided some guidelines when the B5 revision was released based on the different packages, take in account that this may no longer be valid:
- ENC28J60-I/ML Rev B5, QFN package
- ENC28J60-I/SO Rev B5, SO28 package
- ENC28J60-I/SP Rev B5, SPDIP28 package
- ENC28J60/SSC01 Rev B5, SSOP28 package
- ENC28J60/ML Rev B1/B4, QFN package
- ENC28J60/SO Rev B1/B4, SO28 package
- ENC28J60/SS Rev B1/B4, SSOP28 package
- ENC28J60/SP Rev B1/B4, SPDIP28 package
For the differential output and input, four 49.9Ω 1% are required, you can use 50 or 50.1 but make sure that they are all the same. Do not use 5% or 10% resistors.
Last but not least, the Ferrite Bead or what it looks as an inductor in the datasheet and schematics. The ferrite bead is just that, a chunk of conductive ferrite (obviously of specific characteristics) use to reduce common mode noise. If you are not able to find a ferrite bead don't just remove it from the circuit, you still need to feed the center tap of the TX transformer for the ENC28J60 output to work, just connect Vdd directly to the center tap, I'd not recommend this if you are planning to use this on a real world application, but for a prototype and learning the circuit will work fine without the ferrite bead.
OK, let's focus now on the microcontroller
In the previous version of this project I used a PIC18F4620 8-bit microcontroller, and suggested that also a PIC18F452 or its new reincarnation the PIC18F4520 could be used. I'll cover this topic in more detail in the article describing how to build the firmware image based on the Microchip TCP/IP Stack.
You can still use a PIC18F452 or PIC18F4620, but if you are planning to use the latest version of the Microchip TCP/IP Stack (current is v5.25) you will need more program memory, even with all optimizations enabled and few modules of the TCP/IP Stack enabled, the compiled code barely fits on a 64KB device such as the PIC18F4620. Then to get some extra room for the application, this time I used a PIC18F4685 that has 96KB of program memory.
You can also use a 28-pin device with fewer I/O pins, such as the PIC18F2685. There are also some new XLP (Extra Low Power) devices available in SOIC and SDIP 28-pin packages, that I'm about to test that have up to 128KB of program memory, such as the PIC18F27J13.
I mentioned before that I'll be powering the PIC18F4685 with a 5V supply, it is also possible to use a PIC18LF4685 powered with 3.3V and avoid using a level translator, but in this case you must take in account that the maximum CPU clock gets reduced, I really want to use the full 10MIPS of the PIC184685, then I'll stick with using a 5V power supply.
There are many clock configurations supported by the PIC18F microcontroller family, you can use the internal clock generator, you can use an external Resistor/Capacitor, a Ceramic resonator, a crystal or directly feed an appropriate clock signal to the clock input pin. I had at hand in my lab several "can oscillators", like the ones used by Microchip on the PICDEM2+ demo board, then for this project I used an external 10MHz clock source, the firmware will configure the clock to use the internal PLL module bringing the internal clock speed of the CPU to 40MHz.
If you want to store configuration information and use the HTTP server module and be able to modify the contents served by the web server without having to compile and program again the microcontroller with a new image, it's highly recommended to use an external memory can be accessed using the SPI interface. For this project I'll use a Microchip 25LC1024 1Mbit serial EEPROM (the previous PIC10T project used a 25LC256 256Kbit serial EEPROM).
The serial EEPROM will share the SPI interface with the ethernet controller, we only need to use an extra output pin to control the Chip Select signal of the memory chip.
To complete the circuit, I added five LEDs connected to different I/O pins, two tactile switches or push buttons, a serial RS-232 transceiver, and a character LCD module.
The LCD is a 2 lines x 20 character standard module with parallel interface and HD44780 or equivalent controller, that can be interfaced with the microcontroller using only 4 data bits and 3 control signals.
It is another thing that is not strictly required to run the TCP/IP Stack but if the microcontroller has it, it comes very handy for troubleshooting and for some applications to take advantage of the UART interface, then the circuit includes a RS-232 level translator like a MAX232 or equivalent. In this particular case I used a ST202, take in account that some of these transceiver may have different requirements for the capacitors that need to be used, again you will avoid headaches by taking a quick look to the datasheet and confirm which ones are required for your part, in the ST202 they are ceramic 0.1µF.
One more thing (no, no, I'm not Steve Jobs), on the schematic you will also find a 6-pin header to permit programming of the microcontroller via the standard Mirochip ICSP interface. From the previous version I changed the pinout of this header to match the pins of the RJ-11 adapter from Microchip (seen on the picture) and the PICKit2 or PICKit3 programmers.
Building the prototype
Given that the microcontroller, ethernet controller, memory, etc, are all available in DIP packages my first attempt to put the circuit together was using a solderless breadboard.
The only issues to resolve were the RJ-45 jack with integrated magnetics and the ferrite bead that, since I was planning to try different configurations I just put together a small sort of breakout board on a piece of prototype board, with the RJ-45, the 49.9% resistors, the 0.1µF capacitors connected to them and on the bottom side I soldered the ferrite bead between to pads, and added few pins to plug the thing to the solderless breadboard. This way I had now a module that I was able to reuse on different projects.
Here is an old picture of how the very first circuit looked on a solderless breadboard
Having the circuit on a solderless breadboard was very useful to try different things, I removed or replaced resistors in series with the SPI signals and found that in some cases the communication between the microcontroller and the ENC28J60 was not very reliable, I tested multiple clock configurations, including taking the clock from the ENC28J60 CLKOUT pin using one of the buffers of the 74ACT125 to convert the voltage level and feeding the output directly to the clock input of the PIC18, tried different LCD modules, etc.
You have to take in account that this type of prototype bread boards add stray capacitances and all sorts of glitches, particularly to high speed digital pulses, so you must keep wires short and neat, flat to the surface of the breadboard, add some extra 0.1µF ceramic capacitors, here and there, and double check, better said triple check that everything is connected where is supposed to before you apply power.
Once I was happy with the design and the preliminary results of running the Microchip TCP/IP Stack on this prototype, I moved to a more permanent configuration, now using a prototype circuit board, with wire wrapped sockets for all integrated circuits and doing a combination of soldering and wire wrapping to make all the connections.
The picture below shows how the prototype board looks on the bottom side.
No doubt Murphy is always present and many times things don't work as one expected or don't work at all !! Having the two prototypes assembled was a good opportunity to do some experiments and learn some troubleshooting tricks.
After the ENC28J60 became available, activity on the Ethernet subforum of the Microchip Users Forum started to increase dramatically, we started to share our experiences with the ENC28J60 and the Microchip TCP/IP Stack, many users where asking interesting questions, other not very interesting too, but since then we had a fantastic exchange of ideas.
Here are some of the questions and tips of what I -better said- we learned.
You will notice that in some circuits there is a pull-up resistor on the ENC28J60 RESET pin and in some others not. Why is that ?
The ENC28J60 has an internal weak pull-up resistor, there is no need for an external resistor and unless strictly necessary for your application there is no need to control this pin from the microcontroller.
There is a quick way to test if the ENC28J60 is working.
Before you connect it to the microcontroller, or holding the microcontroller in RESET, ie you just let the ENC28J60 work alone, given that the Power-on Reset (POR) internal circuitry is always enabled, when you supply power to the ENC28J60 (be aware that for proper POR operation the minimum rise rate for Vdd must meet the specified value of 0.05V/ms) the oscillator will start and after a very small Start-up timer expires, the internal registers of the ENC28J60 will be loaded with their default values and the CLKOUT pin will begin to show the default frequency of 6.25MHz.
If you have an oscilloscope or a frequency meter you can double check that you are getting the right clock frequency on the CLKOUT output pin.
With the registers loaded with the default values the ENC28J60 is ready to operate. If you connect your circuit to a live Ethernet network port, the ENC28J60 will try to establish the link and the LED connected to the LEDA will lit if the link was successfully established and if there is any activity on the network, LEDB will start blinking showing that the ENC28J60 is receiving packets.
If you don't see this happening, don't waste your time trying to figure what is wrong with the firmware, you have a hardware problem !!!
What are some troubleshooting steps then:
Measure the voltage on the VCAP pin, it should be around 2.5V. If that pin does not show any voltage you most probably forgot to connect some Vdd/Vss pins, remember ALL of them need to be connected, or you have a damaged chip.
Check for the oscillator signal on the CLKOUT output, if you don't see a nice rectangular 6.25MHz pulses, you may have some issues with the external crystal, or forgot to connect the Vddosc and or Vssosc pins.
If the oscillator is working and you believe that the ENC28J60 is properly powered (remember you need a supply able to handle at least 180mA when the ENC28J60 is in transmit mode), double check the polarity of the TPIN+/TPIN- and TPOUT+/TPOUT- connections to the ethernet transformer or MagJack, this is a very common mistake.
Another pin you can measure is the RBIAS pin, you should see there a DC voltage of 1.2V.
The ENC28J60 feels hot, it is that normal ?
Yes, the ENC28J60 may dissipate over 600mW, depending on the package you are using and the ambient temperature, the chip will feel hot-warm to the touch, an IR gun pointed to the may show 40-55C.
Interface with the microcontroller
As I mentioned before, the microcontroller uses the SPI interface to communicate with the ENC28J60. The interface uses at least three different signals, SDI (Serial Data In), SDO (Serial Data Out) and SCK (Serial Clock), these signals can be shared among several devices that support SPI. Remember that whatever device you connect to a shared SPI bus, it must be able to put its SDO or SO pin in 3-state or high impedance when it is not selected.
For each device you have on the SPI bus (ENC28J60, Serial EEPROM, etc), you will need a separate Chip Select (CS) signal. It is very common that most devices use an active low chip select pin, then remember on the microcontroller to initialize the I/O pins properly, and as a good design practice include a pull-up resistor on the CS pin of each device to make sure that during power up or while the I/O pin controlling that signal is on high impedance the device is not selected.
Very frequently communication problems with the ENC28J60 reported in the users forum end being issues with the SPI interface use or configuration. For example, some devices including the ENC28J60 have specific timing parameters when using the SPI interface, one of them is called the CS Hold Time, which means how long the program needs to hold CS on the select level after a data transfer took place to let the device complete its internal process.
This hold time may be different as with the ENC28J60 for different type of operations, if you are accessing the ETH registers or the memory buffer the minimum hold time is 10ns, but if you are accessing the MAC and MII registers, the hold time is 210ns. With some fast microcontrollers the program may be raising the CS pin too soon, and that will abort the internal operation that the ENC28J60 was performing and the communication will become unreliable.
Some forum members asked how the SPI signals look like. Below is an oscilloscope screen capture of the SCK and CS signals, you can notice the over and undershoots we talked about, some of that "ringing" is also added by the oscilloscope probes but the pulses are there.
The following picture shows a screen capture form a logic analyzer with probes on the ENC28J60 CS pin, the SPI signals SCK, SDO, SDI, the Serial EEPROM CS pin and the output of the main clock source (the 10MHz can oscillator).
After playing for a while with this prototype, I started putting together other prototypes and also produced some commercial versions of several boards using the ENC28J60 and PIC microcontrollers. I'll talk more about them in a separate article.
With the hardware done, we are ready now to build the firmware image of the Microchip TCP/IP Stack for it.