Hi All
After having a small difficulty with the demo project on an Olimex board it is interesting to discuss some details about the initialisation of the PHY chip to ensure that it initialises in the correct mode and has the correct address. This has resulted in a slight change in the project configuration code which you may like to take over from the details below.
At the time of writing the uTasker project for the SAM7X is delivered with configurations for two common evaluation boards: the ATMEL AT91SAM7X-EK and the Olimex SAM7-EX256.
The main difference between the Ethernet interface of the two boards is the use of different PHYSICAL layer devices: the AT91SAM7X-EK has a DAVICON DM9161A while the Olimex board uses the MICREL KS8721.
Fortunately the control of the PHYs are compatible (and standardised) to high degree. However the interface to these devices differs in some respects - mainly in the way that the PHYs are configured by port states on reset. It is typical to configure some PHY modes and the address of the device on the maintenance interface using pull-up and pull-downs at reset. Some of these configurations can be be reprogrammed later but a couple are critical so the Ethernet controller can even communicate with the PHY.
Examples of mode inputs are RMII mode, loopback or isolation mode.
The PHYs generally have a pull-up or pull-down to determine the stating mode if no external devices does it. This is also valid for the PHY address - for example the Micrel will default to address 0x01 since 4 address lines have pull-downs and ADD0 has a pull-up.
The configuration lines are also shared with other lines and so are generally connected also to the SAM7X. The SAM7X has pull-ups on its port lines by default and this can give a conflict with the PHY, which may have pull-downs. The question as to which wins the fight to determine the port state can not be determined so, if there is not also a stronger pull-up/down on the board to determine it, the defalt state is not really known.
The solution is to perform a second reset of the PHY while the SAM7X actively drives these configuration pins. This is performed in the Ethernet driver initialisation using the SAM7X feature of being able to generate a pulse on the reset output to reset external devices (without causing a CPU reset). Once the reset has completed, the SAM7X GPIOs can be programmed for MII use and the PHY is in the required mode.
It was found that the communication address of the PHY was not always as expected. The uTasker code uses 0x1f - ADD0..ADD4 = '11111' but the Olimex board, using Micrel PHY, was found to be defaulting to 0x01. This means that a check of the PHY ID (read on initialisation) was not causing a match and the Ethernet interface was subsequently not being initialised (this is interpreted as an error and the Ethernet initialisation is aborted).
A check of project code showed that the mode lines were correctly being derived on the second initialisation, but the PHY address lines were not. Since the code has been previously verified on Olimex boards it suggests that variations in the pull-up strengths between devices means that this may vary between boards and so a correction was necessary.
The following shows the improvement to ensure that the PHY address is controlled correctly.
In app_hw_sam7x.h the driving of the configuration lines are controlled using a define. The define varies between board type, and so there are 2 defines - one for the ATMEL and one for the OLIMEX board. The board type itself is selected in config.h.
ATMEL board code change
#define PHY_ADD_31 (PB04 | PB05 | PB06 | PB13 | PB14)
// DAVICON DM9161AE on ATMEL eval board
// remove pullup on TEST input (MII ERXDV) so that device goes to normal mode
// remove pullup on RMII input (MII ECOL) so that device uses MII mode
// drive power down mode to '0'
// drive PHY address to 0x1f (31)
#define DRIVE_PHY_OPTION_LINES() PIO_PUDR_B = (PB15 | PB16); PIO_PER_B = (PB18 | PHY_ADD_31); PIO_OER_B = (PB18 | PHY_ADD_31); PIO_CODR_B = PB18; \
PIO_SODR_B = (PHY_ADD_31);
The 5 connections from PB04, PB05, PB06, PB13 and PB14 drive the DAVICON pins (CRS, RXD0, RXD1, RXD2, RXD3) to '1' during the commanded reset. These lines latch in the PHY address on reset. Afterwards all pins are switched to their MII function.
OLIMEX board change
#define PHY_ADD_31 (PB05 | PB06 | PB13 | PB14)
// set the option lines as we would like them to be for the MICREL PHY
// drive to zero (default after reset)
// drive PHY address configuration lines to correct address value
#define DRIVE_PHY_OPTION_LINES() PIO_PER_B = (PCS_LPBK | ISOLATION_MODE | RMII_MODE | RMII_BACKTOBACK_MODE | PHY_ADD_31); \
PIO_OER_B = (PCS_LPBK | ISOLATION_MODE | RMII_MODE | RMII_BACKTOBACK_MODE | PHY_ADD_31); \
PIO_SODR_B = (PHY_ADD_31);
The 4 connections from PB05, PB06, PB13 and PB15 drive the MICREL pins (RXD0, RXD1, RXD2, RXD3) to '1' during the commanded reset. These lines latch in the PHY address on reset. Afterwards all pins are switched to their MII function.
The 5th address line (ADD0) is connected to the IRQ line of the PHY and defaults both at the SAM7X and MICREL to pull-up. Therefore this line doesn't need to be specifically driven. Afterwards it remains as input to detect interrupts originating from the PHY.
The modification for the Olimex board solved the problem. No known problems exist with the ATMEL board, but the change was successfully tested and should ensure that no problems are encountered in the future.
Regards
Mark