📄 macinit.c
字号:
}////////////////////////////////////////////////////////////////////////////////// Initialize MAC and BDMA Controller //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void MacInitialize(void){ int pos;// Disable MAC and BDMA interrupts ///////////////////////////////////////////// Disable_Int(nMAC_RX_INT ); // Disable MAC Rx Interrupt Disable_Int(nMAC_TX_INT ); // Disable MAC Tx Interrupt Disable_Int(nBDMA_RX_INT); // Disable BDMA Rx Interrupt Disable_Int(nBDMA_TX_INT); // Disable BDMA Tx Interrupt// BDMA and MAC interrupt vector setup ///////////////////////////////////////// SysSetInterrupt(nMAC_RX_INT , MAC_Rx_isr ); // MAC Rx ISR SysSetInterrupt(nMAC_TX_INT , MAC_Tx_isr ); // MAC Tx ISR SysSetInterrupt(nBDMA_RX_INT, BDMA_Rx_isr); // BDMA Rx ISR SysSetInterrupt(nBDMA_TX_INT, BDMA_Tx_isr); // BDMA Tx ISR // reset PHY, (restart AN) ///////////////////////////////////////////////////// ResetPhyChip();// Set the initial condition of the BDMA, and MAC ////////////////////////////// BDMARXCON = BDMARXCON_RxRS; // Reset BDMAC Receiver BDMATXCON = BDMATXCON_TxRS; // Reset BDMAC Transceiver MACCON = MACCON_SwReset; // MAC Block Reset BDMARXLSZ = MaxRxFrameSize; // // Set the BDMA Tx/Rx Frame Descriptor ///////////////////////////////////////// TxFDInitialize(); // Init Tx buffer descriptors list RxFDInitialize(); // Init Rx buffer descriptors list #if MAC_ADDR_FROM_IIC_EEPROM// Get MAC Address From IIC EEPROM ////////////////////////////////////////////// MacAddrReadIIC(MyMacSrcAddr);#else // manually setting the MAC address MyMacSrcAddr[0] = 0x00; MyMacSrcAddr[1] = 0x00; MyMacSrcAddr[2] = 0xf0; MyMacSrcAddr[3] = 0x11; MyMacSrcAddr[4] = 0x00; MyMacSrcAddr[5] = 0x00;#endif/* Copy MAC Address to global variable */ for(pos = 0; pos < 4; ++pos) { gCam0_Addr0 = (gCam0_Addr0 << 8) | MyMacSrcAddr[pos]; } for(pos = 4; pos < 6; ++pos) { gCam0_Addr1 = (gCam0_Addr1 << 8) | MyMacSrcAddr[pos]; } gCam0_Addr1 = (gCam0_Addr1 << 16) ;/* Set CAM0 register : 0x9100~0x9103, 0x9104, 0x9105 */ CAM_Reg(0) = gCam0_Addr0; CAM_Reg(1) = gCam0_Addr1;// CAM Enable Register(CAMEN) ////////////////////////////////////////////////// CAMEN = 0x0001; // CAM Address 0 = valid CAMCON = gCamCon; // CAM control register // Enable interrupt BDMA Rx and MAC Tx interrupt Enable_Int(nBDMA_RX_INT); // enable BDMA Receive interrupt Enable_Int(nMAC_TX_INT ); // enable BDMA Transmit interrupt // Configure the BDMA and MAC control registers //////////////////////////////// MACCON = gMacCon; // MAC Control Register BDMATXCON = gBdmaTxCon; // BDMA Transmit Control Register MACTXCON = gMacTxCon; // MAC Transmit Control Register BDMARXCON = gBdmaRxCon; // BDMA Receive Control Register MACRXCON = gMacRxCon; // MAC Receive Control Register}////////////////////////////////////////////////////////////////////////////////// Reset The Phychip, Auto-Negotiation Enable //////////////////////////////////////////////////////////////////////////////////////////////////////////////////void ResetPhyChip(void){ int tm1en; // timer 1 enable flag TIME tm; // TIME struct U32 sec; // start time, sec U32 val; // PHY register value // MiiStationWrite ( PHY_CNTL_REG , // control register PHYHWADDR , // PHY address ENABLE_AN | // enable autonegotiation RESTART_AN // restart autonegotiation ); tm1en = TimerEnabled(1); // read timer 1 enable flag if(tm1en == 0) {// timer 1 disabled => enable timer 1 ////////////////////////////////////////// TimerReset(1); // reset timer 1 TimerInit(1,(ONE_SECOND/TICKS_PER_SECOND)); // init timer 1 TimerStart(1); // start timer 1 } GetSysTime(1,& tm); // read start time, convert to ms sec = tm.tm_sec; // start time sec do {// wait AN complete, 3 sec GetSysTime(1,& tm); // read start time, convert to ms val = MiiStationRead(PHY_STATUS_REG, PHYHWADDR); } while((val & PHYSTAT_AN_COMPLETE) == 0 && tm.tm_sec < sec + 3); if(tm1en == 0) { TimerStop(1); // stop timer }// read chip status register val = MiiStationRead(PHY_CHIPSTAT_REG,PHYHWADDR); if((val & PHYCHIPSTAT_LINKUP) == 0) {// Print("\nLink down"); } if((val & PHYCHIPSTAT_FULLDUPLEX) != 0) {// link up bit ignored gMacCon |= MACCON_FullDup; MACCON |= MACCON_FullDup; // set full duplex bit } else { gMacCon &=~MACCON_FullDup; // clear full duplex bit MACCON &=~MACCON_FullDup; // clear full duplex bit }}/* * Function : MiiStationRead, MiiStationWrite * Description : MII Interface Station Management Register Read or Write * Input : PhyInAddr = PHY internal register address * PhyAddr = PHY unique address * PhyWrData = When Write * Output : PhyRdData = WhenRead */void MiiStationWrite(U32 PhyInAddr, U32 PhyAddr, U32 PhyWrData){ int i=1000 ; STADATA = PhyWrData; // Station management data register STACON = // Station control register ( PhyInAddr | // PHY register address (Addr) PhyAddr | // PHY address (PHY) STACON_Busy| // Busy bit (Busy) STACON_Wr | // Write bit (Wr) gStaCon // MDC clock ); while((STACON & STACON_Busy)); while(i--); // delay physet}U32 MiiStationRead(U32 PhyInAddr, U32 PhyAddr) { U32 PhyRdData ; STACON = PhyInAddr | PhyAddr | STACON_Busy | gStaCon; while( (STACON & STACON_Busy) ) ; PhyRdData = STADATA ; return(PhyRdData);}////////////////////////////////////////////////////////////////////////////////// Interrupt Service Routine for MAC Tx ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void MAC_Tx_isr(void){ sFrameDes * frame; // Descriptor pointer U32 status; // status of transmitted descriptor U32 CTxPtr; // current BDMA transmitted descriptor// CTxPtr = BDMATXPTR; while(gCTxFDPtr != CTxPtr) { frame = (sFrameDes *) gCTxFDPtr; // // Check CPU ownership// if Owner is BDMA then break if( (frame->DataPtr & fOwnership_BDMA) ) { // Owner of descriptor is BDMA => descriptor is not transmitted //////////////// break; } status = (frame->StatusLength >> 16) & 0xffff;// divch remove from else if(status & TXFDST_Under) {gsMacTxStatus.UnderErr++;} // Underrun (TXFDST_Under) if(status & TXFDST_ExColl) {gsMacTxStatus.ExCollErr++;}// Excessive Collision (TXFDST_ExColl) if(status & TXFDST_TxDeffer){gsMacTxStatus.TxDefferedErr++;} // Transmit deffered (TXFDST_TxDeffer) if(status & TXFDST_Paused) {gsMacTxStatus.sPaused++;} // Paused (TXFDST_Paused) if(status & TXFDST_Defer) {gsMacTxStatus.DeferErr++;} // TXFDST_Defer if(status & TXFDST_NCarr) {gsMacTxStatus.NCarrErr++;} // No Carrier sense// fake collision signal didn't come from PHY for 1.6us. (TXFDST_SQErr) //////// if(status & TXFDST_SQErr) {gsMacTxStatus.sSQE++;} if(status & TXFDST_LateColl){gsMacTxStatus.LateCollErr++;}// Late collision if(status & TXFDST_TxPar) {gsMacTxStatus.TxParErr++;} // Transmit Parity Error if(status & TXFDST_TxHalted){gsMacTxStatus.sTxHalted++;}// Transmission halted if(status & TXFDST_Comp) { // MAC transmit or discards one packet (TXFDST_Comp) /////////////////////////// gsMacTxStatus.MacTxGood++ ; } else {// Save Error status// Print MAC Debug status ////////////////////////////////////////////////////// MacDebugStatus(); // Set MAC/BDMA Tx control register for next use. BDMATXCON = gBdmaTxCon; MACTXCON = gMacTxCon; }// Clear Framedata pointer already used. frame->StatusLength = (U32)0x0; gCTxFDPtr = (U32)frame->NextDes; } // end while loop}////////////////////////////////////////////////////////////////////////////////// Interrupt Service Routine for MAC Rx ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void MAC_Rx_isr(void) { }////////////////////////////////////////////////////////////////////////////////// Interrupt Service Routine for BDMA Tx ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void BDMA_Tx_isr(void) { }int MACRecv(U8 * data, U32 * status, int * size) { sFrameDes * frame; // pointer to Rx descriptor U32 * dst; // desination address U32 * src; // source address int wlen; // data length words int len; // data lenght if(data == 0 || status == 0 || size == 0) { return(0); } if(gRxFDCnt == 0) { return(0); } // frame = (sFrameDes *) gRRxFDPtr; if((frame->DataPtr & fOwnership_BDMA)) { // owner DMA return(0); // => exit } *status = (frame->StatusLength >> 16) & 0xFFFF; // frame status len = frame->StatusLength & 0xFFFF; // frame length if(len > *size) { // out of input buffer len = *size; // reset length to sizeof buffer } else { *size = len; // readed bytes to buffer } dst = (U32 *) data; // destination address src = (U32 *) frame->DataPtr; // source address wlen = len >> 2; // words count while(wlen-- > 0) { *dst++ = *src++; } if(len & 0x3) {// copy remain bytes data = (U8 *) dst; // reset data pointer wlen = *src; // read source word switch(len & 0x3) { case 3 : *(data + 2) = (wlen >> 16) & 0xFF; case 2 : *(data + 1) = (wlen >> 8) & 0xFF; case 1 : *(data + 0) = wlen & 0xFF; break; } }// Disable_Int(nGLOBAL_INT); gRxFDCnt--; frame->StatusLength = 0x0; // clear frame status frame->DataPtr |= fOwnership_BDMA; // owner DMA gRRxFDPtr = (U32) frame->NextDes; // move read pointer Enable_Int(nGLOBAL_INT); if((BDMARXCON & BDMARXCON_RxEn) == 0) { BDMARXCON |= BDMARXCON_RxEn; } return(1);}////////////////////////////////////////////////////////////////////////////////// flush Rx BD /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int MACRxFlush(void){ sFrameDes * frame; // current frame descriptor pointer int cnt; // Rx BD count int fn; // frame number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -