📄 main.c
字号:
#include "includes.h"
#include "eth.h"
#include "arp.h"
#define PUBLIC
#define PRIVATE static
static void uDelay(int iUSecs);
typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef UCHAR BYTE;
typedef enum {
FALSE = 0,
TRUE = -1
}BOOL;
#define DM9000IOBASE (0x08000000 + 0x300)
// I/O mode register mapping
#define IO_PACKET_PAGE_POINTER 0x0000
#define IO_PACKET_PAGE_DATA 0x0004
#define IO_RX_TX_DATA 0x0000
// Bus interface registers
// PKT 分区知识表
#define PKTPG_PRDCT_ID_H 0x002b
#define PKTPG_PRDCT_ID_L 0x002a
#define PKTPG_VNDR_ID_H 0x0029
#define PKTPG_VNDR_ID_L 0x0028
//
#define DM9000_PRDCT_ID 0x9000
#define DM9000_VNDR_ID 0x0A46
#define DM9000_IO_MODE 0x00 //16bit
/*
* Status and control registers
*/
#define PKTPG_NCR_00 0x0000
#define PKTPG_NSR_01 0x0001
#define PKTPG_TCR_02 0x0002
#define PKTPG_BPTR_08 0x0008
#define PKTPG_FCTR_09 0x0009
#define PKTPG_FCR_0A 0x000a
#define PKTPG_GPCR_1E 0x001e
#define PKTPG_GPR_1F 0x001f
#define PKTPG_SMCR_2F 0x002f
#define PKTPG_ISR_FE 0x00fe
#define PKTPG_IMR_FF 0x00ff
/*
* Bit masks .Set Values
*/
#define NCR_RESET 0x0001
#define NCR_CLEAR 0x0000
#define GPCR_PHY_ON 0x0001
#define GPR_PHY_ON 0x0000
#define NCR_INIT 0x0000
#define NSR_INIT 0x002c
//读/写数据
#define IOREAD(o) ((USHORT)(*((volatile USHORT *)(DM9000IOBASE + (o))) & 0x00ff))
#define IOREADw(o) ((USHORT)*((volatile USHORT *)(DM9000IOBASE + (o))))
#define IOWRITE(o, d) *((volatile USHORT *)(DM9000IOBASE + (o))) = (d & 0x00ff)
#define IOWRITEw(o, d) *((volatile USHORT *)(DM9000IOBASE + (o))) = (USHORT)(d)
//读/写寄存器
#define READ_REG1 ReadReg
#define WRITE_REG1 WriteReg
PRIVATE USHORT
ReadReg(USHORT offset)
{
IOWRITE(IO_PACKET_PAGE_POINTER, offset);
return IOREAD(IO_PACKET_PAGE_DATA);
}
PRIVATE void
WriteReg(USHORT offset, USHORT data)
{
IOWRITE(IO_PACKET_PAGE_POINTER, offset);
IOWRITE(IO_PACKET_PAGE_DATA , data);
}
BOOL dm9000Probe(void)
{
USHORT id_vendor, id_product;
CONSOL_Printf("\n [DM9000 Test]\n");
id_vendor = READ_REG1(PKTPG_VNDR_ID_L);
id_vendor |= READ_REG1(PKTPG_VNDR_ID_H)<<8;
if (id_vendor != DM9000_VNDR_ID)
{
CONSOL_Printf("VENDOR ID Error (0x%04x != 0x%04x)\n", DM9000_VNDR_ID, id_vendor);
return FALSE;
}
else
CONSOL_Printf("VENDOR ID = 0x%04x\n", id_vendor);
id_product = READ_REG1(PKTPG_PRDCT_ID_L);
id_product |= READ_REG1(PKTPG_PRDCT_ID_H)<<8;
if ((id_product & DM9000_PRDCT_ID) != DM9000_PRDCT_ID)
{
CONSOL_Printf("Product ID Error (0x%04x != 0x%04x)\n", DM9000_PRDCT_ID, id_product);
return FALSE;
}
else
CONSOL_Printf("Product ID = 0x%04x\n", id_product);
return TRUE;
}
PRIVATE BOOL dm9000Reset(void)
{
WRITE_REG1(0,1);
uDelay(100);
return TRUE;
}
PRIVATE BOOL dm9000Init(void)
{
//Get IO Mode
UCHAR uchTemp;
USHORT ushTemp;
struct eth_addr ethaddr;
//bit6bit7 = 00 16bit
if ((uchTemp=(READ_REG1(PKTPG_ISR_FE)>>6)&0xff) != DM9000_IO_MODE)
{
CONSOL_Printf("\nDM9000's io mode error. io_mode=%c .\n",uchTemp);
return FALSE;
}
//Active PHY
WRITE_REG1(PKTPG_GPCR_1E,GPCR_PHY_ON);
WRITE_REG1(PKTPG_GPR_1F,GPR_PHY_ON);
//Reset DM9000
WRITE_REG1(0x0000,0);
//TX Control Register Default
WRITE_REG1(0x0002,0);
//Back Pressure Threshold Register Default+600us
WRITE_REG1(0x0008,0x003f);
//Flow Control Threshold Register Default
WRITE_REG1(0x0009,0x0038);
//RX/TX Flow Control Register Default + Back Pressure mode
WRITE_REG1(0x000a,0x0008);
//Special Mode Control Register Default
WRITE_REG1(0x002f,0);
//Interrupt Status Register bit6bit7 = 00 16bit
WRITE_REG1(0x00fe,0x000f);
//
ethaddr = getethaddr();
//write Node address 设定Physical Address 位置
for (ushTemp=0; ushTemp<6; ushTemp++)
{
WRITE_REG1(ushTemp+0x0010, (USHORT)(ethaddr.addr[ushTemp]));
}
//insert hash table 设定Multicast 设置
for (ushTemp=0x0016; ushTemp<0x001e; ushTemp+=2)
{
WRITE_REG1(ushTemp, 0xff);
WRITE_REG1(ushTemp+1, 0xff);
}
//Rx Controll Register Rx Enable
WRITE_REG1(0x0005,0x0031);
//将DM9000 中断功能关闭
WRITE_REG1(0x00ff,0x0080);
CONSOL_Printf("\nDM9000_Init OK.\n");
return TRUE;
}
PRIVATE USHORT
TransmitPkt(BYTE *pbData, USHORT slen)
{
USHORT ushlen;
/* Send Command */
//Disable INT
//WRITE_REG1(0x00ff,0x0080);
IOWRITE(0x0000,0x00f8);//trigger MWCMD(Reg_f8)
ushlen = slen;
//Used the 16 io_mode,so convert byte len to word len
for(; slen>0 ; slen-=2, pbData+=2)
{
if(slen >= 2)// DM9000IOBASE + IO_PACKET_PAGE_DATA 读/写数据
IOWRITEw(IO_PACKET_PAGE_DATA, *((USHORT*)pbData));
else
IOWRITEw(IO_PACKET_PAGE_DATA, (USHORT)(*pbData));
}
//Write the transmittion length
WRITE_REG1(0x00fc,ushlen & 0xff);
WRITE_REG1(0x00fd,(ushlen>>8) & 0xff);
//Start to transmit
WRITE_REG1(0x0002,1);
//Enable INT
//WRITE_REG1(0x00ff,0x83);
return 0;
}
PRIVATE USHORT
RcvPkt(BYTE *pbData, USHORT dwLength)
{
/* use int rather than short for the reason of performance */
USHORT length;
USHORT rlen = 0;
USHORT *bp;
USHORT data,ushStatus;
//Check status
IOWRITE(0, 0x00f2); /* Discard RxStatus */
//ushStatus = IOREAD(0x00f2);
ushStatus = IOREADw(IO_PACKET_PAGE_DATA) & 0xff00;
length = IOREADw(IO_PACKET_PAGE_DATA);
if (length > dwLength) length = 0;
bp = (USHORT *)pbData;
rlen = length;
while (rlen)
{
data = IOREADw(IO_PACKET_PAGE_DATA);
if (rlen == 1)
{
*((BYTE *)bp) = (BYTE)data;
rlen--;
}
else
{
*bp++ = data;
rlen -= 2;
}
}
return length;
}
PUBLIC BOOL
DM9000DBG_IsReceivedPacket(void)
{
USHORT event;
BOOL r = FALSE;
//event = IOREAD(IO_ISQ);
event = READ_REG1(0x00f0);
event = READ_REG1(0x00f0);
if (event == 0x01)
{
r = TRUE;
}
//event >1 ,Error status then reset
if (event > 0x01)
{
WRITE_REG1(0x0005,0x00);
WRITE_REG1(0x00fe,0x80); //clear isr
CONSOL_Printf("\nRecieve packet error.");
while(1)
{
CONSOL_Printf("\nReset()\n");
if(dm9000Reset() && dm9000Init())
break;
}
}
return r;
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
PUBLIC USHORT
DM9000DBG_GetFrame(BYTE *pbData, USHORT *pwLength)
{
if (DM9000DBG_IsReceivedPacket())
{
return RcvPkt(pbData, *pwLength);
}
return 0;
}
PUBLIC USHORT
DM9000DBG_SendFrame(BYTE *pbData, USHORT slen)
{
return TransmitPkt(pbData, slen);
}
static BYTE out_data[1024];
static BYTE in_data[2048];
void APP_vMain(void)
{
int i;
USHORT len;
struct eth_addr ethaddr;
for(i=0; i<sizeof(out_data); i++)
out_data[i] = (BYTE)i;
while(1)
{
dm9000Probe();
dm9000Reset();
dm9000Init();
//getipaddr() 返回u32_t 小端IP 192 168 0 118 = 0xc0 0xA8 0x00 0x76
//转换后得 0x760x000xA80xc0 0x7600A8c0
arp_getethaddr(getipaddr(), ðaddr);//免费ARP
CONSOL_Printf("ethaddr:0X%x0X%x0X%x0X%x0X%x0X%x\n",ethaddr.addr[0],ethaddr.addr[1],
ethaddr.addr[2],ethaddr.addr[3],ethaddr.addr[4],ethaddr.addr[5]);
while(1)
{
if(CONSOL_GetChar((char*)&i))
{
if((i&0xff) == 0x1b)//27
break;
}
len = sizeof(in_data);
len = DM9000DBG_GetFrame(in_data, &len);
if(len > 0)
{
eth_input(in_data, len);
CONSOL_Printf("\n\nRecieve packet len=%d", len);
for(i=0; len>0; len--,i++)
CONSOL_Printf((i%16)==0 ? "\n%02x ": "%02x ", in_data[i]);
}
}
}
}
static void uDelay(int iUSecs)
{
int i;
int iScaledSecs = (iUSecs * 200);
for(i=0;i<iScaledSecs;i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -