Hi,
I work with the Zoom development kit from Logic PD. I test the EMAC/MDIO module. I write a programm receiving Ethernet frames but the receive buffers queue stays empty.
I think my EMAC configuration should be wrong. Have you got an idea of mistakes, please ?
Here is my program:
* Initialization :
// reset emac module.
EMAC->SOFTRESET = 1;
while (EMAC->SOFTRESET != 0) {}
// init emac module.
//------------------
// make sure emac control interrupts are disabled.
EMAC_CTRL->C0RXTHRESHEN = 0;
EMAC_CTRL->C1RXTHRESHEN = 0;
EMAC_CTRL->C0RXEN = 0;
EMAC_CTRL->C1RXEN = 0;
EMAC_CTRL->C0TXEN = 0;
EMAC_CTRL->C1TXEN = 0;
EMAC_CTRL->C0MISCEN = 0;
EMAC_CTRL->C1MISCEN = 0;
// enable the psc and config pinmux for the desired interface.
EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_EMAC, PSC_ENABLE);
EVMOMAPL138_pinmuxConfig(PINMUX_MDIO_REG, PINMUX_MDIO_MASK, PINMUX_MDIO_VAL); //MDIO shared by both RMII and MII
EVMOMAPL138_pinmuxConfig(PINMUX_MII_MDIO_EN_REG, PINMUX_MII_MDIO_EN_MASK, PINMUX_MII_MDIO_EN_VAL); //pinmux to select gpio bank2 pin6
GPIO_setDir(GPIO_BANK2, GPIO_PIN6, GPIO_OUTPUT); //needed to control the MII mido clock enable
//PINMUXING
EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_0, PINMUX_MII_MASK_0, PINMUX_MII_VAL_0);
EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_1, PINMUX_MII_MASK_1, PINMUX_MII_VAL_1);
SYSCONFIG->KICKR[0] = KICK0R_UNLOCK;
SYSCONFIG->KICKR[1] = KICK1R_UNLOCK;
CLRBIT(SYSCONFIG->CFGCHIP[3], 0x00000100);
//Enable the MII MDIO clock line
GPIO_setOutput(GPIO_BANK2, GPIO_PIN6, OUTPUT_LOW);
// init header descriptor pointer regs to 0.
for (i = 0; i < 8; i++)
{
EMAC->TXHDP[i] = 0;
EMAC->RXHDP[i] = 0;
}
// clear all network statistics registers.
#ifndef BOOT
memset((uint8_t *)NET_STAT_REG_BASE, 0, NET_STAT_REG_NUM_BYTES);
#endif
// setup local MAC address, only channel 0 is valid.
// program all 8, only need to set MACADDRHI for index = 0.
// use duplicate address for all unused channels.
// TODO: read MAC address from SPI flash.
EMAC->MACINDEX = 0;
EMAC->MACADDRHI = 0x01020304;
EMAC->MACADDRLO = 0x00000506 | MACADDRLO_VALID | MACADDRLO_MATCHFILT;
for (i = 1; i < 8; i++)
{
EMAC->MACINDEX = i;
EMAC->MACADDRLO = 0x00000506;
}
EMAC->MACSRCADDRHI = 0x01020304;
EMAC->MACSRCADDRLO = 0x00000506;
// initialize receive channel free buffer count regs, if buffer flow
// control is to be enabled.
// NOTE: this example does not use buffer flow control.
// no multicast addresses, clear MAC address hash registers.
EMAC->MACHASH1 = 0;
EMAC->MACHASH2 = 0;
// enable receive and transmit channel interrupts.
EMAC->RXINTMASKSET = 1;
EMAC->TXINTMASKSET = 1;
// init receive buffer offset and max length.
EMAC->RXBUFFEROFFSET = 0;
EMAC->RXMAXLEN = MAX_PACKET_SIZE;
// enable unicast chan 0 only.
EMAC->RXUNICASTSET = 0x01;
// config receive multicast/broadcast/promiscuous channel enable.
EMAC->RXMBPENABLE = 0;
SETBIT(EMAC->RXMBPENABLE, RXCAFEN);
EMAC->RXMBPENABLE = 0x01E02020; //enable reception of almost all frames inc error
// initialize receive/transmit descriptor list queues.
g_rx_active_head = tmp_rx_desc = g_rx_desc;
for (i = 0; i < MAX_RX_BUFFERS; i++)
{
tmp_rx_desc->buffer = &g_rx_buffers[i * (MAX_PACKET_SIZE + PACKET_ALIGN)];
tmp_rx_desc->buff_offset_length = MAX_PACKET_SIZE;
tmp_rx_desc->flags_pkt_length = EMAC_DSC_FLAG_OWNER;
if (i == (MAX_RX_BUFFERS - 1))
{
tmp_rx_desc->next = 0;
g_rx_active_tail = tmp_rx_desc;
g_rx_queue_active = 1;
}
else
{
tmp_rx_desc->next = (uint32_t)(tmp_rx_desc + 1);
tmp_rx_desc++;
}
}
// clear MAC, receive, and transmit control registers.
EMAC->MACCONTROL |= EMAC_RMII_SPEED_100;
// prepare for receive by writing pointer to head of receive buffer
// desriptor list.
EMAC->RXHDP[0] = (uint32_t)g_rx_desc;
// enable receive / transmit DMA controllers...set GMIIEN.
EMAC->RXCONTROL = 1;
EMAC->TXCONTROL = 1;
SETBIT(EMAC->MACCONTROL, GMIIEN | FULLDUPLEX );
SETBIT(EMAC->EMCONTROL, SOFT);
// init the mdio regs.
MDIO->CONTROL = MDIO_CTRL_ENABLE |
MDIO_CTRL_FAULT |
MDIO_CTRL_FAULTENB |
MDIO_CLK_DIVISOR;
while (CHKBIT(MDIO->CONTROL, MDIO_CTRL_IDLE)) {}
// look for an active phy...takes up to 50 us for each phy to be checked.
for (i = 0; i < 32; i++)
{
if (MDIO->ALIVE)
{
// at least one phy has acknowledged us...break the loop.
break;
}
USTIMER_delay(50);
}
if (MDIO->ALIVE)
{
#if DEBUG
printf("found an active phy: 0x%08X\n\n", MDIO->ALIVE);
#endif
}
else
{
#if DEBUG
printf("error connecting to phy!\n");
#endif
return (ERR_INIT_FAIL);
}
// identify which phy is active.
for (i = 0; i < 32; i++)
{
if (CHKBIT(MDIO->ALIVE, bitval_u32[i]))
{
if (CHKBIT(MDIO->ALIVE, ~bitval_u32[i]) && CHKBIT(MDIO->ALIVE, ~bitval_u32[3]))
{
// more than one phy connected!
#if DEBUG
printf("more than one phy connected: 0x%08X\r\n", MDIO->LINK);
#endif
g_active_phy_id = 0xFF;
return (ERR_INIT_FAIL);
}
else
{
g_active_phy_id = i;
break;
}
}
}
MDIO->USERPHYSEL0 = 0;
* Body :
while( 1 )
{
if ((!CHKBIT(EMAC->RXINTSTATRAW, RX0PEND)) ||
(CHKBIT(tmp_rx_flags, EMAC_DSC_FLAG_OWNER)))
{
return (ERR_ENET_QUEUE_EMPTY);
}
}
I send Ethernet frames from my computer using Colasoft program.
Best regards,
Nicolas ROBIN