brain1986 0 9 марта, 2011 Опубликовано 9 марта, 2011 · Жалоба Добрый день! Я мучаю плату 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(); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться