摘要: 应用说明372提供了如何配置单个T3/E3/HSSI/VDSL端口以在桥接模式下对DS3134进行非信道化操作的示例。本应用程序说明是作为编码示例提供的,以便于适应最终用户应用程序。
概述
本应用说明介绍了如何在桥接模式下为DS3134上的非通道化操作配置单个T3端口的示例。此外,本示例还描述了如何在该端口上以环回模式构造、发送、接收和检查数据包。本应用程序说明是作为编码示例提供的,以便于适应最终用户应用程序。
DS3134的本地总线可以在两种模式下工作:
PCI桥接模式
配置模式
PCI桥接模式允许PCI总线上的主机访问本地总线。在此应用中,PCI总线用于控制和监视DS3134并传输数据包数据。DS3134还配置为将数据从PCI总线映射到本地总线,用于控制和监视外围组件,如xDSL调制解调器或T3/E3接口。(请参阅ds3134数据表第10节。)
本例配置如下:
DS3134的端口1作为非信道化端口操作。也就是说,端口接收/发送时钟,但没有同步脉冲。其他所有端口未被使用。
HDLC通道0被分配到DS3134的端口1。它还被分配了256个RX FIFO块,256个TX FIFO块,一个RX FIFO高水位179(256的70%)和一个TX低水位77(256的30%)。
在主机内存中使用10个TX缓冲区、10个TX描述符和一个TX挂起队列条目构造10个16字节的数据包。TX挂起队列入口指向一个描述符,该描述符通过下一个描述符指针字段链接到10个描述符,并设置EOF和CV。
由于DS3134处于环回模式,数据包在传输时也将被DS3134接收。接收到的数据包使用10个RX缓冲区、10个RX描述符和10个RX已完成队列条目写入主机内存。
主机内存配置如下:
接收方
RX空闲队列基址(RFQBA1/0) = 0x10000000
RX完成队列基数地址(RDQBA1/0) = 0x10000B00
RX描述符基址(RDBA1/0) = 0x10001080
RX缓冲区基址= 0x10002680
传输方
TX待处理队列基址(TPQBA1/0) = 0x10059084
TX完成队列基址(TDQBA1/0) = 0x10059604
TX描述符基址(TDBA1/0) = 0x10059B84
TX缓冲区基址= 0x1005B184
代码示例函数调用的定义
为了提高可读性,本例中的代码使用了几个函数调用。这些函数的定义如下:
write_reg(地址、数据)
将指定的数据写入指定的DS3134寄存器地址
输入:
地址=要写入数据的寄存器地址
数据=要写入指定寄存器的数据
输出:没有
read_reg(地址、数据)
读取DS3134寄存器在指定地址的内容
输入:
Address =要读取的寄存器地址
输出:
数据=从寄存器中读取的值
write_reg_IS(地址、数据)
将指定的数据写入指定的DS3134间接选择寄存器,然后等待该寄存器?i’回来之前有点忙,需要清理一下
输入:
地址=要写入数据的间接选择寄存器
数据=要写入指定寄存器的数据
输出:没有
功能码:write_reg(address, data);
Bit_check = 0x8000;
While (bit_check &0 x8000)
read_reg(地址、bit_check);
wr_dword(地址、数据)
将指定的32位数据值写入指定的32位主机内存地址
输入:
Address =要写入数据的主机内存地址
Data =要写入指定内存地址的数据
输出:没有
rd_dword(地址、数据)
从指定的32位主机内存地址中读取32位数据值
输入:
Address =需要读取的主机内存地址
输出:
Data =从主机内存中读取的32位数据值
frame_wait(计数)
提供一个等于count帧周期的延迟,其中帧周期为125?年代
输入:
Count =等待的帧周期数
输出:没有
非信道化配置模式解码示例
这个编码示例由以下步骤组成:
复位DS3134
配置DS3134
开启HDLC通道
将HDLC通道设置为环回模式
对数据包进行排队、发送、接收和检查
以下各节将通过简要描述和编码示例详细介绍这些步骤。为了提高可读性,使用寄存器名代替地址。DS3134内部设备配置寄存器的相应地址/偏移量列在附表中。另外,使用缩写TX和RX分别表示发送端和接收端。有关更详细的信息,请参阅ds3134数据表。
复位DS3134
重置DS3134包括两个步骤。首先,DS3134的内部ram必须归零,然后DS3134内部寄存器必须重置。
零DS3134内部RAM?年代
DS3134内部配置ram不能通过复位芯片来清除,因此必须手动调零。这项任务是通过使用DS3134的适当数据和间接选择寄存器对DS3134中的每个内部ram执行一系列写操作来完成的。介绍完成该任务的具体步骤。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
CP [n] rdi | 03 xx | 信道化端口n寄存器数据间接选择 | 5.3 |
CP [n] RD | 03 xx | 信道化端口n注册数据 | 5.3 |
/*所有端口的零RX配置和TX配置ram */
For (port = 0;港& lt;16;端口=端口+ 1)
{
write_reg(CP0RD + 8*port, 0x0000);
For (ds0 = 0;ds0 & lt;128;Ds0 = Ds0 + 1)
{
/*设置位9?8 = 01选择RX Configuration RAM */
/*设置位9?8 = 10选择“TX Configuration RAM */”
write_reg_IS(CP0RDIS + 8*port, (0x0100 + ds0));
write_reg_IS(CP0RDIS + 8*port, (0x0200 + ds0));
}
}
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RHCDIS | 0400 | 接收HDLC通道定义间接选择 | 6.2 |
RHCD | 0404 | 接收HDLC通道定义 | 6.2 |
/*调零RX HDLC通道定义RAM */
write_reg (RHCD 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (RHCDIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
THCDIS | 0480 | 传输HDLC信道定义间接选择 | 6.2 |
THCD | 0484 | 传输HDLC信道定义 | 6.2 |
/*调零TX HDLC通道定义RAM */
write_reg (THCD 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (THCDIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFSBPIS | 0900 | 接收FIFO起始块指针间接选择 | 7.2 |
RFSBP | 0904 | 接收FIFO起始块指针 | 7.2 |
/*将RX FIFO起始块指针归零*/
write_reg (RFSBP 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (RFSBPIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFBPIS | 0910 | 接收FIFO块指针间接选择 | 7.2 |
RFBP | 0914 | 接收FIFO块指针 | 7.2 |
/*将RX FIFO块指针归零*/
write_reg (RFBP 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (RFBPIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFHWMIS | 0920 | 接收FIFO高水位间接选择 | 7.2 |
RFHWM | 0924 | 接收FIFO高水位 | 7.2 |
/*置零RX FIFO高水位RAM */
write_reg (RFHWM 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (RFHWMIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TFSBPIS | 0980 | 传输FIFO起始块指针间接选择 | 7.2 |
TFSBP | 0984 | 发送FIFO起始块指针 | 7.2 |
/* TX FIFO起始块指针寄存器归零*/
write_reg (TFSBP 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (TFSBPIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TFBPIS | 0990 | 发送FIFO块指针间接选择 | 7.2 |
TFBP | 0994 | 发送FIFO块指针 | 7.2 |
/*置零TX FIFO块指针RAM */
write_reg (TFBP 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (TFBPIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TFLWMIS | 09年a0 | 传输FIFO低水位间接选择 | 7.2 |
TFLWM | 09年a4 | 发送FIFO低水印 | 7.2 |
/*置零TX FIFO低水位RAM */
write_reg (TFLWM 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS (TFLWMIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RDMACIS | 0770 | 接收DMA配置间接选择 | 8.1.5 |
RDMAC | 0774 | 接收DMA配置 | 8.1.5 |
/* RX DMA配置内存*/
write_reg (RDMAC 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS(RDMACIS, 0x0400 + channel);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TDMACIS | 0870 | 传输DMA配置间接选择 | 8.2.5 |
TDMAC | 0874 | 发送DMA配置 | 8.2.5 |
/*调零TX DMA配置内存*/
write_reg (TDMAC 0 x0000);
For (channel = 0;频道& lt;256;通道=通道+ 1)
write_reg_IS(TDMACIS, 0x0400 + channel);
重置DS3134内部寄存器
可以使用主复位寄存器(MRID)对DS3134中的所有寄存器执行软件复位。主机必须将这个位设置回0,设备才能被编程正常运行。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
MRID | 0000 | 主复位&身份证登记 | 4.1 |
/*复位DS3134使用MRID寄存器主复位位。* /
write_reg (MRID 0 x0001);
write_reg (MRID 0 x0000);
配置DS3134
DS3134的配置包括以下步骤:
1. 配置PCI寄存器
2. 配置第一层寄存器
3.配置HDLC寄存器
4. 配置FIFO寄存器
5. 配置DMA寄存器
每个寄存器集的配置将在下面的小节中详细介绍。
/*本例使用端口1通道0 */
端口= 1;
通道= 0;
/* RX空闲队列基址*/
Rfq_base_addr = 0x10000000;
/* RX空闲队列结束地址*/
/* - RX空闲队列大小= 16 */
rfq_end_idx = 0x000F;
/* RX完成队列基数地址*/
rdq_base_addr = 0x10000B00;
/* RX完成队列结束地址*/
/* - RX完成队列大小= 16 */
rdq_end_idx = 0x000F;
/* RX描述符基址*/
/* - RX描述符表大小= 256 */
Rdscr_base_addr = 0x10001080;
/* RX数据缓冲区基址*/
Rx_buf_base_addr = 0x10002680;
/* TX等待队列的基址*/
Tpq_base_addr = 0x10059084;
/*等待队列结束地址*/
/* - TX等待队列大小= 16 */
tpq_end_idx = 0x000F;
/* TX完成队列的基址*/
Tdq_base_addr = 0x10059604;
/*发送完成队列结束地址*/
/* - TX完成队列大小= 16 */
tdq_end_idx = 0x000F;
/* TX描述符基址*/
/* - TX描述符表大小= 256 */
tdscr_base_addr = 0x10059B84;
/* TX数据缓冲区基址*/
tx_buf_base_addr = 0x1005B184;
配置PCI寄存器
PCI桥接模式允许PCI总线上的主机访问本地总线。PCI总线用于对DS3134进行控制和监控,传输数据包数据。DS3134将数据从PCI总线映射到本地总线。(请参阅ds3134数据表第10节。)
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
PCMD0 | 0 x004/0a04 | PCI命令状态0 | 9.2 |
/*将DS3134配置寄存器映射到PCI总线基址*/
write_reg(颁证书,0 x80000000);
/* PCI命令/状态寄存器0 ?控制DS3134 DMA功能*/
/*设置位1 = 1,允许通过PCI总线访问内部设备配置寄存器(桥模式需要)*/
/*设置位2 = 1,允许设备在PCI总线上作为总线主操作(DMA需要)*/
/*设置位6 = 1对奇偶校验错误起作用*/
/*设置位8 = 1使能PSERR引脚*/
write_reg (PCMD0 0 x00000146);
配置第一层寄存器
DS3134的每个端口都包含一个第一层控制器,该控制器执行多种功能,包括:
为输入和输出数据分配HDLC通道号
信道化的本地和网络环回
信道化选择64kbps, 56kbps,或没有数据
信道化传输DS0通道填充的所有
将数据路由到BERT函数或从BERT函数发送数据
将数据路由到V.54环路模式检测器
第一层配置是通过RP[n]CR、TP[n]CR、CP[n]RD和CP[n]RDIS寄存器(其中n为要配置的端口)以端口为基础进行的。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RP [n] CR | 01 xx | 接收端口n控制寄存器 | 5.2 |
TP [n] CR | 02年xx | 发送端口n控制寄存器 | 5.2 |
CP [n] rdi | 03 xx | 信道化端口n寄存器数据间接选择 | 5.3 |
CP [n] RD | 03 xx | 信道化端口n注册数据 | 5.3 |
/*设置RX端口控制寄存器*/
/*设置位2?0 = 000为时钟,数据和同步不倒转*/
/*设置位5?4 = 00为同步脉冲0时钟提前*/
/*位7?6被忽略;启用高速模式*/
/*设置位8 = 1,开启高速模式*/
/*设置位9 = 1开启非通道化模式*/
/*设置位10 = 0禁用本地环回*/
/*位11不赋值*/
/*位12?13为只读*/
/*设置位14 = 0以启用非通道化模式*/
/*第15位为只读*/
write_reg(r0cr + 4*port, 0x0300);
/*设置TX端口控制寄存器*/
/*设置位2?0 = 000为时钟,数据和同步不倒转*/
/*设置位3 = 0,强制TD的所有数据为1 */
/*设置位5?4 = 00为同步脉冲0时钟提前*/
/*位7?启用高速模式时,忽略6(屯=1)*/
/*设置位8 = 1,开启高速模式*/
/*设置位9 = 1开启非通道化模式*/
/*设置位10 = 0禁用网络环回*/
/*设置位11 = 0从HDLC控制器选择源传输数据*/
/*位12?13不赋值为*/
/*设置第14位= 0来屏蔽中断*/
/*第15位为只读*/
write_reg(TP0CR + 4*port, 0x0300);
配置HDLC寄存器
DS3134包含一个256通道HDLC控制器,执行第2层功能,其中包括以下功能:
零填充和零拆封
标志检测和字节对齐
CRC的生成和校验
数据反转和位翻转
HDLC控制器通过RHCD、RHCDIS、THCD和THCDIS寄存器在通道基础上配置。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RHCDIS | 0400 | 接收HDLC通道定义间接选择 | 6.2 |
RHCD | 0404 | 接收HDLC通道定义 | 6.2 |
THCDIS | 0480 | 传输HDLC信道定义间接选择 | 6.2 |
THCD | 0484 | 传输HDLC信道定义 | 6.2 |
/* RX HDLC配置*/
/*设置位3?2 = 10对于32位的CRC */
write_reg (RHCD 0 x0008);
write_reg_IS (RHCDIS、通道);
/* TX HDLC配置*
/*设置位1= 0,选择7E */的间隔字节
/*设置位3?2 = 10对于32位的CRC */
/*设置位11?8 = 0000共享开闭标志*/
write_reg (THCD 0 x0008);
write_reg_IS (THCDIS、通道);
配置FIFO寄存器
DS3134包含一个16kb的发送FIFO和一个16kb的接收FIFO。每个FIFO被分成1024个块,每块4个双字(dwords)或16个字节。FIFO内存是在HDLC信道的基础上分配的。分配给每个HDLC通道的FIFO内存的数量是可编程的,可以最小为4个块,最大为1024个块。FIFO内存通过从一组块中创建一个循环链表来分配给HDLC通道,其中每个块指向链中的下一个块,最后一个块指向第一个块。FIFO块链表通过在链表中分配一个块作为该通道分配给特定的HDLC通道?s FIFO起始块指针。
在这个例子中,256个TX FIFO块和256个RX FIFO块被分配给HDLC通道。本例还使用了RX FIFO高水位179和TX FIFO低水位77。RX FIFO高水位表示在DMA开始将数据发送到PCI总线之前,HDLC引擎应该将多少块写入RX FIFO。对于所涉及的特定信道,高水位设置必须在一个块到比链表链中的块数少一个块之间。TX FIFO低水位表示在DMA开始从PCI总线获取更多数据之前,TX FIFO中应该留下多少块。HDLC通道防止发送欠流和接收溢出发生所需的FIFO内存,RX FIFO高水位和TX FIFO低水位的数量取决于应用程序。请注意,水印选择通常需要优化,并且非常依赖于应用程序。一般来说,将高低水印都设置为50%是一个很好的起点。最后,DS3134的TX FIFO和RX FIFO通过下表中列出的寄存器在HDLC通道上独立配置。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RHCDIS | 0910 | RFBPIS接收FIFO块指针间接选择 | 7.2 |
RHCD | 0914 | RFBP接收FIFO块指针 | 7.2 |
/*构建RX FIFO块链表0->1->2->3->4‡”。255→0 * /
For (block = 0;块& lt;255;Block = Block + 1)
{
/*位9?RFBP寄存器中的0表示链表*/中的下一个块
write_reg(RFBP, block + 1);
write_reg_IS (RFBPIS块);
}
/*最后一个块指向第一个块创建一个循环链表*/
write_reg (RFBP 0 x0000);
write_reg_IS (RFBPIS 0 x00ff);
/*将循环链表分配给特定的通道*/
write_reg (RFSBP 0 x0000);
write_reg_IS (RFSBPIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFHWMIS> | 0920 | 接收FIFO高水位间接选择 | 7.2 |
RFHWM | 0924 | 接收FIFO高水位 | 7.2 |
/*设置通道的RX FIFO高水位为179 */
write_reg (RFHWM 0 x00b3);
write_reg_IS (RFHWMIS、通道);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TFBPIS | 0990 | 发送FIFO块指针间接选择 | 7.2 |
TFBP | 0994 | 发送FIFO块指针 | 7.2 |
/ * TX FIFO块链表0→1→2→3→4‡”255→0 * /
For (block = 0;块& lt;255;Block = Block + 1)
{
/* RFBP寄存器中的9-0位表示链表中的下一个块*/
write_reg(TFBP, block + 1);
write_reg_IS (TFBPIS块);
}
/*最后一个块指向第一个块创建一个循环链表*/
write_reg (TFBP 0 x0000);
write_reg_IS (TFBPIS 0 x00ff);
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TFSBPIS | 0980 | 传输FIFO起始块指针间接选择 | 7.2 |
TFSBP | 0984 | 发送FIFO起始块指针 | 7.2 |
/*将循环链表分配给特定的通道*/
write_reg (TFSBP 0 x0000);
write_reg_IS (TFSBPIS、通道);
/*设置通道的TX FIFO低水位为77 */
write_reg (TFLWM 0 x004d);
write_reg_IS (TFLWMIS、通道);
Ȋ
配置DMA寄存器
DMA块处理数据包数据从FIFO块到PCI块的传输,反之亦然。PCI块控制DS3134和外部PCI总线之间的数据传输。主机被定义为位于PCI总线上的CPU或智能控制器,它指示DS3134如何处理传入和传出数据。
这是使用描述符完成的,这些描述符被定义为从主机传递到DMA块的预格式化消息,反之亦然。通过这些描述符,主机通知DMA要传输的数据包数据的位置和状态,以及在哪里放置接收到的数据包数据。DMA使用这些描述符告诉主机已传输的数据包数据的状态以及已接收的数据包数据的状态和位置。
在接收端,主机将写入空闲队列描述符,通知DMA可以将传入的数据包数据放置在哪里。与每个空闲队列条目相关联的是接收数据缓冲区位置和数据包描述符。由于DS3134使用无接收队列条目将接收到的数据包数据写入主机内存,因此它会在RX完成队列中创建条目。这些RX已完成队列条目通知主机接收数据的位置和状态。有关更详细的信息,请参阅ds3134数据表。主机必须通过写入下表中的所有寄存器来配置RX DMA:
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFQBA0 | 0700 | 接收空闲队列基址0(下一个字) | 8.1.3 |
RFQBA1 | 0704 | 接收空闲队列基地地址1(上一个字) | 8.1.3 |
RFQEA | 0708 | 接收空闲队列结束地址 | 8.1.3 |
RFQSBSA | 070 c | 接收免费的小缓冲区起始地址 | 8.1.3 |
RFQLBWP | 0710 | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
FQSBWP | 0714 | 接收空闲队列小缓冲区主机写指针 | 8.1.3 |
RFQLBRP | 0718 | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
RFQSBRP | 071 c | 接收空闲队列小缓冲区DMA读指针 | 8.1.3 |
RDQBA0 | 0730 | 接收完成队列基址0(下一个字) | 8.1.4 |
RDQBA1 | 0734 | 接收完成队列基地地址1(上字) | 8.1.4 |
RDQEA | 0738 | 接收完成队列结束地址 | 8.1.4 |
RDQRP | 073 c | 接收完成队列主机读指针 | 8.1.4 |
RDQWP | 0740 | 接收完成队列DMA写指针 | 8.1.4 |
RDBA0 | 0750 | 接收描述符基址0(下一个字) | 8.1.2 |
RDBA1 | 0754 | 接收描述符基址1(上一个字) | 8.1.2 |
RDMACIS | 0770 | 接收DMA配置间接选择 | 8.1.5 |
RDMAC | 0774 | 接收DMA配置 | 8.1.5 |
RLBS | 0790 | 接收大缓冲区大小 | 8.1.1 |
/* RX大缓冲区大小= 256字节*/
write_reg (RLBS 0 x0100);
/* RX空闲队列基址*/
write_reg(RFQBA0, rfq_base_addr &0 x0000ffff);
write_reg(RFQBA1, (rfq_base_addr >>)16),0 x0000ffff);
/* RX空闲队列大缓冲区读写指针= 0 */
write_reg (RFQLBRP 0 x0000);
write_reg (RFQLBWP 0 x0000);
/* RX空闲队列小缓冲区起始地址= 16 */
write_reg (RFQSBSA rfq_end_idx);
/* RX空闲队列小缓冲区读写指针= 0 */
write_reg (RFQSBRP 0 x0000);
write_reg (RFQSBWP 0 x0000);
/* RX空闲队列结束地址*/
write_reg (RFQEA rfq_end_idx);
/* RX完成队列基数地址*/
write_reg(RDQBA0, rdq_base_addr &0 x0000ffff);
write_reg(RDQBA1, (rdq_base_addr >>)16),0 x0000ffff);
/* RX完成队列读写指针= 0 */
write_reg (RDQRP 0 x0000);
write_reg (RDQWP 0 x0000);
/* RX完成队列结束地址*/
write_reg (RDQEA rdq_end_idx);
/* RX描述符基址*/
write_reg(RDBA0, rdscr_base_addr &0 x0000ffff);
write_reg(RDBA1, (rdscr_base_addr >>)16),0 x0000ffff);
/* RX DMA通道配置*
/* RDMAC寄存器中的数据被写入或从接收配置RAM中读取*/
/*设置位0 = 0禁用HDLC通道*/
/*设置位2?1 = 00仅用于大缓冲区*/
/*设置位6?3 = 0000 = 0 byteOffset从第一个数据缓冲区的数据缓冲区地址*/
/*设置位9?7 = 000,仅在数据包接收完成后,DMA写入完成队列*/
/*通过RDMACIS寄存器设置HDLC通道号*/
write_reg (RDMAC 0 x0000);
write_reg_IS(RDMACIS, 0x0400 + channel);
在传输端,主机将写入挂起队列,通知DMA哪些通道有准备传输的数据包数据。与每个挂起队列描述符相关联的是一个或多个描述数据包数据的传输数据包描述符的链表。每个传输包描述符都有一个指向传输数据缓冲区的指针,该缓冲区包含HDLC包的实际数据有效载荷。
当DS3134处理传输暂挂队列描述符项时,它创建传输完成队列描述符队列项。当DMA完成传输完整的数据包或数据缓冲区时,它将写入完成队列,这取决于DS3134的配置方式。通过这些已完成队列描述符,DMA通知主机有关传出数据包数据的状态。有关更详细的信息,请参阅ds3134数据表。主机必须通过写入下表中的所有寄存器来配置TX DMA:
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
TPQBA0 | 0800 | 传输等待队列基址0(下一个字) | 8.2.3 |
TPQBA1 | 0804 | 发送等待队列基地地址1(上一个字) | 8.2.3 |
TPQEA | 0808 | 传输等待队列结束地址 | 8.2.3 |
TPQWP | 080 c | 传输挂起队列主机写指针 | 8.2.3 |
TPQRP | 0810 | 传输挂起队列DMA读指针 | 8.2.3 |
TDQBA0 | 0830 | 发送完成队列基址0(下一个字) | 8.2.4 |
TDQBA1 | 0834 | 发送完成队列基址1(上一个字) | 8.2.4 |
TDQEA | 0838 | 发送完成队列结束地址 | 8.2.4 |
TDQRP | 083 c | 传输完成队列主机读指针 | 8.2.4 |
TDQWP | 0840 | 传输完成队列DMA写指针 | 8.2.4 |
TDBA0 | 0850 | 发送描述符基址0(下一个字) | 8.2.2 |
TDBA1 | 0854 | 发送描述符基址1(上一个字) | 8.2.2 |
TDMACIS | 0870 | 传输DMA配置间接选择 | 8.2.5 |
TDMAC | 0874 | 发送DMA配置 | 8.2.5 |
/* TX等待队列的基址*/
write_reg(TPQBA0, tpq_base_addr &0 x0000ffff);
write_reg(TPQBA1, (tpq_base_addr >>)16),0 x0000ffff);
/* TX挂起队列读写指针= 0 */
write_reg (TPQRP 0 x0000);
write_reg (TPQWP 0 x0000);
/*等待队列结束地址*/
write_reg (TPQEA tpq_end_idx);
/* TX完成队列的基址*/
write_reg(TDQBA0, tdq_base_addr &0 x0000ffff);
write_reg(TDQBA1, (tdq_base_addr >>16),0 x0000ffff);
/* TX完成队列读写指针= 0 */
write_reg (TDQRP 0 x0000);
write_reg (TDQWP 0 x0000);
/* TX完成队列结束地址*/
write_reg (TDQEA tdq_end_idx);
/* TX描述符基址*/
write_reg(TDBA0, tdscr_base_addr &0 x0000ffff);
write_reg(TDBA1, (tdscr_base_addr >>)16),0 x0000ffff);
/* TX DMA通道配置*/
/* TDMAC寄存器中的数据被写入或从接收配置RAM中读取*/
/*设置位0 = 0禁用HDLC通道*/
/*报文发送后写入完成队列设置位1 = 0 */
/*通过TDMACIS寄存器设置HDLC通道号*/
write_reg (TDMAC 0 x0000);
write_reg_IS(TDMACIS, 0x0200 + channel);
开启HDLC通道
DS3134初始化后的下一步是启用HDLC通道。除了已经描述的配置步骤之外,必须执行以下步骤才能在DS3134中启用数据包传输和接收:
在端口TX和RX配置ram中启用通道
启用端口一层数据传输
使能DS3134的TX DMA和RX DMA
使能HDLC通道TX DMA和RX DMA
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
MC | 0010 | 主配置寄存器 | 4.2 |
TP [n] CR | 02年xx | 发送端口n控制寄存器 | 5.2 |
RDMACIS | 0770 | 接收DMA配置间接选择寄存器 | 8.1.5 |
RDMAC | 0774 | 接收DMA配置寄存器 | 8.1.5 |
TDMACIS | 0870 | 传输DMA配置间接选择寄存器 | 8.2.5 |
TDMAC | 0874 | 传输DMA配置间接选择寄存器 | 8.2.5 |
/* TX端口控制寄存器*/
/*设置位3 = 1,允许数据正常传输*/
read_reg(TP0CR + 4*port, data);
write_reg(TP0CR + 4*port, data | 0x0008);
/*在DS3134主配置寄存器中启用TX和RX DMA */
/*设置位0 = 1使能接收DMA */
/*设置位2?1 = 00到突发长度最大为32个字。最佳长度*/
/*依赖于应用程序。* /
/*设置位3 = 1使能传输DMA */
/*设置PCI总线上HDLC数据包数据的第6位= 1为大端*/
/*设置位11?7 = 00000给端口0提供BERT的专用资源*/
write_reg (MC, 0 x0049);
/*从RX DMA配置RAM中读取当前通道值*/
/*设置RDMACIS位为7?0 = channel */
/*设置RDMACIS位为10?8 = 100读取dword 2 */的下字
/*设置RDMACIS位14 = 1从RAM读取*/
write_reg_IS(RDMACIS, 0x4400 + channel);
read_reg (RDMAC、数据);
/*启用通道RX DMA */
/*更新内存值*/
/*设置RDMAC位0 = 1,开启HDLC通道*/
/*设置RDMACIS位为7?0 = channel */
/*设置RDMACIS位为10?8 = 100,写dword 2 */的下字
/*设置RDMACIS位14 = 0写入RAM */
write_reg(RDMAC, data | 0x0001);
write_reg_IS(RDMACIS, 0x0400 + channel);
/*从TX DMA配置RAM中读取当前通道值*/
/*设置TDMACIS位7?0 = channel */
/*设置TDMACIS位11?8 = 0010读取dword 1 */的下字
/*设置TDMACIS位14 = 1从RAM读取*/
write_reg_IS(TDMACIS, 0x4200 + channel);
read_reg (TDMAC、数据);
/*启用通道TX DMA */
/*更新内存值*/
/*设置TDMAC位0 = 1,开启HDLC通道*/
/*设置TDMACIS位7?0 = channel */
/*设置TDMACIS位11?8 = 0010写入dword的下一字1 */
/*设置TDMACIS位14 = 0写入RAM */
write_reg((TDMAC, data | 0x0001);
write_reg_IS(TDMACIS, 0x0200 + channel);
将HDLC通道设置为环回模式
信道配置并启用后,大约需要5个帧周期,即625?s,用于DS3134的内部逻辑完成向新配置的转换。一旦这个转换完成了HDLC通道,那么可以将其置于环回模式,以便在该通道上传输的所有数据也将在该通道上接收。在五帧等待期之前将HDLC通道置于环回模式会导致将垃圾数据写入通道?RX FIFO。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RP [n] CR | 01 xx | 接收端口n控制寄存器 | 5.2 |
/*等待至少5帧周期的内部DS3134初始化完成*/
frame_wait (5);
/*设置位10 = 1使能环回?路由将数据发送回接收端口*/
read_reg(r0cr + 4*port, data);
write_reg(r0cr + 4*port, data | 0x0400);
对数据包进行排队、发送、接收和检查
一旦DS3134初始化完成,数据就可以发送和接收。由于DS3134处于环回模式,在HDLC通道上传输的所有数据也将在该通道上接收。介绍在主机内存中建立数据包、发送数据包、接收数据包和检查结果的过程。下面几节将详细描述这个过程。
初始化RX空闲队列
在DS3134可以将收到的数据包从其内部FIFO传输到主机内存之前,主机必须指示DS3134将数据放在哪里。这是通过RX空闲队列完成的。RX空闲队列中的每个条目都包含一个指向RX数据缓冲区的指针和一个RX包描述符索引。本例使用10个RX空闲队列条目。每个条目包含一个RX空闲队列大缓冲区和一个RX包描述符。DS3134 RX大数据缓冲区大小已设置为256字节(RLBS = 256)。此外,DS3134已配置为使用4字节的CRC,并将RX CRC写入RX数据缓冲区。因此,一个RX大数据缓冲区能够容纳多达252字节的数据包数据。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
RFQLBWP | 0710 | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
RFQLBRP | 0718 | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
/*检查RX大空闲队列的空间*/
read_reg (RFQLBWP wr_ptr);
read_reg (RFQLBRP rd_ptr);
If (rd_ptr >wr_ptr)
CNT = rd_ptr ?Wr_ptr - 1;
其他的
CNT = rfq_end_idx ?Wr_ptr + rd_ptr;
/*如果在RX空闲队列中的房间,则在队列中放入10个条目*/
/* dword 0 = RX数据缓冲区地址*/
/*(使用从RX缓冲区基址开始的RX数据缓冲区)*/
/* dword 1 =对应的RX描述符索引(使用RX描述符表索引0)*/
If (t >9)
{
Rx_dscr_idx = 0;
For (index=0, index <10, index++)
{
Wr_dword (rfq_base_addr + wr_ptr*8, rx_buf_base_addr+index*256);
Wr_dword (rfq_base_addr + wr_ptr*8+4, index);
If (wr_ptr == rfq_end_idx)
Wr_ptr = 0;
其他的
wr_ptr + +;
}
/* RX空闲队列大缓冲区写指针向前移动10 */
write_reg (RFQLBWP wr_ptr);
}
在主机内存中构建数据包
这个示例将发送一个由10个16字节数据包组成的链。在发送数据包之前,它必须在主机内存中构造。此外,还必须在主机内存中构造相应的TX包描述符。下面的代码详细介绍了这些任务。
/*在TX缓冲区的内存中创建一个16字节的数据包,其起始地址是TX缓冲区的基址*/
wr_dword (tx_buf_base_addr 0 x01234567);
wr_dword(tx_buf_base_addr + 4, 0x89ABCDEF);
wr_dword(tx_buf_base_addr + 8, 0x02468ACE);
wr_dword(tx_buf_base_addr + 12, 0x13579BDF);
/*第二个数据包进入第二个数据缓冲区(16字节的数据包进入256字节缓冲区)。* /
wr_dword(tx_buf_base_addr + 256, 0x08192A3B);
wr_dword(tx_buf_base_addr + 256 + 4, 0x4D5E6F70);
wr_dword(tx_buf_base_addr + 256 + 8, 0x8192A3B4);
wr_dword(tx_buf_base_addr + 256 + 12, 0xC5D6E7F8);
/*创建8多个数据包,每个数据包中都有唯一的数据。* /
For (index = 2, index <10日,指数+ +)
{
wr_dword(tx_buf_base_addr + index*256, 0x08192A30 + index);
wr_dword(tx_buf_base_addr + index*256 + 4, 0x4D5E6F71 + index);
wr_dword(tx_buf_base_addr + index*256 + 8, 0x8192A3B2 + index);
wr_dword(tx_buf_base_addr + index*256 + 12, 0xC5D6E7F3 + index);
}
创建10个TX描述符(每个4字)
/* TX描述符表索引0 */
/* dword0 = TX缓冲区地址*/
/* dword1 = EOF, CV,字节数(10h),下一个描述符指针*/
/* dword2 = HDLC通道*/
/* dword3 = PV,下一个挂起的描述符指针(设置为0)*/
Tx_dscr_idx = 0;
For (index = 0, index <10日,指数+ +)
{
w_dword (tdscr_base_addr +index* 16, tx_buf_base_addr+index*256);
If (index == 9)
Wr_dword (tdscr_base_addr + index*16 + 4, 0x80100000);
/*链结束,CV设为0 */
其他的
wr_dword(tdscr_base_addr + index*16 + 4, 0xC0100000 + index+1);
Wr_dword (tdscr_base_addr + index*16 + 8, 0x00000000 + channel);
Wr_dword (tdscr_base_addr + index*16 + 12, 0x00000000);
}
/*创建10个TX描述符,通过下一个描述符指针链接在一起。* /
发送和接收数据包
为了传输数据包,TX描述符必须放在传输挂起队列中,然后必须增加传输挂起队列写指针(TPQWP)。当DS3134检测到挂起队列不为空(TPQWP不等于TPQRP)时,它将开始处理队列条目,并传输数据包。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
SDMA | 0028 | DMA状态寄存器 | 4.3.2 |
TPQWP | 080 c | 传输挂起队列主机写指针 | 8.2.3 |
TPQRP | 0810 | 传输挂起队列DMA读指针 | 8.2.3 |
/*读取SDMA寄存器以清除任何先前设置的状态位*/
read_reg (SDMA、数据);
写TX Pending-Queue Entry
/*检查TX挂起队列的空闲空间*/
read_reg (TPQWP wr_ptr);
read_reg (TPQRP rd_ptr)
If (rd_ptr >wr_ptr)
CNT = rd_ptr ?Wr_ptr - 1;
其他的
CNT = rfq_end_idx ?Wr_ptr + rd_ptr;
/*如果在TX等待队列中有空间,为数据包创建一个条目*/
If (t >0)
{
/*位0?15描述符指针(0000h) */
/*位16?23 HDLC通道?(频道& lt; & lt;16) * /
Wr_dword (tpq_base_addr + wr_ptr*4, 0x0000000 + (channel <<)16));
/*提高TX挂起队列写指针*/
If (wr_ptr == tpq_end_idx)
Wr_ptr = 0;
其他的
Wr_ptr = Wr_ptr + 1;
write_reg (TPQWP wr_ptr);
}
检查结果
在等待数据包的发送和接收足够的时间后,可以执行几个检查来确定数据包的发送和接收是否成功。下面的代码详细说明了这些检查。
首字母缩写 | 抵消/地址 | 注册的名字 | 资料单张组 |
SDMA | 0028 | DMA状态寄存器 | 4.3.2 |
RFQLBWP | 0710 | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
RFQLBRP | 0718 | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
RDQRP | 073 c | 接收完成队列主机读指针 | 8.1.4 |
RDQWP | 0740 | 接收完成队列DMA写指针 | 8.1.4 |
TDQRP | 083 c | 传输完成队列主机读指针 | 8.2.4 |
TDQWP | 0840 | 传输完成队列DMA写指针 | 8.2.4 |
/*等待两个帧周期的数据包发送/接收*/
frame_wait (2);
/*检查SDMA寄存器,期望值= 0x6440;如果没有,则表示有错误*/
read_reg (SDMA、数据);
/*检查TX完成队列中有多少条目(从TDQRP到TDQWP的距离)*/
/*期望值为0Ah ?TX完成队列中的10个条目对应发送的10个数据包*/
read_reg (TDQRP rd_ptr);
read_reg (TDQWP wr_ptr);
If (wr_ptr >= rd_ptr)
CNT = wr_ptr - rd_ptr;
其他的
CNT = tdq_end_idx + 1 - rd_ptr + wr_ptr;
/*检查TX完成队列描述符*/
/*期望值= 0x00000000 */
/*位15?0表示描述符指针*/
/*位23?16表示通道号,在本例中应该是0 */
/*位28?26表示报文状态,全0表示报文传输完成,描述符*/
/*指针字段对应于HDLC包中传输的第一个描述符*/
For (index = 0;指数& lt;10;指数+ +)
{
Rd_dword (tdq_base_addr + rd_ptr*4, tdq_entry);
/*提前TX完成队列读指针*/
If (rd_ptr == tdq_end_idx)
Rd_ptr = 0;
其他的
Rd_ptr = Rd_ptr + 1;
write_reg (TDQRP rd_ptr);
}
/*检查RX大空闲队列,看看队列中有多少RX缓冲区(从RFQLBRP到RFQLBWP的距离)*/
/*期望数为0,因为队列在接收数据包之前有10个缓冲区,并且数据包接收需要10个缓冲区*/
read_reg (RFQLBRP rd_ptr);
read_reg (RFQLBWP wr_ptr);
If (wr_ptr >= rd_ptr)
CNT = wr_ptr - rd_ptr;
其他的
CNT = rfq_end_idx + 1 ?Rd_ptr + wr_ptr;
/*检查RX完成队列,查看是否收到任何数据包(从RDQRP到RDQWP的距离)
期望值是10 ?RX done-queue条目中的10个条目对应于应该接收到的10个数据包*/
read_reg (RDQRP rd_ptr);
read_reg (RDQWP wr_ptr);
If (wr_ptr >= rd_ptr)
CNT = wr_ptr - rd_ptr;
其他的
CNT = rdq_end_idx + 1 ?Rd_ptr + wr_ptr;
/*检查RX完成队列描述符*/
/*期望值= 0x40000000, */
/*位15?0表示描述符指针*/
/*位23?16表示通道号;在这个例子中它应该是0 */
/*位26?24表示缓冲区计数;所有0表示已接收到完整的数据包*/
/*位30 EOF = 1表示接收方描述符是链中的最后一个*/
For (index = 0;index <)10;指数+ +)
/*检查所有10个条目*/
{
Rd_dword (rdq_base_addr + 8*rd_ptr, rdq_entry);
/*检查对应的RX描述符(4 dwords) */
/* dword 0期望值= 0x10002680 RX缓冲区地址*/
/* dword 1期望值= 0x80140000 */
/*位15?0是下一个描述符指针*/
/*位28?16是数据缓冲区中存储的字节数*/
/*位31?29表示缓存状态*/
/* dword 2期望值= 0xxxxxxx00 * /
/*位7?0表示HDLC通道号(应该匹配TDQ入口通道)*/
/*位31?8表示时间戳(各不相同)*/
rdq_entry &0 x0000ffff※
Rd_dword (rdscr_base_addr + ȱ6*rdscr_idx, rdscr_dword0);
(rdscr_base_addr + 16*rd * cr_idx + 4, rdscr_dword1);
Rd_dword (rdscr_base_addr + 16*rds * r_idx + 8, rdscr_dword2);
/* Che / k在RX缓冲区中的d / d / ta */ dx >/* 16†字节的数据+†4字节的数据ɃRC */ /* Exp * cted va ^ ue = &
/ *,‣9;,ȣ9;0 x89abcdef * /Ȋ
/ *,ȣ9;,‣9;0 x024‶8 ace * /
/* &ȣ9;0x135ȷ9BDF */
/* & * 9;0x051 ' 7B09(4字节CRC) */
Byte_count = (rdscr_dword1 >>16),0 x00001fff;
For (addr = rdscr_dword0, addr <Rdscr_dword0 + byte_count;Addr = Addr + 4)
rd_dword (addr,数据);
/*移动RX完成队列读指针*/
If (rd_ptr == rdq_end_idx)
Rd_ptr = 0;
其他的
Rd_ptr = Rd_ptr + 1;
write_reg (RDQRP rd_ptr);
}
针对高速使用的额外优化
在每个应用程序的基础上对许多变量进行了优化,并且可以预期会进行一些性能调优。以下选项可能会有所帮助,具体取决于手头应用程序的细节:
ȼb>
端口时钟反转 ȼp>在具有高低频时钟频率的应用中,端口时钟采样沿和端口时钟采样沿之间的倾斜可能会成为满足DS3134?S数据满足时钟设置要求。对相应的DS3134端口时钟进行反相处理可以解决这个倾斜问题。通过在寄存器TP[n]CR内设置TICE位,可以逐端口反转TX端口时钟。RX端口时钟可以通过在寄存器RP[n]CR内设置RICE位来反转。
/*反转接收时钟/*
For (port = 0;港& lt;16;端口+ +){
RPnVal = read_reg(RP0CR + 4*port);
RpnVal = RpnVal | 1;}
/*发送时钟可以使用TPnCR寄存器以同样的方式反转*/
DS3134 TX/RX队列缓存
DS3134包含内部缓存存储器,可用于突发读/写多个DMA队列条目,从而减少DS3134执行这些DMA操作所使用的PCI总线带宽量。这些缓存在重置后被禁用。用于启用和配置这些内部缓存的寄存器如下:
TDMAQ寄存器用于启用和刷新DS3134 TX挂起队列缓存和TX完成队列缓存。RDMAQ寄存器用于启用和刷新RX自由队列缓存和RX完成队列缓存。寄存器TDQFFT和RDQFFT用于控制将TX完成队列缓存和RX完成队列缓存中的条目刷新到主机内存中各自的缓存中的频率。
TX/RX完成队列FIFO刷新定时器控制TX/RX完成队列条目在写入主机内存中的相应队列之前在缓存中等待的最大时间。为了最大限度地提高将已完成队列条目从内部缓存分解到主机内存的效率,应该将刷新定时器值设置为足够大的值,以便在正常操作下,达到缓存高水位时触发向主机内存写入缓存,而不是刷新定时器超时. 在数据包速率较低的应用程序中,刷新计时器值太大可能导致已完成队列条目放入缓存和将其写入主机内存中的队列之间的延迟增加。因此,FIFO刷新定时器的最优值必须根据应用需求来选择。
/*慢速刷新*/
write_reg (CHAT_REG_DMA_RDQFFT 0 x1000);
write_reg (CHAT_REG_DMA_TDQFFT 0 x1000);
有关如何配置这些寄存器的详细信息,请参阅ds3134数据表。
TDMAQ吗?TX DMA队列控制
TDQFFT吗?TX DMA完成队列FIFO刷新定时器
RDMAQ吗?RX DMA队列控制
RDQFFT吗?RX DMA完成队列FIFO刷新定时器
中断驱动的DMA队列主机服务
如果DS3134在桥接模式下工作,则PCI总线在DS3134 DMA传输和DS3134内部寄存器访问之间共享。如果主机处理器使用轮询方案来服务DS3134?在DMA队列中,轮询速率可能对DS3134?s的最大吞吐量能力,因为寄存器轮询正在使用PCI总线带宽的一定百分比。轮询还会给处理器带来不必要的负担,因为它会产生大量的开销。为了最小化用于DS3134寄存器访问的PCI总线带宽百分比,可以实现一个中断驱动的DMA队列服务方案。通过在ISDMA寄存器中设置适当的位,各种DS3134 dma队列访问事件可用于在DS3134 LINT和PINTA引脚上生成硬件中断。请参阅ds3134数据表了解更多详细信息。
另一个可用的优化是能够对DS3134进行编程,使其在多个TX/RX完成队列写入事件发生后才在SDMA寄存器中设置TDQW/RDQW位,而不是在单个写入事件发生后。此特性可用于降低TX/RX完成队列写中断的频率,并在检测到中断时增加准备处理的TX/RX完成队列条目的数量。因此,处理TX/RX已完成队列条目变得更加高效。在发送端,该特性由TDMAQ寄存器内的位场TDQT[2:0]控制。在接收端,这个特性由位域RDQT[2:0]和RDMAQ寄存器控制。请参阅ds3134数据表了解更多详细信息。
/*中断驱动代码几乎肯定需要在高速。* /
/*打开RLBR的中断*/
write_reg(CHAT_REG_GEN_ISDMA, read_reg(CHAT_REG_GEN_ISDMA) |
CHAT_BIT_GEN_SDMAISDMA_RLBR);
TX/RX FIFO大小和水印
最佳TX/RX FIFO块分配和水印设置根据应用需求有所不同。以下准则可以作为一个起点:
对于所有HDLC通道具有近似统一吞吐量要求的应用,在通道之间均匀地划分FIFO块。
对于HDLC通道没有统一吞吐量要求的应用,使用基于吞吐量的加权方案来划分通道之间的FIFO块。与吞吐量要求较低的通道相比,具有较高吞吐量要求的通道应该分配更多的FIFO块。
所有具有大致相同吞吐量要求的HDLC信道应该将其低传输水印设置为相同的值。同样,它们的高接收水印也应该设置为相同的值。
设置TX FIFO低水位为25%。必要时增加,直到达到可接受的TX底流率。
选择TX FIFO低水印值的目标是在通道TX FIFO数据请求到服务延迟和有效数据传输到TX FIFO之间找到一个可接受的平衡。低水位的值越低,数据传输效率越高,因为TX FIFO在服务时能够接受更多的数据。在服务时,TX FIFO可以接受的数据越多,DS3134就越有效地将主机内存中的新数据DMA到TX FIFO中。相反,低水位值越高,传输溢出的可能性就越小。在请求更多数据时,TX FIFO中的数据量越大,TX FIFO在欠流之前等待服务的时间就越长。
设置RX FIFO高水位为75%。必要时减少,直到达到可接受的RX溢出率。
选择RX FIFO高水位的目标是在RX FIFO数据请求到服务延迟和有效数据传输到TX FIFO之间找到一个可接受的平衡。高水位的高值可以最大限度地提高数据传输效率,因为RX FIFO在服务时将包含更多的数据。RX FIFO包含的数据越多,DS3134将数据DMA到主机内存的效率就越高。相反,高水位的值越低,接收溢出的可能性就越小。在请求清空RX FIFO时,RX FIFO中的空空间越多,RX FIFO在溢出之前等待服务的时间就越长。
DMA突发长度
缺省情况下,DS3134的DMA突发长度为32 dwords。在可以支持更长的突发的系统中,DS3134 DMA数据传输效率可以通过将其最大DMA突发长度增加到64、128或256个dwords来提高。这是通过DS3134 TX/RX DMA节流参数,位域TDT[1:0]和RDT[1:0],在DS3134 MC寄存器中完成的。增加DS3134的后果?s的最大DMA突发长度可能会增加待处理DS3134 DMA事务以及与DS3134共享PCI总线的其他设备上的待处理事务的延迟。
另外两个可以用来提高DMA突发效率的DS3134参数是PCI总线缓存线大小和PCI总线延迟计时器。这些参数控制DS3134如何执行PCI总线事务。
cache-line size-parameter,寄存器PLTH0[7:0],应该设置为匹配系统内存控制器的cache-line大小。当DS3134尝试执行一次超过缓存行大小的突发读取时,它将发出一次内存读取多个命令,而不是内存读取命令,以通知内存系统它正在启动多个缓存行读取。如果内存系统能够提前读取一条或多条额外的缓存线,那么当读取的数据总量超过一条缓存线时,就可以实现更高效的数据传输。
延迟定时器参数,寄存器PLTH0[15:8],控制在PCI总线仲裁器解除DS3134对总线的控制后,DS3134在放弃对总线的控制之前继续PCI总线事务的最小时间长度。s PGNT输入信号。延迟计时器值越大,潜在的PCI事务突发长度就越长,这可以导致更有效的DS3134数据传输。但是,由于DS3134放弃PCI总线的速度较慢,因此PCI总线上其他设备的潜在授予延迟会增加。有关这些特性的更多详细信息,请参阅ds3134数据表。
TX/RX FIFO HDLC通道仲裁
复位后,TX/RX FIFO HDLC通道仲裁模式设置为轮循模式。对于低通道数的应用程序,可以通过使用基于优先级的仲裁方案而不是轮询方案来减少通道服务延迟。TX/RX FIFO HDLC通道仲裁方案是通过MC寄存器中的TFPC[1:0]和RFPC[1:0]位域来选择的。请参阅ds3134数据表了解更多详细信息。
各种各样的技巧
为了帮助早期的代码开发,编写一个函数来回收数据包,然后使用它设置一个长测试循环。这将测试所有的循环队列,因为它们绕?常见的困难来源是什么?并确保代码中没有内存泄漏。
社群二维码
关注“华强商城“微信公众号
Copyright 2010-2023 hqbuy.com,Inc.All right reserved. 服务热线:400-830-6691 粤ICP备05106676号 经营许可证:粤B2-20210308