📄 cs8900a.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 + -