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

📄 cs8900a.c

📁 uccos2的的源码文件
💻 C
字号:
#include "test.h"

#include "cs89x0.h"

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define vlt volatile

#define CS8900A_IOBASEADDR  0x19000300

#define outw(value,port)    *(vlt u16*)(port) = (value)
#define inw(port)           *(vlt u16*)(port)
#define inline  __inline

void reset_chip(void);
void set_mac_address(void *addr);
void get_mac_address(void *addr);



inline void enter_cs8900a(void)
{
	rBWSCON |= 0x0000d000;
	rBWSCON &= ~0x00040000;
}

inline exit_cs8900a(void)
{
}

void test_cs8900a(void)
{
    char tbuf[8];
    char addr[] = {0x00,0x11,0x22,0x33,0x44,0x55};
    enter_cs8900a();
    printf("cs8900 id: %04x %04x\r\n",readreg(0x00),readreg(0x02));
    printf("i/o base: %04x\r\n",readreg(0x20));
    get_mac_address(tbuf);
    printbuf(tbuf,6);
    set_mac_address(addr);
    get_mac_address(tbuf);
    printbuf(tbuf,6);
    exit_cs8900a();
}


inline int readreg( int portno) {
	outw(portno, CS8900A_IOBASEADDR + ADD_PORT);
	return inw(CS8900A_IOBASEADDR + DATA_PORT);
}

inline void writereg( int portno, int value) {
	outw(portno, CS8900A_IOBASEADDR + ADD_PORT);
	outw(value, CS8900A_IOBASEADDR + DATA_PORT);
}

inline int readword( int portno) {
	return inw(CS8900A_IOBASEADDR + portno);
}

inline void writeword( int portno, int value) {
	outw(value, CS8900A_IOBASEADDR + portno);
}

inline void writeblock( char *pData, int Length) {
    int i;

    for (i = 0 ; i < (Length/2); i++) {
        writeword(TX_FRAME_PORT, *(u16 *)pData );
        pData += 2;
    }

    if (Length % 2) {
        u16 OddWordValue = *pData;
        writeword( TX_FRAME_PORT, OddWordValue);
    }
}

inline void readblock( char *pData, int Length) {
    u16 InputWord;
    int i;

    for (i=0; i < (Length/2); i++) {
        InputWord = readword( RX_FRAME_PORT);
        *(u8*)pData++ = (u8) InputWord & 0xFF;
        *(u8*)pData++ = (u8) (InputWord >> 8) & 0xFF;
    }

    if (Length & 0x1)
      *pData = (u8) (readword( RX_FRAME_PORT) & 0xff);
}

void reset_chip(void)
{
    unsigned long timeout = 0x10000;
    writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
    /* wait 30 ms */
    while(timeout-- > 0);
    timeout = 0x100000;
    while( (readreg(PP_SelfST) & INIT_DONE) == 0
        && timeout-- > 0);
}


void set_mac_address(void *addr)
{
    int i;
    unsigned char* dev_addr = (unsigned char*)addr;

    /* set the Ethernet address */
    for (i=0; i < 3; i++)
      writereg(PP_IA+i*2, dev_addr[i*2] | (dev_addr[i*2+1] << 8));
}

void get_mac_address(void *addr)
{
    int i;
    unsigned char* dev_addr = (unsigned char*)addr;
    /* set the Ethernet address */
    for (i=0; i < 3; i++)
    {
     *(unsigned short*)(dev_addr+i*2) = readreg(PP_IA+i*2);
    }
}


void net_open(void)
{
    u32 curr_rx_cfg;

    enter_cs8900a();

    reset_chip();

    /* Prevent the crystal chip from generating interrupts */
   writereg(PP_BusCTL, readreg(PP_BusCTL) & ~ENABLE_IRQ);

    /* Turn on both receive and transmit operations */
    writereg(PP_LineCTL,readreg(PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);

    /* Receive all packets  */
    writereg(PP_RxCTL, RX_PROM_ACCEPT | RX_OK_ACCEPT );

    curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL;
    writereg(PP_RxCFG, curr_rx_cfg);

    writereg(PP_TxCFG,
         TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
         TX_LATE_COL_ENBL | TX_JBR_ENBL |
         TX_ANY_COL_ENBL | TX_16_COL_ENBL);

    writereg(PP_BufCFG,
         READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
         TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);

     writereg(PP_BusCTL, ENABLE_IRQ);

    exit_cs8900a();
}

extern void ReceivedEther(char *buffer,int length);

char frame[1600];
void net_rxframe(void)
{
    u16 status,length;

    status = readword(RX_FRAME_PORT);
    if ((status & RX_OK) == 0)
    {
      return;
    }

    length = readword(RX_FRAME_PORT);
    if( length < 1 || length > sizeof(frame) )
        return;
    readblock(frame, length);
    ReceivedEther(frame,length);
}

void PollintNet(void)
{
    u16 status;

    enter_cs8900a();
    status = readword(ISQ_PORT);
    switch(status & ISQ_EVENT_MASK)
    {
      case ISQ_RECEIVER_EVENT:	/* Got a packet(s). */
        net_rxframe();
	    break;
    }
    exit_cs8900a();
}

int net_send_packet(char* data,int len)
{
    writereg(PP_BusCTL, 0x0);
    writereg(PP_BusCTL, readreg(PP_BusCTL) | ENABLE_IRQ);

    /* initiate a transmit sequence */
    writeword(TX_CMD_PORT, TX_AFTER_ALL);
    writeword(TX_LEN_PORT, len);

    /* Test to see if the chip has allocated memory for the packet */
    if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0)
    {
          //printf("send fail\r\n");
          return 0;
    }
    /* Write the contents of the packet */
    writeblock(data,len);
    //printf("send ok\r\n");
    //printbuf(data,len);
    return 1;
}

⌨️ 快捷键说明

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