Actualización: he leído más sobre esto y lo que puedo concluir es que el phy IC no se ha iniciado correctamente. Todavía no es capaz de averiguar cómo inicializar el dispositivo phy. Vaya a través de las configuraciones de código y correa y hágame saber dónde está el error.
Estoy usando el dispositivo K60DN512 con 8720A PHY IC. He escrito un programa simple para comunicarme con el PHY IC. Lo he comprobado en el analizador lógico y no recibo ninguna respuesta del dispositivo PHY. ¿Cuáles pueden ser las posibles causas?
Configuración de las correas del dispositivo PHY.
PHYAD [0]: tirado bajo.
MODO [2: 0]: 011 100Base-TX Full Duplex. Negociación automática deshabilitada. CRS está activo durante la recepción.
MDIO: alto tirado.
MDC: 1 Mhz.
Estoy usando el código generado por el experto en procesadores. Así que en ese caso no debería haber ningún error. ¿Cuál puede ser la posible razón del fracaso de la comunicación? El valor es 0 o 0xFFFF.
main(){
MAChandler = mac_Init(NULL);
Bit1_Init(NULL);
uint16_t id = 0;
uint16_t value = 0;
uint16_t timeout = 0;
uint16_t count = 0;
uint8_t sfr = 0;
const uint8_t netifLINK_DELAY = 3;
do {
mii_read(id, PHY_PHYIDR1, &value);
count++;
} while (value == 0xffff);
do {
value = 0xffff;
mii_read(id, sfr, &value);
if (value != 0xffff)
sfr++;
count++;
} while (sfr <= 0x1F);
uint16 config;
do {
config = 0x2200;
mii_write(id, PHY_BMCR, config);
uint16_t i, j;
for (i = 0; i < 0xFF; i++)
for (j = 0; j < 0xFFFF; j++)
;
mii_read(id, PHY_BMCR, &value);
count++;
} while (value != config);
}
int mii_write(int phy_addr, int reg_addr, uint16_t data) {
int timeout;
/* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;
/* Initiatate the MII Management write */ENET_MMFR /*(ch)*/=
0 | ENET_MMFR_ST(0x01) | ENET_MMFR_OP(0x01) | ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr) | ENET_MMFR_TA(0x02)
| ENET_MMFR_DATA(data);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++) {
if (ENET_EIR /*(ch)*/& ENET_EIR_MII_MASK)
break;
}
if (timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;
return 0;
}
/********************************************************************/
/*!
* \brief Read a value from a PHY's MII register.
* \param phy_addr Address of the PHY
* \param reg_addr Address of the register in the PHY
* \param data Pointer to location were read data will be stored
* \return 0 if write is successful; 1 if write times out
*
* mii_read() polls for the FEC's MII interrupt event (which should
* be masked from the interrupt handler) and clears it. If after a
* suitable amount of time the event isn't triggered, a non-zero value
* is returned.
*/
int mii_read(int phy_addr, int reg_addr, uint16_t *data) {
int timeout;
/* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;
Bit1_SetVal(NULL); // Indication that the MDIO transfer is about to begin.
/* Initiatate the MII Management read */ENET_MMFR /*(ch)*/= 0
| ENET_MMFR_ST(0x01) | ENET_MMFR_OP(0x2) | ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr) | ENET_MMFR_TA(0x02);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++) {
if (ENET_EIR /*(ch)*/& ENET_EIR_MII_MASK){
Bit1_ClrVal(NULL); // Indication that the MDIO transfer is complete.
break;
}
}
if (timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */ENET_EIR /*(ch)*/= ENET_EIR_MII_MASK;
uint16_t test = ENET_MMFR /*(ch)*/& 0x0000FFFF;
*data = ENET_MMFR /*(ch)*/& 0x0000FFFF;
return 0;
}