Перейти к содержанию
    

BF518F и Ethernet

Добрый день!

 

Я мучаю плату ADSP-BF518F EZ-Kit Lite.

Никак не получется настроить Ethernet (PHY микросхема DP83848). В качестве базового примера использую Power_On_Self_Test для этой платы.

 

Для начала хочется хотя бы просто смотреть все пакеты, которые приходят.

Но дело в том, что приходит непонятно что (даже MAC источника и приемника не совпадают ни с одним из МАСов в сети).

 

Сначала настраиваю буферы (как положено по 2 буфера на канал. Первый буфер в приемном (DMA1) канале на данные , второй на контрольные суммы и статус). Все по примеру.

 

Инициализирую пины (для MII или для RMII). Далее включаю тактирование, настраиваю частоту MII(RMII)и прочие параметры, Задаю MAC.

Далее программный ресет микросхемы PHY. Читаю ID - все читается, все совпадает. Запускаю Autonegotiation. Все ок. Задаю EMAC_OPMODE (опять таки по примеру), Включаю приемный DMA.

И... и приходит всякая фигня :(

 

И еще

1. При проверке статуса НИКОГДА еще не было флага RX_OK. Все время был RX_COMP.

2. Если при обработке регнистра DMA1_IRQ_STATUS не сбравывать DMA_ERR, то он просто никогда не сбрасывается и данные прекращают читаться.

Просто в примере нигде данный флаг не сбрасывался.

 

Что делать?

 

Исходные коды:

unsigned char emac_tx_buff[EMAC_SIZEOF_TX];
unsigned char emac_rx_buff[EMAC_SIZEOF_RX];

ADI_ETHER_FRAME_BUFFER * emac_tx_data = (ADI_ETHER_FRAME_BUFFER *)emac_tx_buff;
ADI_ETHER_FRAME_BUFFER * emac_rx_data = (ADI_ETHER_FRAME_BUFFER *)emac_rx_buff;

ADI_ETHER_BUFFER emac_tx_discr;
ADI_ETHER_BUFFER emac_rx_discr;

//-----------------------------------------------------------------------------
void EMAC_SetupRxBuffer(void)
{
//Setup rx
memset(&emac_rx_discr, 0, sizeof(emac_rx_discr));

emac_rx_discr.FrmData = emac_rx_data;

emac_rx_discr.Dma[0].NEXT_DESC_PTR = &(emac_rx_discr.Dma[1]);
emac_rx_discr.Dma[0].START_ADDR = (unsigned int)emac_rx_discr.FrmData;
emac_rx_discr.Dma[0].CONFIG.b_DMA_EN = 1;	/* enabled */
emac_rx_discr.Dma[0].CONFIG.b_WNR    = 1;	/* write to memory */
emac_rx_discr.Dma[0].CONFIG.b_DI_EN  = 0;	/* enable interrupt */
emac_rx_discr.Dma[0].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
emac_rx_discr.Dma[0].CONFIG.b_NDSIZE = 5;	/* 5 half words is desc size */
emac_rx_discr.Dma[0].CONFIG.b_FLOW   = 7;	/* large desc flow */

emac_rx_discr.Dma[1].NEXT_DESC_PTR = mac_rx_discr.Dma[0]);
emac_rx_discr.Dma[1].START_ADDR    = (unsigned int)&emac_rx_discr.IPHdrChksum;
emac_rx_discr.Dma[1].CONFIG.b_DMA_EN = 1;	/* enabled */
emac_rx_discr.Dma[1].CONFIG.b_WNR    = 1;	/* write to memory */
emac_rx_discr.Dma[1].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
emac_rx_discr.Dma[1].CONFIG.b_DI_EN  = 1;	/* enable interrupt */
emac_rx_discr.Dma[1].CONFIG.b_NDSIZE = 0;	/* must be 0 when FLOW is 0 */
emac_rx_discr.Dma[1].CONFIG.b_FLOW   = 0;	/* stop */
}

