📄 rtl8019.c
字号:
/*
*********************************************************************************************************
* ModbusTCP
* programmable human machine interface
*
* (c) Copyright 2007, 浙大中自集成控制股份有限公司开发二部
* All Rights Reserved
*
* File : LcdDriver.c
* By : lb
*********************************************************************************************************
*/
/***********************************************
8019的驱动,但是不会用它的查询去做,这样会影响实时性,中断的
处理机制我传给了ethernetif.c去做了。
************************************************/
#define __RTL8019__SLF__
#include "RTL8019.h"
#include "ucos_ii.h"
#include "def.h"
unsigned char txd_buffer_select=0; //选择网卡的发送缓冲区
static unsigned char next_page;
unsigned char My_hwaddr[6];
#define Rtl8019ResetLow IO0CLR |= 0x40;
#define Rtl8019ResetHigh IO0SET |= 0x40;
#define P06DirOut IO0DIR |= 0x40;
extern void ENT2_ISR(void);
void page(unsigned char pagenumber)
{
unsigned char temp;
temp = Read8019Reg(0x00);
temp=temp&0x3B ;
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
Write8019Reg(0x00, temp);
}
void Init8019GPIO(void)
{
unsigned char i;
PINSEL0 = 0xC000;
i=100;
while(i--);
P06DirOut;
}
void InitINT(void)
{
EXTMODE = 0x0f; // 设置EINT1中断为边沿触发模式
EXTPOLAR = 0x0f; // 设置EINT1中断为下降沿触发
VICIntSelect = 0x00000000; // 设置所有中断分配为IRQ中断
VICVectCntl6 = 0x20|16; // 分配EINT1中断到向量中断0
VICVectAddr6 = (int)ENT2_ISR; // 设置中断服务程序地址
EXTINT = 0x04; // 清除EINT1中断标志
VICIntEnable |= 1<<16; // 使能EINT1中断 */
}
static void Rtl8019AS_Reset() //复位网卡
{
Rtl8019ResetHigh;
OSTimeDly(10);
Rtl8019ResetLow;
OSTimeDly(10);
}
static void WriteRtl8019NodeID(void)
{
page(1);
Write8019Reg(0x01, My_hwaddr[0]);
Write8019Reg(0x02, My_hwaddr[1]);
Write8019Reg(0x03, My_hwaddr[2]);
Write8019Reg(0x04, My_hwaddr[3]);
Write8019Reg(0x05, My_hwaddr[4]);
Write8019Reg(0x06, My_hwaddr[5]);
page(0);
}
void init_8019(void)
{
unsigned char i;
while(1)
{
Rtl8019AS_Reset(); //复位8019
OSTimeDly(8);
Write8019Reg(0x00, 0x21); //使芯片处于停止模式,这时进行寄存器设置 停止模式下,将不会发送和接收数据包
OSTimeDly(8); //延时10毫秒,确保芯片进入停止模式
i = Read8019Reg(0x00);
if(i == 0x21)
break;
}
page(0);
Write8019Reg(0x0a, 0x00);
Write8019Reg(0x0b, 0x00);
Write8019Reg(0x0c, 0xe0); //monitor mode (no packet receive)
Write8019Reg(0x0d, 0xe2); //loop back mode 使芯片处于mon和loopback模式,跟外部网络断开
Write8019Reg(0x01, 0x4c);
Write8019Reg(0x02, 0x80);
Write8019Reg(0x03, 0x4c);
Write8019Reg(0x04, 0x40);
Write8019Reg(0x07, 0xff); //清除所有中断标志位
Write8019Reg(0x0f, 0x11); //disable all interrupt
Write8019Reg(0x0e, 0xc8); //byte dma 8位dma方式
page(1);
Write8019Reg(0x07, 0x4d);
Write8019Reg(0x08, 0x00);
Write8019Reg(0x09, 0x00);
Write8019Reg(0x0a, 0x00);
Write8019Reg(0x0b, 0x00);
Write8019Reg(0x0c, 0x00);
Write8019Reg(0x0d, 0x00);
Write8019Reg(0x0e, 0x00);
Write8019Reg(0x0f, 0x00);
Write8019Reg(0x00, 0x22); //这时让芯片开始工作
//ReadRtl8019NodeID(); //读出网卡的物理地址48位
WriteRtl8019NodeID(); //将网卡地址写入到mar寄存器
page(0);
Write8019Reg(0x0c, 0xcc); //将网卡设置成正常的模式,跟外部网络连接
Write8019Reg(0x0d, 0xe0);
Write8019Reg(0x00, 0x22); //这时让芯片开始工作
Write8019Reg(0x07, 0xff); //清除所有中断标志位
}
void send_frame(unsigned char * outbuf, unsigned short len)/*发送一个数据包的命令,长度最小为60字节,最大1514字节*/
{
unsigned char i;
unsigned short ii;
unsigned char temp;
page(0);
if(len<60)len=60;
txd_buffer_select=!txd_buffer_select;
if(txd_buffer_select)
Write8019Reg(0x09, 0x40); //txdwrite highaddress将远程DMA地址分为两个,40-45,46-4b。前面用于发送包。
else
Write8019Reg(0x09, 0x46); //txdwrite highaddress后面用于构造端的包
Write8019Reg(0x08, 0x00); //read page address low
Write8019Reg(0x0b, (unsigned char)(len>>8)); //read count high
Write8019Reg(0x0a, (unsigned char)(len&0xff)); //read count low
Write8019Reg(0x00, 0x12); //write dma, page0从远端DMA写到8019RAM中数据
for(ii=0; ii<len; ii++) //for(ii=4;ii<len+4;ii++) //是否加4有待验证
{
Write8019Reg(0x10, *(outbuf+ii));
}
/* 以下3句为中止dma的操作,可以不要 */
// reg0b=0x00; //read count high 中止DMA操作
// reg0a=0x00; //read count low;
// reg00=0x22; //complete dma page 0
for(i=0;i<16;i++) //最多重发16次
{
for(ii=0;ii<1000;ii++) //检查txp为是否为低
{
temp = Read8019Reg(0x00);
if((temp&0x04)==0) break;
}
temp = Read8019Reg(0x04);
if((temp&0x01)!=0) break; //表示发送成功,如果不成功,则执行reg00=3e,继续发送。
Write8019Reg(0x00, 0x3e);
}
Write8019Reg(0x07, 0xff); //清除所有中断标志位
if(txd_buffer_select)
Write8019Reg(0x04, 0x40); //txd packet start; //设置发送开始页的地址
else
Write8019Reg(0x04, 0x46); //txd packet start;
Write8019Reg(0x06, (unsigned char)(len>>8)); //high byte counter要发送的包的字节数(长度)
Write8019Reg(0x05, (unsigned char)(len&0xff)); //low byte counter
Write8019Reg(0x07, 0xff); //清除所有中断
Write8019Reg(0x00, 0x3e); //to sendpacket; 从本地DMA中发送包
}
char query_8019(void)
{
unsigned char my_bnry=0;
unsigned char my_curr=0;
page(0);
my_bnry = Read8019Reg(0x03); //bnry page have read 读页指针
page(1);
my_curr = Read8019Reg(0x07); //curr writepoint 8019写页指针
page(0);
if ((my_curr==0)) return 0;
my_bnry++;
if (my_bnry>0x7f) my_bnry=0x4c;
if (my_bnry!=my_curr) //此时表示有新的数据包在缓冲区里
{
Write8019Reg(0x0b, 0x00); //complete dma page 0 //
Write8019Reg(0x0a, 0x00); //
Write8019Reg(0x00, 0x22);
return 1;
}
Write8019Reg(0x0b, 0x00); //complete dma page 0 //
Write8019Reg(0x0a, 0x00); //
Write8019Reg(0x00, 0x22);
return 0;
//Write8019Reg(0x0b, 0x00); //complete dma page 0
//Write8019Reg(0x0a, 0x00);
//Write8019Reg(0x00, 0x22);
}
unsigned short GetPackedLen(void)
{
unsigned char bnry,curr;
unsigned short len=0x0000;
unsigned char temp;
page(0); //bnry page have read 读页指针
bnry = Read8019Reg(0x03);
page(1); //curr writepoint 8019写页指针
curr = Read8019Reg(0x07);
page(0);
if ((curr==0)) return 0; //读的过程出错
next_page=bnry;
bnry++;
if (bnry>0x7f) bnry=0x4c;
if (bnry!=curr) //此时表示有新的数据包在缓冲区里
{
//读取一包的前4个字节:4字节的8019头部
page(0);
//read page address high
Write8019Reg(0x09, bnry);
//read page address low
Write8019Reg(0x08, 0x00);
//read count high
Write8019Reg(0x0b, 0x00);
//read count low;
Write8019Reg(0x0a, 0x04);
//read dma
Write8019Reg(0x00, 0x0a);
temp = Read8019Reg(0x10);
temp = Read8019Reg(0x10);
next_page = temp-1; //next page start-1
len = Read8019Reg(0x10);
temp = Read8019Reg(0x10);
len += temp<<8;
Write8019Reg(0x0b, 0x00); //complete dma page 0
Write8019Reg(0x0a, 0x00);
Write8019Reg(0x00, 0x22);
return len;
}
return 0;
}
void rcve_frame(unsigned char * inbuf, unsigned short len)
{
unsigned char bnry,curr;
unsigned short ii;
if (inbuf == NULL)
{
//out of RAM
//Tell 8019 to skip the frame
page(1); //page1
curr = Read8019Reg(0x07);
page(0); //切换回page0
bnry = curr -1;
if(bnry < 0x4c) bnry =0x7f; //write to bnry
Write8019Reg(0x03, bnry); //清除中断状态可以不用
Write8019Reg(0x07, 0xff);
return;
}
page(0); //bnry page have read 读页指针
bnry = Read8019Reg(0x03);
page(1); //curr writepoint 8019写页指针
curr = Read8019Reg(0x07);
//This flag keeps track of allocated rcve memory
//rcve_buf_allocated = TRUE;
//Call the assembler function to get the incoming frame
//read page address high
Write8019Reg(0x09, bnry); //read page address low
Write8019Reg(0x08, 0x04); //read count high
Write8019Reg(0x0b, (unsigned char)(len>>8)); //read count low;
Write8019Reg(0x0a, (unsigned char)(len&0xff)); //read dma
Write8019Reg(0x00, 0x0a);
for(ii=0;ii<len;ii++)
{
inbuf[ii] = Read8019Reg(0x10);
}
//dma complete page0
Write8019Reg(0x0b, 0x00);
Write8019Reg(0x0a, 0x00);
Write8019Reg(0x00, 0x22);
//Return pointer to start of buffer
bnry=next_page;
if (bnry<0x4c) bnry=0x7f; //write to bnry
Write8019Reg(0x03, bnry);
Write8019Reg(0x07, 0xff);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -