基于LPC2210的RTL8019AS以太網(wǎng)驅(qū)動系統(tǒng)設計(二)
五.發(fā)送數(shù)據(jù)包模塊
5.1發(fā)送數(shù)據(jù)包模塊功能
發(fā)送數(shù)據(jù)包時,先將待發(fā)送數(shù)據(jù)包通過遠程DMA寫入芯片RAM,給出發(fā)送緩沖區(qū)首地址和數(shù)據(jù)包長度,即可實現(xiàn)RTL8019AS的數(shù)據(jù)發(fā)送。RTL8019AS會自動按以太網(wǎng)協(xié)議完成發(fā)送并將結(jié)果寫入狀態(tài)寄存器。
5.2發(fā)送數(shù)據(jù)包??斓臄?shù)據(jù)結(jié)構(gòu)
1>_pkst
struct _pkst{
struct _pkst *STPTR;//前一個結(jié)構(gòu)數(shù)組
unsigned intlength;//以太網(wǎng)幀報頭長度長度14字節(jié)
unsigned char*DAPTR;//報頭的指針
};
2>ipethernet
typedef struct{
uint8DestMacId[6];/*目的網(wǎng)卡地址*/
uint8SourceMacId[6];/*源網(wǎng)卡地址*/
int16NextProtocal;/*下一層協(xié)議*/
} ipethernet;
3>定義數(shù)據(jù)結(jié)構(gòu):
struct _pkst* TxdData;
struct _pkst *ExPtr;
5.3發(fā)送數(shù)據(jù)包模塊組成
第一部分:ARM LPC2210把數(shù)據(jù)寫到RTL8019AS RAM中
該過程涉及以下幾個寄存器:
?RBCR0,RBCR1:遠程DMA數(shù)據(jù)字節(jié)技術器
?RSAR0,RSAR1:遠程DMA起始地址
?CR:發(fā)出遠程DMA開始命令
1>計算發(fā)送包幀的長度
2>設置遠程DMA起始地址寄存器(RSAR0,RSAR1),使遠程DMA起始地址寄存器為發(fā)送緩沖區(qū)首地址
3>設置遠程DMA字節(jié)計數(shù)器寄存器為發(fā)送數(shù)據(jù)幀的長度
4>啟動遠程DMA寫
設置CR命令寄存器使DMA開始遠程寫。
5>將數(shù)據(jù)寫到遠程DMA 0x10號寄存器處
6>清零遠程DMA字節(jié)計數(shù)器為0,并終止遠程DMA寫
7>清除所有中斷標志
第二部分:RTL8019AS將數(shù)據(jù)發(fā)送到以太網(wǎng)
在ARM LPC2210把數(shù)據(jù)通過遠程DMA寫到RTL8019AS RAM之后,RTL8019AS芯片通過本地DMA將數(shù)據(jù)發(fā)送到以太網(wǎng)。
該過程涉及以下寄存器:
?TPSR:設置傳輸數(shù)據(jù)包開始頁面地址
?TBCR0,TBCR1:設置傳輸數(shù)據(jù)包的字節(jié)計數(shù)。
?CR:發(fā)出發(fā)送數(shù)據(jù)包的指令。
設置寄存器結(jié)束后,RTL8019AS會自動用本地DMA發(fā)數(shù)據(jù)。
1>設置要發(fā)送包的起始頁
配置TPSR(發(fā)送開始頁寄存器):把發(fā)送緩沖區(qū)首地址賦值給TPSR.
2>判斷數(shù)據(jù)包長度,若小于60字節(jié),補足60字節(jié)
3>設置傳輸數(shù)據(jù)包的字節(jié)計數(shù)
設置TBCR0,TBCR1為數(shù)據(jù)包長度
4>發(fā)送數(shù)據(jù)前先清除所有中斷源
5>啟動本地DMA發(fā)送數(shù)據(jù)包
配置CR命令寄存器為3E發(fā)送數(shù)據(jù)包
6>包發(fā)送完后,判斷是否出錯,若發(fā)送錯誤則進行重發(fā),但只重發(fā)六次
?讀取命令寄存器(CR)中的TXP位:判斷數(shù)據(jù)包是否發(fā)送完畢。沒有發(fā)送完,則循環(huán)等待包發(fā)送完。
?讀TSR(傳輸狀態(tài)寄存器):判斷PTX位是否為1,若為1說明傳輸正確,退出程序。否則啟動DMA重新傳輸數(shù)據(jù)。
5.4發(fā)送數(shù)據(jù)包模塊的接口
發(fā)送包模塊調(diào)用了寫數(shù)據(jù)子模塊,讀數(shù)據(jù)子模塊和頁面切換子模塊
?讀數(shù)據(jù)子模塊:從RTL8019AS芯片中把數(shù)據(jù)讀出。
?寫數(shù)據(jù)子模塊:將數(shù)據(jù)寫入RTL8019AS芯片中
?頁面切換子模塊:可選擇Page0,Page1,Page3三個頁面。
5.5發(fā)送數(shù)據(jù)包模塊程序
/****************************Copyright(c)********************
**西安郵電學院
**graduate school
**XNMS實驗室
**Author:冀博
**Time:2011年2月21日
**http://blog.csdn.net/tigerjb
**
**--------------FileInfo---------------------------------------------------------------------
****************************Copyright(c)******************** /
/***************************************************
**函數(shù)原型:voidSend_Packet(struct _pkst *TxdData)
**入口參數(shù):struct _pkst *TxdData:指向要發(fā)送數(shù)據(jù)的結(jié)構(gòu)指針
**出口參數(shù):無
**說明:發(fā)送數(shù)據(jù)包,以太網(wǎng)底層驅(qū)動程序,所有的數(shù)據(jù)發(fā)送都要通過該程序
***************************************************/
void Send_Packet(struct _pkst *TxdData)//
{
static uint8 Tx_Buff_Sel=0;
struct _pkst *ExPtr;
uint8 *TEPTR;
union send_temp{
uint16 words;
uint8bytes[2];
}send_buff;
uint16 ii,length=0;
//切換至第0頁
page(0);
length=length+TxdData->length;
ExPtr=TxdData->STPTR;
//計算出要發(fā)送的數(shù)據(jù)的總長度
while(ExPtr!=NULL)
{
length=length+ExPtr->length;
ExPtr=ExPtr->STPTR;
}
ii=length;
//發(fā)送緩沖區(qū)的切換
Tx_Buff_Sel=Tx_Buff_Sel^1;
//設置遠程DMA起始地址寄存器(RSAR0,RSAR1)
if(Tx_Buff_Sel)
{
WriteToNet(0x09,0x40);
}
else
{
WriteToNet(0x09,0x46);
}
WriteToNet(0x08,0x00);
//設置遠程DMA字節(jié)計數(shù)器寄存器為發(fā)送數(shù)據(jù)幀的長度
WriteToNet(0x0b,ii>>8);
WriteToNet(0x0a,ii&0x00ff);
//啟動遠程DMA開始寫