//-----------------------------------------------------------------------------
void EMAC_SetupTxBuffer(void)
{
//Setup tx

memset(&emac_tx_discr, 0x00, sizeof(emac_tx_discr));

emac_tx_discr.Dma[0].NEXT_DESC_PTR = &(emac_tx_discr.Dma[1]);
emac_tx_discr.Dma[0].START_ADDR    = (unsigned int)emac_tx_discr.FrmData;
emac_tx_discr.Dma[0].CONFIG.b_DMA_EN = 1;        /* enabled */
emac_tx_discr.Dma[0].CONFIG.b_WNR    = 0;        /* read to memory */
emac_tx_discr.Dma[0].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
emac_tx_discr.Dma[0].CONFIG.b_NDSIZE = 5;        /* 5 half words is desc size */
emac_tx_discr.Dma[0].CONFIG.b_FLOW   = 7;        /* large desc flow */

emac_tx_discr.Dma[1].NEXT_DESC_PTR = &(emac_tx_discr.Dma[0]);
emac_tx_discr.Dma[1].START_ADDR    = (unsigned int)&emac_tx_discr.StatusWord;
emac_tx_discr.Dma[1].CONFIG.b_DMA_EN = 1;        /* enabled */
emac_tx_discr.Dma[1].CONFIG.b_WNR    = 1;        /* write to memory */
emac_tx_discr.Dma[1].CONFIG.b_WDSIZE = 2;        /* wordsize is 32 bits */
emac_tx_discr.Dma[1].CONFIG.b_DI_EN  = 1;        /* enable interrupt */
emac_tx_discr.Dma[1].CONFIG.b_NDSIZE = 0;        /* must be 0 when FLOW is 0 */
emac_tx_discr.Dma[1].CONFIG.b_FLOW   = 0;        /* stop */
}

//-----------------------------------------------------------------------------
void EMAC_InitMIIPort(void)
{
#ifdef EMAC_RMII
 *pPORTF_MUX &= ~(0x0FC0);
 asm("SSYNC;");
 *pPORTF_FER |= 0x7F80;
 asm("SSYNC;");
#else
 *pPORTF_MUX &= ~(0x0FCF);
 asm("SSYNC;");
 *pPORTF_FER |= 0x7FBF;
 asm("SSYNC;");
#endif

*pPORTG_MUX &= ~(0x0003);
asm("SSYNC;");
*pPORTG_FER |= 0x0007;
asm("SSYNC;");

}

//-----------------------------------------------------------------------------
void EMAC_SetupSysRegs(void)
{
unsigned short tmp;
// Setup system regs
*pVR_CTL |= PHYCLKOE; // Enable PHY output

#ifdef EMAC_RMII
 tmp = SET_MDCDIV(12);
#else
 tmp = SET_MDCDIV(24);
#endif

tmp |= RXDWA | RXCKS; //Config DMA
*pEMAC_SYSCTL = tmp;

*pEMAC_MMC_CTL = RSTC | CROLL | MMCE;

// Init DMA channels TX, RX
*pDMA2_X_COUNT =  0;
*pDMA2_X_MODIFY = 4;
*pDMA2_Y_COUNT =  0;
*pDMA2_Y_MODIFY = 0;

*pDMA1_X_COUNT =  0;
*pDMA1_X_MODIFY = 4;
*pDMA1_Y_COUNT =  0;
*pDMA1_Y_MODIFY = 0;
}

//-----------------------------------------------------------------------------
void EMAC_SetupMACAddr(unsigned char * mac_addr)
{
// Setup MAC addr
*pEMAC_ADDRLO = *(unsigned int *)&mac_addr[0];
*pEMAC_ADDRHI = *(unsigned short *)&mac_addr[4];
}

//-----------------------------------------------------------------------------
void EMAC_EnableRxDMA(void)
{
memset(emac_rx_data, 0xFE, EMAC_SIZEOF_RX);
// Enable Rx DMA
*pDMA1_NEXT_DESC_PTR = &emac_rx_discr.Dma[0];
*pDMA1_CONFIG = *((unsigned short *)&emac_rx_discr.Dma[0].CONFIG);
}

//-----------------------------------------------------------------------------
void EMAC_PollMDCDone(void)
{
while(*pEMAC_STAADD & STABUSY);
}

//-----------------------------------------------------------------------------
unsigned short EMAC_RdPHYReg(unsigned short PHYAddr, unsigned short RegAddr)
{
EMAC_PollMDCDone();
*pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) | STABUSY;
EMAC_PollMDCDone();
return (unsigned short)*pEMAC_STADAT;
}

//-----------------------------------------------------------------------------
void EMAC_WrPHYReg(unsigned short PHYAddr, unsigned short RegAddr, unsigned int Data)
{
EMAC_PollMDCDone();
*pEMAC_STADAT = Data;
*pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) | STAOP | STABUSY;
EMAC_PollMDCDone();
}

//-----------------------------------------------------------------------------
int EMAC_Init(void)
{
unsigned int tmp;

EMAC_SetupRxBuffer();
EMAC_SetupTxBuffer();

EMAC_InitMIIPort();

EMAC_SetupSysRegs();

EMAC_SetupMACAddr(MyMAC);

#ifdef EMAC_RMII
 *pEMAC_OPMODE |= RMII;
#endif

EMAC_PollMDCDone();

// Read and check ID
tmp = EMAC_RdPHYReg(0x01, EMAC_REG_PHYID1); // Read ID1
if(tmp != EMAC_REG_PHYID1_VAL) return 0;
sprintf(str, "PHY1 = 0x%X\n\r", tmp);
USART0_PutStr(str);

tmp = EMAC_RdPHYReg(0x01, EMAC_REG_PHYID2); //Read ID2
if(tmp != EMAC_REG_PHYID2_VAL) return 0;
sprintf(str, "PHY2 = 0x%X\n\r", tmp);
USART0_PutStr(str);

// Internal reset (write bit 15 of BMCR(0x00))
EMAC_WrPHYReg(0x01, 0x00 /*BMCR*/, (1 << 15));
// Read reset complete 
tmp = 100000;
while((EMAC_RdPHYReg(0x01, EMAC_REG_BMCR) & EMAC_REG_BMCR_RESET) & (--tmp));
if(!tmp) return 0;
USART0_PutStr("Reset complete\n\r");

//Enable Auto Negotiation
tmp = EMAC_RdPHYReg(0x01, EMAC_REG_BMCR);
tmp |= EMAC_REG_BMCR_ANENABLE | EMAC_REG_BMCR_ANRESTART;
EMAC_WrPHYReg(0x01, EMAC_REG_BMCR, tmp);
// Read AN complete
tmp = 100000;
while(!(EMAC_RdPHYReg(0x01, EMAC_REG_BMSR) & EMAC_REG_BMSR_ANCOMP) & (--tmp));
if(!tmp) return 0;
USART0_PutStr("Auto Negotiation complete\n\r");

// Check link status
while(!(EMAC_RdPHYReg(0x01, EMAC_REG_BMSR) & EMAC_REG_BMSR_LSTATUS) & (--tmp));
if(!tmp) return 0;
USART0_PutStr("Link applied\n\r");

EMAC_EnableRxDMA();

// Turn on EMAC
tmp = *pEMAC_OPMODE;
tmp |= 	  ASTP | PR | RAF | FDMODE | RE;
*pEMAC_OPMODE = tmp;
return 1;
}


/*****************************************/
/* цикл обработки сообщения */
/*****************************************/

while(1)
{
irq_stat = *pDMA1_IRQ_STATUS;
if(irq_stat & DMA_DONE)
{
	*pDMA1_IRQ_STATUS = irq_stat; //Сброс DMA_DONE и DMA_ERR, если они есть
	int RXStat = emac_rx_discr.StatusWord;
	emac_rx_discr.StatusWord = 0;
	if(RXStat & RX_COMP)
	{
		int len = GET_RX_FRLEN(RXStat); 
                                         //Выводим то что получили
                                         //...
	}
	EMAC_EnableRxDMA();
}
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...