📄 cs8900.c
字号:
#include "cs8900.h"
#include "2410lib.h"
#include "string.h"
#include "2410addr.h"
#define printf Uart_Printf
int cs8900_reset(void);
unsigned short ReadPPRegister(unsigned short regOffset);
void WritePPRegister(unsigned short regOffset, unsigned short val);
extern unsigned char gRxDataBuf[1520];
extern unsigned char gTxDataBuf[1520];
extern int ack_flag;
//源地址
static char EtherAddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66};
//目的地址
static char EtherDesAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static int gPrevTxBidFail = 0; /* The flag to know if the previous bid for Tx is failed. */
/***************************************************************************************/
/* ReadPPRegister(): Read value from the Packet Pointer register at regOffset */
/***************************************************************************************/
unsigned short ReadPPRegister(unsigned short regOffset)
{
CS8900_PPTR = regOffset;
return CS8900_PDATA;
}
/****************************************************************************************/
/* WritePPRegister(): write value to the Packet Pointer register at regOffset */
/****************************************************************************************/
void WritePPRegister(unsigned short regOffset, unsigned short val)
{
CS8900_PPTR = regOffset;
CS8900_PDATA = val;
}
/**************************************************************************/
/* cs8900_poll_init( ): start up CS8900 for Poll Mode */
/**************************************************************************/
int cs8900_poll_init(unsigned short duplexMode)
{
unsigned short chip_type, chip_rev,/* chip_status,*/ tmpAddr0, tmpAddr1, tmpAddr2;
unsigned short *ptr;
int status;
/* Information: read Chip Id and Revision */
chip_type = ReadPPRegister(PP_ChipID);
chip_rev = ReadPPRegister(PP_ChipRev);
if ( chip_type != 0x630e )
{
printf ("Chip ID Error\n");
return -1;
}
/****** step 1: software reset the chip ******/
status = cs8900_reset();
if (status != 0 )
{
printf("CS8900 Error: Reset Failed!\n");
return -1;
}
/****** step 2: Set up Ethernet hardware address ******/
ptr = (unsigned short *)EtherAddr;
tmpAddr0=*ptr;
tmpAddr1=*(ptr+1);
tmpAddr2=*(ptr+2);
/* Write 2 bytes of Ethernet address into the Individual Address register at a time */
WritePPRegister(PP_IA, tmpAddr0 );
WritePPRegister(PP_IA+2, tmpAddr1 );
WritePPRegister(PP_IA+4, tmpAddr2 );
/****** step 3: Configure RxCTL to receive good frames for Indivual Addr, Broadcast, and Multicast.*/
/*WritePPRegister(PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_Multicast);*/
/****** step 3: or set to Promiscuous mode to receive all network traffic ******/
//任意地址接收 //网卡设置成接收correct CRC & valid length(64--1518)
WritePPRegister(PP_RxCTL, PP_RxCTL_Promiscuous|PP_RxCTL_RxOK);
/****** step 4: Configure TestCTL (DuplexMode) ******/
/* defualt: 0:half duplex; 0x4000=Full duplex*/
//duplexMode由参数传递过来
// WritePPRegister(PP_TestCTL, duplexMode);
//全双工
WritePPRegister(PP_TestCTL, PP_TestCTL_FDX);
/****** step 5: Set SerRxOn, SerTxOn in LineCTL ******/
//使接收下一桢成为可能
WritePPRegister(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
return 0;
}
//初始化中断
void interrupt_init(void)
{
U16 val;
int int_stat;
//mcu相关的设定使之响应中断
pISR_EINT8_23 = (int)interrupt_done; //中断入口函数
WritePPRegister(PP_IntReg, PP_IntReg_IRQ0);//选择pin0
WritePPRegister(PP_RxCFG, PP_RxCFG_RxOK);//接收产生中断
// WritePPRegister(PP_TxCFG, PP_TxCFG_TxOK);//发送产生中断
Uart_Printf("RxCFG = %x\n", ReadPPRegister(PP_RxCFG));
val = ReadPPRegister(PP_LineCTL)|PP_LineCTL_Rx|PP_LineCTL_Tx;
WritePPRegister(PP_LineCTL, val);
val = ReadPPRegister(PP_BusCtl);
val |= PP_BusCtl_EnableIRQ;
rEXTINT1 |= 1<<4; //使eint9高电平有效
rEINTMASK &= ~(1<<9);//开外部屏蔽中断
rINTMSK &= ~(1 << 5);//开内部中断屏蔽
WritePPRegister(PP_BusCtl, val);//受理中断使能
}
//中断服务程序
void __irq interrupt_done(void)
{
U16 int_stat;
U8 isdata;
int_stat = CS8900_ISQ;// ReadPPRegister(0x0008);
Uart_Printf("%x\n", int_stat);
switch (int_stat & 0x003f) {
case 4:
Uart_Printf("接收中断!\n");
if ((int_stat & PP_RER_RxOK)) {
Uart_Printf("接收!\n");
Uart_Printf("int_stat = %x\n", int_stat);
cs8900a_rev(gRxDataBuf);
//是数据就发送确认桢
if (data_is(gRxDataBuf))
if (get_frame_num(gTxDataBuf) == get_frame_num(gRxDataBuf)) {
send_ack(gTxDataBuf);
Uart_Printf("ack send!\n");
ack_flag = 1;
}
ShowReceiveFrame();
return;
}
/*case 8:
Uart_Printf("发送中断!\n");
if (int_stat & PP_TER_TxOK) {
creat();
cs8900_poll_send(gTxDataBuf);
}*/
}
/* Uart_Printf("响应!\n");
//把中断队列的内容全部处理
while (((int_stat = CS8900_ISQ)& 0xffc0) != 0) {
if (int_stat & PP_RER_RxOK) {
cs8900a_rev(gRxDataBuf);
//是数据就发送确认桢
if (data_is(gRxDataBuf))
if (get_frame_num(gTxDataBuf) == get_frame_num(gRxDataBuf)) {
send_ack(gTxDataBuf);
ack_flag = 1;
}
ShowReceiveFrame();
return;
}
return ;
} */
/*
if (int_stat & 0x003f) {
if (int_stat & PP_TER_TxOK){
Uart_Printf("产生中断\n");
creat();
cs8900_poll_send(gTxDataBuf);
}
if (int_stat & PP_RER_RxOK) {
Uart_Printf("接收中断!\n");
}
}*/
rSRCPND = BIT_EINT8_23; //Clear pending bit
rINTPND = BIT_EINT8_23;
rINTPND;
rEINTPEND = 1<<9;//Clear externt pending bit
rEINTPEND;
}
//发送数据桢
int cs8900a_send(unsigned char *pTxData)
{
int total_len, len, i;
unsigned short *sdata;
U16 stat;
total_len = get_frame_len(pTxData) + 14;
CS8900_TxCMD = (unsigned short) PP_TxCmd_TxStart_Full | PP_TxCmd_Force;
CS8900_TxLEN = total_len;
sdata = (unsigned short *)pTxData;
len = total_len;
if (len > 0)
{
/* Output contiguous words, two bytes at a time. */
while (len > 1)
{
CS8900_RTDATA = *sdata ++;
len -= 2;
printf(".");
}
/* If Odd bytes, copy the last one byte to chip.*/
if (len == 1)
{
CS8900_RTDATA = (*sdata) & 0x00ff;
}
}
printf("\nEnding Translate\n");
/****** Step 5.1: enable interrupts at processor level if it is disabled in step 0.******/
/*enable( ); */
/****** Step 6: Poll the TxEvent Reg for the TX completed status */
/* This step is optional. If you don't wait until Tx compelete, the next cs8900_poll_send()
Bid For Tx may encounter Not Ready For Tx because CS8900 is still Tx'ing.*/
for ( i=0; i<30000; i++)
{
stat = ReadPPRegister(PP_TER);
if ( stat != 0x0008 )
{
break;
}
}
Uart_Printf("***%x\n", stat);
/* Tx compelete without error, return total_length Tx'ed */
if ( (stat & PP_TER_TxOK) || (stat == 0x0008) )
{
printf("Translate successful \n");
printf("----------End Translate-------\n");
Uart_Printf("***\n%x\n", ReadPPRegister(PP_TER));
return total_len; /* return successful*/
}
/* Tx with Errors */
printf("Tx Error! TxEvent=%x \n", stat);
printf("----------End Translat--------\n");
Uart_Printf("***\n%x\n", ReadPPRegister(PP_TER));
return -1; /* return failed*/
}
//判定是不是数据桢,如果是,创建确认桢,发送,不是则采取动作
/*
在桢中数据长度后面的1bit来标记数据桢还是确认桢
1 表示数据桢,
0 表示确认桢,
位置在gRxDataBuf中的14个单元的第一个bit
*/
int data_is(unsigned char *pRxData)
{
unsigned char *ptr = pRxData;
ptr += 14;
*ptr >> 7;
return *ptr;
}
//Ack的桢的发送
int send_ack(unsigned char *pTxData, unsigned char *pRxData)
{
unsigned char *ptr;
U16 *tptr;
ptr = pTxData;
//创建确认桢
memcpy(ptr,(unsigned char*)EtherDesAddr, 6);
ptr += 6;
memcpy(ptr, EtherAddr, 6);
ptr += 6;
tptr = (U16 *)ptr;
*tptr = 2;
ptr += 2;
*ptr = 0x0;
*ptr << 7; //设置ack桢标志
ptr ++;
*ptr = get_frame_num(pRxData);//接收桢的编号,封装在确认桢中
cs8900_poll_send(pTxData);
}
//获取接收到桢的编号
int get_frame_num(unsigned char *pRxData)
{
unsigned char *ptr = pRxData;
return *(ptr + 15);
}
//数据接收
int cs8900a_rev(unsigned char *dataBuf)
{
U16 *data;
unsigned short totalLen, leftLen,val;
unsigned char *cp;
totalLen = ReadPPRegister(PP_Rx_LENGTH);
// Uart_Printf("rxlenth = %d\n", totalLen);
data = (U16 *)dataBuf;
leftLen = totalLen;
/* read 2 bytes at a time */
while (leftLen >= 2)
{
*data++ = CS8900_RTDATA;
leftLen -= 2;
}
/* if odd bytes, read the last byte from chip*/
if (leftLen == 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);
}
return (int)totalLen;
}
/**************************************************************************/
/* cs8900_reset( ): software reset the CS8900 chip */
/**************************************************************************/
int cs8900_reset(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -