EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Initialising Olimex LPC-2378STK MAC device

Started by jdauchot July 16, 2009
Hi

I am trying to intialise the LPC22378 MAC device to send ethernet packets.

I found some demo code to do this but it fails on this bit of code

#define PHY_BMCR 0x0000
#define BMCR_SPEED_100 0x2000
#define BMCR_DUPLEX 0x0100

WritePHY( PHY_BMCR, BMCR_SPEED_100 | BMCR_DUPLEX) ;

void WritePHY( DWORD PHYReg, DWORD PHYData)
{

MAC_MCMD = 0x0000; /* write command */
MAC_MADR = PhyAddr | PHYReg; /* [12:8] == PHY addr, [4:0]=register addr */
MAC_MWTD = PHYData;
while ( MAC_MIND != 0 );
}
return;
}

It never returns from the function call and PhyAddr is set somewhere else and I do not its value at this point.

Also I have tried to find a user manual for the KS8721 PHY chip in google with no luck. Has any one got a link for it?

Many thanks

Jean-Jacques

An Engineer's Guide to the LPC2100 Series

----Original Message----
From: l...
[mailto:l...] On Behalf Of jdauchot
Sent: 16 July 2009 18:07 To: l...
Subject: [lpc2000] Initialising Olimex LPC-2378STK MAC
device

> Hi
>
> I am trying to intialise the LPC22378 MAC device to send
> ethernet packets.
>
> I found some demo code to do this but it fails on this
> bit of code
>
> #define PHY_BMCR 0x0000
> #define BMCR_SPEED_100 0x2000
> #define BMCR_DUPLEX 0x0100
>
> WritePHY( PHY_BMCR, BMCR_SPEED_100 | BMCR_DUPLEX) ;
>
> void WritePHY( DWORD PHYReg, DWORD PHYData) {
>
> MAC_MCMD = 0x0000; /* write command */
> MAC_MADR = PhyAddr | PHYReg; /* [12:8] == PHY addr,
> [4:0]=register addr */ MAC_MWTD = PHYData;
> while ( MAC_MIND != 0 );
> }
> return;
> }
>
> It never returns from the function call and PhyAddr is
> set somewhere else and I do not its value at this point.
>
> Also I have tried to find a user manual for the KS8721
> PHY chip in google with no luck. Has any one got a link
> for it?

This comes up 3rd on my google search...
http://www.chipdocs.com/datasheets/datasheet-pdf/Micrel/KS8721.html

I've got that Olimex board and the PHY physical address seems to be
random when you start the board. To make it work I had to poll each
possible value of PHY address and see if I got a response.

--
Tim Mitchell

Good day,

Datasheet on micro you can find on DigiKey:

http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&nameW6-1028-5-ND

>
> I am trying to intialise the LPC22378 MAC device to send ethernet packets.
>

Here are changes I made to demo code for Micrel PHY.Works fine for me.

Set PhyAddr as:

PhyAddr = findPHYAdress();

before any other PHY operations.

/* Micrel_100001 PHY */
#define MII_MICREL_ID 0x00221400
#define MII_MICREL21_ID (MII_MICREL_ID|0x210)
#define MII_MICREL_KSZ8721_ID (MII_MICREL21_ID|0x19)
#define PHY_REG_ESTAT 0x1F /* 100BASE-TX PHY Controller in Micrel */

void writePHY (unsigned char phyReg, unsigned long val)
{
unsigned int tout;

MAC_MADR = ((phyAddress & 0x1f) << 8) | phyReg;
MAC_MCMD = 0;
MAC_MWTD = val;

/* Wait utill operation completed */
tout = 0;
for (tout = 0; tout < MII_WR_TOUT; tout++) {
if ((MAC_MIND & MIND_BUSY) == 0) {
break;
}
}
}

unsigned short readPHY0(unsigned char phyAddr, unsigned char phyReg)
{
unsigned int tout;

MAC_MADR = ((phyAddr & 0x1f) << 8) | phyReg;
MAC_MCMD = MCMD_READ;

/* Wait until operation completed */
tout = 0;
for (tout = 0; tout < MII_RD_TOUT; tout++) {
if ((MAC_MIND & MIND_BUSY) == 0) {
break;
}
}
MAC_MCMD = 0;
return (MAC_MRDD);
}

unsigned short readPHY(unsigned char phyReg)
{
return readPHY0(phyAddress, phyReg);
}

inline unsigned long readPHYId0(unsigned char phyAddr)
{
return (readPHY0(phyAddr, PHY_REG_IDR1) << 16) | readPHY0(phyAddr, PHY_REG_IDR2);
}

unsigned long readPHYId(void)
{
return readPHYId0(phyAddress);
}

unsigned char findPHYAdress( void )
{
unsigned char phyAddress = 0;
unsigned long phyid;

while ((phyAddress < 32)) {
/* Read the PHY ID registers */
phyid = readPHYId0(phyAddress);

switch (phyid & 0xFFFFFFF0L) {
case MII_MICREL21_ID:
return phyAddress;
}
phyAddress++;
}
return (unsigned char) 0;
}

Best Regards,
Vladimir Sekissov

Hi Vladimir

Thanks for the info as always from the group.

I have gone pass the initialisation without a hang.
However, the LCD does not work anymore, probobly due tue corruption of the LPC2278 registers. Needs to look in to that.

The address of the phyAddr is either 1 or or 0x11.

Still have not transmitted any frames yet.
Debugging shows that the TXPRODUCEINDEX and the TXCONSUMEINDEX registers are not equal at the start of transmittng a frame. I am using a free demo code from google etc and learning hard from it.
Those name sound like sounds like a receipe from a menu or something.
I will offcourse read the menu(hoops the LPC2378 manual)

Regards

Jean-Jacques

--- In l..., "eryx67" wrote:
>
> Good day,
>
> Datasheet on micro you can find on DigiKey:
>
> http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&nameW6-1028-5-ND
>
> >
> > I am trying to intialise the LPC22378 MAC device to send ethernet packets.
> > Here are changes I made to demo code for Micrel PHY.Works fine for me.
>
> Set PhyAddr as:
>
> PhyAddr = findPHYAdress();
>
> before any other PHY operations.
>
> /* Micrel_100001 PHY */
> #define MII_MICREL_ID 0x00221400
> #define MII_MICREL21_ID (MII_MICREL_ID|0x210)
> #define MII_MICREL_KSZ8721_ID (MII_MICREL21_ID|0x19)
> #define PHY_REG_ESTAT 0x1F /* 100BASE-TX PHY Controller in Micrel */
>
> void writePHY (unsigned char phyReg, unsigned long val)
> {
> unsigned int tout;
>
> MAC_MADR = ((phyAddress & 0x1f) << 8) | phyReg;
> MAC_MCMD = 0;
> MAC_MWTD = val;
>
> /* Wait utill operation completed */
> tout = 0;
> for (tout = 0; tout < MII_WR_TOUT; tout++) {
> if ((MAC_MIND & MIND_BUSY) == 0) {
> break;
> }
> }
> }
>
> unsigned short readPHY0(unsigned char phyAddr, unsigned char phyReg)
> {
> unsigned int tout;
>
> MAC_MADR = ((phyAddr & 0x1f) << 8) | phyReg;
> MAC_MCMD = MCMD_READ;
>
> /* Wait until operation completed */
> tout = 0;
> for (tout = 0; tout < MII_RD_TOUT; tout++) {
> if ((MAC_MIND & MIND_BUSY) == 0) {
> break;
> }
> }
> MAC_MCMD = 0;
> return (MAC_MRDD);
> }
>
> unsigned short readPHY(unsigned char phyReg)
> {
> return readPHY0(phyAddress, phyReg);
> }
>
> inline unsigned long readPHYId0(unsigned char phyAddr)
> {
> return (readPHY0(phyAddr, PHY_REG_IDR1) << 16) | readPHY0(phyAddr, PHY_REG_IDR2);
> }
>
> unsigned long readPHYId(void)
> {
> return readPHYId0(phyAddress);
> }
>
> unsigned char findPHYAdress( void )
> {
> unsigned char phyAddress = 0;
> unsigned long phyid;
>
> while ((phyAddress < 32)) {
> /* Read the PHY ID registers */
> phyid = readPHYId0(phyAddress);
>
> switch (phyid & 0xFFFFFFF0L) {
> case MII_MICREL21_ID:
> return phyAddress;
> }
> phyAddress++;
> }
> return (unsigned char) 0;
> }
>
> Best Regards,
> Vladimir Sekissov
>


The 2024 Embedded Online Conference