📄 macinit.c
字号:
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* macinit.c KS32C50100 : version 1.0 */
/* */
/* COMPONENT */
/* */
/* DESCRIPTION */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* */
/* FUNCTIONS */
/* */
/* Include All MAC & BDMAC Initialize Routine */
/* */
/* DEPENDENCIES */
/* */
/* */
/*************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "std.h"
#include "sysconf.h"
#include "isr.h"
#include "mac.h"
#include "uart.h"
#include "pollio.h"
#include "timer.h"
#include "memory.h"
#include "iic.h"
/*
* Define MAC address source, IIC EEPROM or set value by manual
*/
#define MAC_ADDR_FROM_IIC_EEPROM 1
#define KS32C5000_BUG_FETCH 1
sFrameDescriptor RxFDBaseAddr[MaxRxFrameDescriptors]; // Tx Frame Descriptor
sMACFrame RxFBABaseAddr[MaxRxFrameData]; // Tx Frame Buffer
sFrameDescriptor TxFDBaseAddr[MaxTxFrameDescriptors]; // Rx Frame Descriptor
sMACFrame TxFBABaseAddr[MaxTxFrameData]; // Rx Frame Buffer
// Global variables used for MAC driver
volatile U32 gMacCon = FullDup ;
volatile U32 gMacTxCon = EnComp ;
volatile U32 gMacRxCon = RxEn | StripCRC ;
volatile U32 gBdmaTxCon = BTxBRST | BTxMSL110 | BTxSTSKO ;
#ifdef LITTLE
volatile U32 gBdmaRxCon = BRxDIE | BRxEn | BRxLittle | BRxMAINC | BRxBRST | \
BRxNLIE | BRxNOIE | BRxSTSKO ;
#else
volatile U32 gBdmaRxCon = BRxDIE | BRxEn | BRxBig | BRxMAINC | BRxBRST | \
BRxNLIE | BRxNOIE | BRxSTSKO ;
#endif
volatile U32 gCamCon = CompEn | BroadAcc | GroupAcc;
volatile U32 gDuplexValue = 0 ;
volatile U32 gCTxFDPtr, gWTxFDPtr ;
volatile U32 gCRxFDPtr, gPreviousFdp=0 ;
volatile U32 gCam0_Addr0 = 0 , gCam0_Addr1 = 0 ;
volatile U8 MyMacSrcAddr[6] ;
volatile int WatchDogTime = 0 ;
volatile int gErrorPacketCnt =0 ;
#if KS32C5000_BUG_FETCH
volatile U32 gPreviousStatusField = 0 ;
#endif
volatile int BdmaRxDoneFlagForLoopBackCheck = 0 ;
volatile int MacTxDoneFlagForLoopBackCheck = 0 ;
// Global variable structure for store status
pMACTxStatus gsMacTxStatus = {0,0,0,0,0,0,0,0,0,0,0} ;
pMACRxStatus gsMacRxStatus = {0,0,0,0,0,0,0,0,0} ;
pBDMATxStatus gsBdmaTxStatus = {0,0,0} ;
pBDMARxStatus gsBdmaRxStatus = {0,0,0,0,0} ;
extern TIME tm0 ;
/*
* void LanInitialize(void)
*/
void LanInitialize(void)
{
// Reset the PHY chip and start Auto-negotiat
ResetPhyChip() ;
// Read MAC address from IIC EEPROM
GetMyMacAddr() ;
// Initialize MAC and BDMA controller
// MacInitialize() ;
}
/*
* void MacInitialize(void)
* Initialize MAC and BDMA Controller
*/
void MacInitialize(void)
{
/*-----------------------------------------------------------------*
* 1. 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
/*-----------------------------------------------------------------*
* 2. BDMA and MAC interrupt vector setup. *
*-----------------------------------------------------------------*/
SysSetInterrupt(nMAC_RX_INT, MAC_Rx_isr) ;
SysSetInterrupt(nMAC_TX_INT, MAC_Tx_isr) ;
SysSetInterrupt(nBDMA_RX_INT, BDMA_Rx_isr) ;
SysSetInterrupt(nBDMA_TX_INT, BDMA_Tx_isr) ;
/*-----------------------------------------------------------------*
* 3. Set the initial condition of the BDMA, and MAC *
*-----------------------------------------------------------------*/
BDMARXCON = BRxRS ; // Reset BDMAC Receiver
BDMATXCON = BTxRS ; // Reset BDMAC Transceiver
MACCON = Reset ;
BDMARXLSZ = MaxRxFrameSize+40 ; // 1520
MACCON = gMacCon ;
/*-----------------------------------------------------------------*
* 4. Set the BDMA Tx/Rx Frame Descriptor *
*-----------------------------------------------------------------*/
TxFDInitialize() ;
RxFDInitialize() ;
/*-----------------------------------------------------------------*
* 5. Set the CAM Control register and the MAC address value *
*-----------------------------------------------------------------*/
// CAM0 register of CAM registers : 0x9100~0x9103, 0x9104, 0x9105
CAM_Reg(0) = gCam0_Addr0;
CAM_Reg(1) = gCam0_Addr1;
// CAM Enable Register(CAMEN)
CAMEN = 0x0001 ;
CAMCON = gCamCon ;
/*-----------------------------------------------------------------*
* 6. Enable interrupt BDMA Rx and MAC Tx interrupt. *
*-----------------------------------------------------------------*/
Enable_Int(nBDMA_RX_INT);
Enable_Int(nMAC_TX_INT);
//Enable_Int(nMAC_RX_INT);
/*-----------------------------------------------------------------*
* 7. Configure the BDMA and MAC control registers. *
*-----------------------------------------------------------------*/
ReadyMacTx() ;
ReadyMacRx() ;
}
void MacWatchdogInit(void)
{
sFrameDescriptor *pRxFDptr ;
MACRXCON = 0x0 ; // Disable MAC contoller Rx operation
BDMARXCON = 0x0 ; // Disable BDMA contoller Rx operation
BDMARXCON = BRxRS ; // Reset BDMAC Receiver
Disable_Int(nBDMA_RX_INT) ; // Disable BDMA Rx Interrupt
BDMARXLSZ = MaxRxFrameSize ; // 1520
pRxFDptr = (sFrameDescriptor *)gCRxFDPtr ;
BDMARXPTR = gCRxFDPtr = (U32)(pRxFDptr->NextFrameDescriptor) ;
Enable_Int(nBDMA_RX_INT);
BDMARXCON = gBdmaRxCon ;
MACRXCON = gMacRxCon ;
}
/*
* void TxFDInitialize(void) ;
* Initialize Tx frame descriptor area-buffers.
*/
void TxFDInitialize(void)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
U32 FrameDataAddr;
U32 i;
// Get Frame descriptor's base address.
// +0x4000000 is for setting this area to non-cacheable area.
BDMATXPTR = (U32)TxFDBaseAddr + 0x4000000;
gWTxFDPtr = gCTxFDPtr = BDMATXPTR;
// Get Transmit buffer base address.
FrameDataAddr = (U32)TxFBABaseAddr + 0x4000000;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr;
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxTxFrameDescriptors; i++) {
if(pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->FrameDataPtr =
(U32)(FrameDataAddr & fOwnership_CPU);
pFrameDescriptor->Reserved = (U32)0x0;
pFrameDescriptor->StatusAndFrameLength = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
} // end for loop
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
/*
* void RxFDInitialize(void) ;
* Initialize Rx frame descriptor area-buffers.
*/
void RxFDInitialize(void)
{
sFrameDescriptor *pFrameDescriptor;
sFrameDescriptor *pStartFrameDescriptor;
sFrameDescriptor *pLastFrameDescriptor = NULL;
U32 FrameDataAddr;
U32 i;
// Get Frame descriptor's base address.
// +0x4000000 is for setting this area to non-cacheable area.
BDMARXPTR = (U32)RxFDBaseAddr + 0x4000000;
gCRxFDPtr = BDMARXPTR;
// Get Transmit buffer base address.
FrameDataAddr = (U32)RxFBABaseAddr + 0x4000000;
// Generate linked list.
pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr;
pStartFrameDescriptor = pFrameDescriptor;
for(i=0; i < MaxRxFrameDescriptors; i++) {
if(pLastFrameDescriptor == NULL)
pLastFrameDescriptor = pFrameDescriptor;
else pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;
pFrameDescriptor->FrameDataPtr =
(U32)(FrameDataAddr | fOwnership_BDMA | 0x4000000 );
pFrameDescriptor->Reserved = (U32)0x0;
pFrameDescriptor->StatusAndFrameLength = (U32)0x0;
pFrameDescriptor->NextFrameDescriptor = NULL;
pLastFrameDescriptor = pFrameDescriptor;
pFrameDescriptor++;
FrameDataAddr += sizeof(sMACFrame);
} // end for loop
// Make Frame descriptor to ring buffer type.
pFrameDescriptor--;
pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
}
/*
* Function : ReadyMacTx
* Description : set Tx Registers related with BDMA & MAC to transmit
* packet.
*/
void ReadyMacTx(void)
{
BDMATXCON = gBdmaTxCon ;
MACTXCON = gMacTxCon ;
}
/*
* Function : ReadyMacRx
* Description : set Rx Registers related with BDMA & MAC to Receive packet.
*/
void ReadyMacRx(void)
{
BDMARXCON = gBdmaRxCon ;
MACRXCON = gMacRxCon ;
}
/*
* Function : MacTxGo
* Description : MAC Transfer Start for interactive mode
*/
void MacTxGo(void)
{
// Enable MAC and BDMA Transfer
if (!(BDMATXCON & BTxEn)) BDMATXCON |= BTxEn ;
MACTXCON |= TxEn ;
}
/*
* Function : Lan_WatchDog
* Description : LAN watchdog function
*/
void Lan_WatchDog(void)
{
WatchDogTime++ ;
if ( !(WatchDogTime%100) ) {
if (gCRxFDPtr == gPreviousFdp) {
MacWatchdogInit() ;
}
else gPreviousFdp = gCRxFDPtr ;
}
}
/*
* Function : GetMyMacAddr
* Description : Get MAC Address From IIC EEPROM
*/
void GetMyMacAddr(void)
{
U8 *MacAddr;
U8 TempAddr[MAC_ADDR_SIZE];
int i;
gCam0_Addr0 = gCam0_Addr1 = 0 ;
#if MAC_ADDR_FROM_IIC_EEPROM // when use IIC EEPROM for store MAC address
MacAddr=(U8 *)IICReadInt((U8)IIC_DEV_0,(U32)iMacAddrPtr,(U32)MAC_ADDR_SIZE) ;
#else // When manual ly setting the MAC address
MacAddr[0] = 0x00 ;
MacAddr[1] = 0x00 ;
MacAddr[2] = 0xf0 ;
MacAddr[3] = 0x11 ;
MacAddr[4] = 0x00 ;
MacAddr[5] = 0x00 ;
#endif
/* Get MAC Address */
for (i=0;i<(int)MAC_ADDR_SIZE;i++) TempAddr[i] = *MacAddr++;
/* Copy MAC Address to global variable */
for (i=0;i<(int)MAC_ADDR_SIZE-2;i++)
gCam0_Addr0 = (gCam0_Addr0 << 8) | TempAddr[i] ;
for (i=(int)(MAC_ADDR_SIZE-2);i<(int)MAC_ADDR_SIZE;i++)
gCam0_Addr1 = (gCam0_Addr1 << 8) | TempAddr[i] ;
gCam0_Addr1 = (gCam0_Addr1 << 16) ;
/* Set CAM0 register : 0x9100~0x9103, 0x9104, 0x9105 */
CAM_Reg(0) = gCam0_Addr0;
CAM_Reg(1) = gCam0_Addr1;
for (i=0;i<(int)MAC_ADDR_SIZE;i++) MyMacSrcAddr[i] = TempAddr[i];
}
/*
* Function : ResetPhyChip
* Description : Reset The Phychip, Auto-Negotiation Enable
*/
void ResetPhyChip(void)
{
U32 value ;
if(MACCON&MACLoop) MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB|PHY_FULLDUPLEX) ;
else {
#if 0 /* This routine is not used, because have some error */
// 1. Reset PHY chip
MiiStationWrite(PHY_CNTL_REG, PHYHWADDR, RESET_PHY ) ;
while ( (MiiStationRead(PHY_CNTL_REG, PHYHWADDR) & RESET_PHY) ) ;
// 2. Restart PHY auto-negotiation
MiiStationWrite(PHY_CNTL_REG, PHYHWADDR, ENABLE_AN | RESTART_AN);
// 3. Wait until auto-negotiation complete
while ( !(MiiStationRead(PHY_STATUS_REG, PHYHWADDR) & AN_COMPLETE) ) ;
// 4. Read auto-negotiation status from PHY register
value = MiiStationRead(PHY_ANLPAR_REG, PHYHWADDR) ;
// 5. Set PHY control register as auto-negotiation status
if ( (value & DR100_TX_FULL) ) {
MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB|PHY_FULLDUPLEX) ;
gDuplexValue = FullDup ;
}
else if ( (value & DR100_TX_HALF) )
MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB) ;
else if ( (value & DR10_TX_FULL) ) {
MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,PHY_FULLDUPLEX) ;
gDuplexValue = FullDup ;
}
else MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,0) ;
#endif
}
//MiiStationWrite(PHY_CNTL_REG, PHYHWADDR, ENABLE_AN | RESTART_AN);
//MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB|PHY_FULLDUPLEX) ;
//MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB) ;
//MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,PHY_FULLDUPLEX) ;
//MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,0) ;
//gDuplexValue = FullDup ;
}
/*
* 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)
{
STADATA = PhyWrData ;
STACON = PhyInAddr | PhyAddr | MiiBusy | PHYREGWRITE ;
while( (STACON & MiiBusy) ) ;
delay_physet() ;
}
U32 MiiStationRead(U32 PhyInAddr, U32 PhyAddr)
{
U32 PhyRdData ;
STACON = PhyInAddr | PhyAddr | MiiBusy ;
while( (STACON & MiiBusy) ) ;
PhyRdData = STADATA ;
return PhyRdData ;
}
void delay_physet(void)
{
int i=1000 ;
while(i--) ;
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -