⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs8900.c

📁 44B0板子的检测程序 包括键盘 LED LCD SEG
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "cs8900.h"
#include "s3c44b0.h"
#include "lib_44b0.h"

unsigned short ReadReg(unsigned short offset);
void WriteReg(unsigned short offset, unsigned short value);
int  ChipReset(void);
void CopyTxFrameToChip(void);

/* Ethernet physical address of the chip*/
unsigned char gEtherAddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
int gPrevTxBidFail = 0;
int gRxLength;
int gTxLength;
unsigned char gRxDataBuf[1520];
unsigned char gTxDataBuf[1520];

/***********************************************************************/
/* ReadReg(): Read value from the Packet Pointer register at regOffset */
/***********************************************************************/
unsigned short ReadReg(unsigned short offset)
{
    CS8900_PPTR = offset;
    return (CS8900_PDATA);
}

/***********************************************************************/
/* WriteReg(): Write value to the Packet Pointer register at regOffset */
/***********************************************************************/
void WriteReg(unsigned short offset, unsigned short value)
{
    CS8900_PPTR = offset;
    CS8900_PDATA = value;
}

/********************************************/
/* DelayForAWhile(): Take ~2.0 microseconds */
/********************************************/
void DelayForAWhile(void)
{
    unsigned int t;
    t = (*(volatile unsigned int *)(0));
}

/***********************************************/
/* ChipReset(): Software reset the CS8900 chip */
/***********************************************/
int ChipReset(void)
{
    int j;
    unsigned short status;
    /* Reset chip */
     WriteReg(PP_SelfCtl, PP_SelfCtl_Reset);
    /* Wait about 125 msec for chip resetting in progress */
    for (j=0; j<100; j++)
    {
        DelayForAWhile();
    }
    /* check the PP_SelfStat_InitD bit if the chip successflly reset */
    for (j=0; j<3000; j++)
    {
        status=(ReadReg(PP_SelfStat) & PP_SelfStat_InitD);
        if ( status != 0 ) return 0  /* successful */;
    }
    return -1; /* fail */
}

/*********************************************************************/
/* CopyTxFrameToChip(): Copy Tx data from user buffer to CS8900 chip */
/*********************************************************************/
void CopyTxFrameToChip()
{
    int len;
    unsigned short *sdata;
    sdata = (unsigned short *)gTxDataBuf;
    len = gTxLength;
    if (len > 0)
    {
        /* Output contiguous words, two bytes at a time */
        while (len > 1)
        {
            CS8900_RTDATA = *sdata;
            sdata++;
            len -= 2;
        }
        /* If Odd bytes, copy the last one byte to chip */
        if (len == 1)
        {
            CS8900_RTDATA = *sdata;
        }
    }
    /* return and wait for TxEvent Interrupt */
}

/*****************************************************/
/* cs8900_poll_init(): Start up CS8900 for Poll Mode */
/*****************************************************/
int cs8900_poll_init()
{
    unsigned short chip_id, ia0, ia1, ia2;
    int status;
    /* gData */
    gPrevTxBidFail = 0;
    /* detect chip */
    chip_id = ReadReg(PP_ChipID);
    if (chip_id != CS8900_ID) return -1;
    /* software reset the chip */
    status = ChipReset();
    if (status != 0) return -1;
    /* set up ethernet hardware address */
    ia0=gEtherAddr[0]|(gEtherAddr[1]<<8);
    ia1=gEtherAddr[2]|(gEtherAddr[3]<<8);
    ia2=gEtherAddr[4]|(gEtherAddr[5]<<8);
    WriteReg(PP_IA+0, ia0 );
    WriteReg(PP_IA+2, ia1 );
    WriteReg(PP_IA+4, ia2 );
    /* set to Promiscuous mode to receive all network traffic */
    //WriteReg(PP_RxCTL, PP_RxCTL_Promiscuous|PP_RxCTL_RxOK);
    /* configure RxCTL to receive good frames for Indivual Addr, Broadcast, and Multicast */
    WriteReg(PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_Multicast);
    /* configure TestCTL (mode) */
    /* default: 0:half duplex;  0x4000=Full duplex*/
    WriteReg(PP_TestCTL, PP_TestCTL_HDX);
    /* set SerRxOn, SerTxOn in LineCTL ******/
    WriteReg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
    return 0;
}

