Уменя следующая проблема: Ethrnet на LPC2368 и DP83848I не хотит работать. Вернее настроить PHY получилось, проходит автосогласование, определяется скорость и дуплекс, загораются светодиоды Speed, Duplex, даже иногда подмигивает Act, на свитче тоже загораются соответствующие светодиоды, но в процессор не передается ни каких пакетов!
Уже чего только не перепробывал, смотрел примеры и от иара и от кейла. Все вроди сделано правильно!!!? А Пакеты не принимаются (не изменяется индекс производства приема, соответственно и нет принятых данных).
Подскажите уже долго бодаюсь, но ни чего не получается.
Вот код инициализации
Код
void Eth_init(pInt8U MAC)
{
Int32U Reg,wait;
PCONP_bit.PCENET = 1;
POWERDOWN_bit.POWERDOWN = 0;
PINMODE2 = 0xA02A020A;
PINSEL2 &= ~(0xF03F030F);
PINSEL2 |= 0x50150105;
PINMODE3 = 0x0000000A;
PINSEL3 &= ~(0x0000000F);
PINSEL3 |= 0x00000005;
MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX |
MAC1_RES_RX | MAC1_RES_MCS_RX |
MAC1_SIM_RES | MAC1_SOFT_RES;
COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;
MCFG = MCFG_RES_MII;
for (wait = 100; wait; wait--);
MAC1 = COMMAND = MCFG = 0;
MAC1 = MAC1_PASS_ALL;
MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
IPGT = IPGT_HALF_DUP;
IPGR = IPGR_DEF;
CLRT = CLRT_DEF;
MAXF = ETH_MAX_FLEN;
SUPP = 0;
TEST = 0;
MCFG = 0x0018; // ((CCLK = 48 MHz)/20 = 2,4 MHz)
MCMD = 0;
COMMAND = CR_PASS_RUNT_FRM | CR_PASS_RX_FILT | CR_RMII;
SA0 = (((Int16U)MAC[5]) << 8) | ((Int16U)MAC[4]);
SA1 = (((Int16U)MAC[3]) << 8) | ((Int16U)MAC[2]);
SA2 = (((Int16U)MAC[1]) << 8) | ((Int16U)MAC[0]);
for(PhyAddr = 1; PhyAddr < 32; ++PhyAddr)
{
// PHY DP83848
if((PHY_read(PhyAddr, PHY_PHYIDR1) & 0xFFFF) != 0x2000)
continue;
if ((PHY_read(PhyAddr, PHY_PHYIDR2) & 0xFFFF) == 0x5C90)
break;
}
if(PhyAddr == 32) return;
PHY_write (PhyAddr,PHY_BMCR, BMCR_RESET);
for (wait = 0; wait < 0x100000; wait++)
{
Reg = PHY_read(PhyAddr,PHY_BMCR);
if(!(Reg & BMCR_RESET)) break;
}
Reg = PHY_read_ext(PhyAddr,PHY_RBR);
if(Reg != (RBR_RMII_MODE | RBR_ELAST_BUFF_2_bit))
PHY_write_ext(PhyAddr,PHY_RBR, RBR_RMII_MODE | RBR_ELAST_BUFF_2_bit);
Reg = PHY_read (PhyAddr,PHY_BMSR);
if(Reg & BMSR_NOPREAM)
MCFG |= MCFG_SUPP_PREAM;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED | LEDCR_DRV_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
Delay_us(500000);
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED | LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
PHY_write_ext(PhyAddr,PHY_MICR, MICR_INTEN | MICR_INT_OE);
PHY_write_ext(PhyAddr,PHY_MISR, MISR_LINK_INT_EN);
Eth_descr_init();
Reg = ANAR_100BT_FULL_D | ANAR_100BT | ANAR_10BT_FULL_D | ANAR_10BT |
ANAR_SELECTOR_IEEE_802_3u;
PHY_write(PhyAddr,PHY_ANAR, Reg);
PHY_write(PhyAddr,PHY_BMCR, BMCR_AN_EN);
EthState.AllField = 0;
}
{
Int32U Reg,wait;
PCONP_bit.PCENET = 1;
POWERDOWN_bit.POWERDOWN = 0;
PINMODE2 = 0xA02A020A;
PINSEL2 &= ~(0xF03F030F);
PINSEL2 |= 0x50150105;
PINMODE3 = 0x0000000A;
PINSEL3 &= ~(0x0000000F);
PINSEL3 |= 0x00000005;
MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX |
MAC1_RES_RX | MAC1_RES_MCS_RX |
MAC1_SIM_RES | MAC1_SOFT_RES;
COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;
MCFG = MCFG_RES_MII;
for (wait = 100; wait; wait--);
MAC1 = COMMAND = MCFG = 0;
MAC1 = MAC1_PASS_ALL;
MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
IPGT = IPGT_HALF_DUP;
IPGR = IPGR_DEF;
CLRT = CLRT_DEF;
MAXF = ETH_MAX_FLEN;
SUPP = 0;
TEST = 0;
MCFG = 0x0018; // ((CCLK = 48 MHz)/20 = 2,4 MHz)
MCMD = 0;
COMMAND = CR_PASS_RUNT_FRM | CR_PASS_RX_FILT | CR_RMII;
SA0 = (((Int16U)MAC[5]) << 8) | ((Int16U)MAC[4]);
SA1 = (((Int16U)MAC[3]) << 8) | ((Int16U)MAC[2]);
SA2 = (((Int16U)MAC[1]) << 8) | ((Int16U)MAC[0]);
for(PhyAddr = 1; PhyAddr < 32; ++PhyAddr)
{
// PHY DP83848
if((PHY_read(PhyAddr, PHY_PHYIDR1) & 0xFFFF) != 0x2000)
continue;
if ((PHY_read(PhyAddr, PHY_PHYIDR2) & 0xFFFF) == 0x5C90)
break;
}
if(PhyAddr == 32) return;
PHY_write (PhyAddr,PHY_BMCR, BMCR_RESET);
for (wait = 0; wait < 0x100000; wait++)
{
Reg = PHY_read(PhyAddr,PHY_BMCR);
if(!(Reg & BMCR_RESET)) break;
}
Reg = PHY_read_ext(PhyAddr,PHY_RBR);
if(Reg != (RBR_RMII_MODE | RBR_ELAST_BUFF_2_bit))
PHY_write_ext(PhyAddr,PHY_RBR, RBR_RMII_MODE | RBR_ELAST_BUFF_2_bit);
Reg = PHY_read (PhyAddr,PHY_BMSR);
if(Reg & BMSR_NOPREAM)
MCFG |= MCFG_SUPP_PREAM;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED | LEDCR_DRV_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
Delay_us(500000);
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED | LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
PHY_write_ext(PhyAddr,PHY_MICR, MICR_INTEN | MICR_INT_OE);
PHY_write_ext(PhyAddr,PHY_MISR, MISR_LINK_INT_EN);
Eth_descr_init();
Reg = ANAR_100BT_FULL_D | ANAR_100BT | ANAR_10BT_FULL_D | ANAR_10BT |
ANAR_SELECTOR_IEEE_802_3u;
PHY_write(PhyAddr,PHY_ANAR, Reg);
PHY_write(PhyAddr,PHY_BMCR, BMCR_AN_EN);
EthState.AllField = 0;
}
Вот код контроля состояния линии, который крутится в основном цикле
Код
void Eth_Check_State(void)
{
Int32U Reg;
Reg = PHY_read_ext (PhyAddr,PHY_PHYSTS);
if (Reg & PHYSTS_MII_INT)
{
if(!EthState.ValidInit)
{
if(Reg & PHYSTS_LINK_STS)
{
EthState.Link = 1;
if(Reg & PHYSTS_SPEED_STS)
{
SUPP = SUPP_SPEED_10M;
EthState.Speed = 0;
}
else
{
SUPP = SUPP_SPEED_100M;
EthState.Speed = 1;
}
if(Reg & PHYSTS_DUPLEX_STS)
{
MAC2 |= MAC2_FULL_DUP;
COMMAND |= CR_FULL_DUP;
IPGT = IPGT_FULL_DUP;
EthState.Duplex = 1;
}
else
{
MAC2 &= ~(MAC2_FULL_DUP);
COMMAND &= ~(CR_FULL_DUP);
IPGT = IPGT_HALF_DUP;
EthState.Duplex = 0;
}
EthState.ValidInit = 1;
PHY_write_ext(PhyAddr,PHY_LEDCR, LEDCR_ALL_PHY_DRV);
COMMAND |= (CR_RX_EN | CR_TX_EN);
MAC1 |= MAC1_REC_EN;
}
else
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
}
}
else
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
if(Reg & PHYSTS_LINK_STS)
PHY_write(PhyAddr,PHY_BMCR, BMCR_AN_EN | BMCR_RESTART_AN);
}
PHY_read_ext(PhyAddr,PHY_MISR);
}
else
{
if(Reg & PHYSTS_LINK_STS)
{
if( ((EthState.Speed) && (Reg & PHYSTS_SPEED_STS)) ||
((!EthState.Speed) && (!(Reg & PHYSTS_SPEED_STS))) ||
((EthState.Duplex) && (!(Reg & PHYSTS_DUPLEX_STS))) ||
((!EthState.Duplex) && (Reg & PHYSTS_DUPLEX_STS)) )
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
if(Reg & PHYSTS_LINK_STS)
PHY_write(PhyAddr,PHY_BMCR,
BMCR_AN_EN | BMCR_RESTART_AN);
}
}
}
}
{
Int32U Reg;
Reg = PHY_read_ext (PhyAddr,PHY_PHYSTS);
if (Reg & PHYSTS_MII_INT)
{
if(!EthState.ValidInit)
{
if(Reg & PHYSTS_LINK_STS)
{
EthState.Link = 1;
if(Reg & PHYSTS_SPEED_STS)
{
SUPP = SUPP_SPEED_10M;
EthState.Speed = 0;
}
else
{
SUPP = SUPP_SPEED_100M;
EthState.Speed = 1;
}
if(Reg & PHYSTS_DUPLEX_STS)
{
MAC2 |= MAC2_FULL_DUP;
COMMAND |= CR_FULL_DUP;
IPGT = IPGT_FULL_DUP;
EthState.Duplex = 1;
}
else
{
MAC2 &= ~(MAC2_FULL_DUP);
COMMAND &= ~(CR_FULL_DUP);
IPGT = IPGT_HALF_DUP;
EthState.Duplex = 0;
}
EthState.ValidInit = 1;
PHY_write_ext(PhyAddr,PHY_LEDCR, LEDCR_ALL_PHY_DRV);
COMMAND |= (CR_RX_EN | CR_TX_EN);
MAC1 |= MAC1_REC_EN;
}
else
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
}
}
else
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
if(Reg & PHYSTS_LINK_STS)
PHY_write(PhyAddr,PHY_BMCR, BMCR_AN_EN | BMCR_RESTART_AN);
}
PHY_read_ext(PhyAddr,PHY_MISR);
}
else
{
if(Reg & PHYSTS_LINK_STS)
{
if( ((EthState.Speed) && (Reg & PHYSTS_SPEED_STS)) ||
((!EthState.Speed) && (!(Reg & PHYSTS_SPEED_STS))) ||
((EthState.Duplex) && (!(Reg & PHYSTS_DUPLEX_STS))) ||
((!EthState.Duplex) && (Reg & PHYSTS_DUPLEX_STS)) )
{
MAC1 &= ~(MAC1_REC_EN);
COMMAND &= ~(CR_RX_EN | CR_TX_EN);
EthState.AllField = 0;
Reg = LEDCR_DRV_SODLED | LEDCR_DRV_LNKLED |
LEDCR_DRV_ACTLED | LEDCR_SPDLED |
LEDCR_LNKLED | LEDCR_ACTLED;
PHY_write_ext(PhyAddr,PHY_LEDCR, Reg);
if(Reg & PHYSTS_LINK_STS)
PHY_write(PhyAddr,PHY_BMCR,
BMCR_AN_EN | BMCR_RESTART_AN);
}
}
}
}
Если кто знает в чем проблема, подскажите пожалуста, а то я уже больше недели бодаюсь.
И если код правильный, то может проблема в аппаратке какая то... я ни как не могу разобраться.
PDFки перелапатил и в доль и в поперек, но решения проблемы найти не удалось, а то что предлагают на форуме не помогает!