/****************************************************/
/* cs8900_poll_recv(): Receive a frame in Poll mode */
/****************************************************/
int cs8900_poll_recv()
{
    unsigned short status, val;
    int len;
    unsigned short *data;
    unsigned char *cp;
    /* Step 1: check RxEvent Register */
	status = ReadReg(PP_RER);
    /* Step 2: Determine if there is Rx event */
	/* If nothing happened, then return. 0x0004 is the register ID.
	   If some bits in Bit 6 - Bit 15 are set, some Rx event happened. */
	if ( status == 0x0004 ) return 0;
    /* Step 3: Determine if there is Rx Error */
	/* If RxOk bit is not set, Rx Error occurred */
	if ( !(status & PP_RER_RxOK) ) 
	{
        /* Step 4: skip this received error frame */
        /* Note: Must skip this received error frame. Otherwise, CS8900 hangs here */
		/* Read the length of Rx frame */
        ReadReg(PP_Rx_LENGTH);
		/* Write Skip1 to RxCfg Register and also keep the current configuration.*/
		val = ReadReg(PP_RxCFG);
		val |= PP_RxCFG_Skip1; 
	    WriteReg(PP_RxCFG, val);
	    /* return failed */
		return -1; 
    }
 	/* Step 5: Read the length of Rx frame */
    gRxLength = ReadReg(PP_Rx_LENGTH);
 	/* Step 6: Read the Rx data from Chip and store it to user buffer */
    data = (unsigned short *)gRxDataBuf;
    len = gRxLength;
	/* read 2 bytes at a time */
    while (len >= 2)
    {
        *data = CS8900_RTDATA;
        data++;
        len -= 2;
    }
	/* if odd bytes, read the last byte from chip */
    if (len == 1) 
    {
        /* Read the last byte from chip */
		val = CS8900_RTDATA;
        /* point to the last one byte of the user buffer */
        cp = (unsigned char *)data;
	    /* truncate the word (2-bytes) read from chip to one byte */
        *cp = (unsigned char)(val & 0xff);
    }
    len = gRxLength;
    return len;
}

/*****************************************************/
/* cs8900_poll_send(): Transmit a frame in Poll mode */
/*****************************************************/
int cs8900_poll_send()
{
    int len;
    unsigned short *sdata;
    unsigned short status;
    unsigned long i;
    /* Step 0: First thing to do is to disable all interrupts at processor level */
    /* These steps: Write the TX command, Bid for Tx, and copy Tx data to chip must be atomic
       Otherwise, CS8900 may hang if interrupts occurs in the middle of these steps */
    INT_DISABLE(26);
    /* Step 1:  Write the TX command */
    if ( gPrevTxBidFail )
    {
        /* Previous BidForTX has reserved the Tx FIFO on CS8900, must clear off it.*/
        /* Setting PP_TxCmd_Force bit will cause CS8900 to release the previous reserved Tx buffer.*/
        CS8900_TxCMD = PP_TxCmd_TxStart_Full | PP_TxCmd_Force;
        gPrevTxBidFail = 0;
    }
    else
    {
        CS8900_TxCMD = PP_TxCmd_TxStart_Full;
    }
    /* Step 2: Bid for Tx */
    /* Write the frame length (Number of bytes to TX) */
    /* Note: After the frame length has been written, CS8900 reserves Tx buffer for this bid no
             matter PP_BusStat_TxRDY is set or not.*/
    CS8900_TxLEN = gTxLength;
    /* Read BusST to verify it is set as Rdy4Tx. */
    status = ReadReg(PP_BusStat);
    /* Step 3: check if TxBidErr happens ******/
    if ( status & PP_BusStat_TxBid )
    {
        /* TxBidErr happens only if Tx_length is too small or too large */
        INT_ENABLE(26);
        return -1;
    }
    /* Step 4: check if chip is ready for Tx now */
    /* If Bid4Tx not ready, skip the frame */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -