摘要: 本应用说明介绍如何在桥接模式下配置DS3134 HDLC控制器上的单个T1端口。本示例描述了如何在该端口上以环回模式构造、发送、接收和检查数据包。本应用程序说明是作为编码示例提供的,以便于适应最终用户应用程序。
本应用说明介绍如何在DS3134上配置单个T1端口,DS3134工作在 网桥模式下。此外,本示例还描述了如何在该端口上以环回模式构造、发送、接收和检查 数据包。本应用程序说明是作为编码示例提供的,以便于 适应最终用户应用程序。
DS3134的本地总线可以在两种模式下工作:
PCI桥接模式
配置模式
PCI桥接模式允许PCI总线上的主机访问本地总线。PCI总线用于 控制和监控DS3134和传输的数据包数据。DS3134将数据从PCI 总线映射到本地总线。(请参阅DS3134数据表第10节)。
本例配置如下:
DS3134的1号端口是信道化的T1端口。其他所有端口未被使用。
DS3134的端口1 DS0的0-3分配给HDLC通道3。所有其他端口1的DS0都是无符号的。
DS3134的HDLC通道3被分配了4个RX FIFO块,4个TX FIFO块,RX FIFO高水位标记为3,TX低水位标记为1。
在主机内存中使用一个TX缓冲区、一个TX描述符和一个TX暂挂队列条目构造一个16字节的数据包。由于DS3134处于环回模式,当数据包被传输时,它也将被DS3134接收。接收到的数据包使用一个RX缓冲区、一个RX描述符和一个RX完成队列条目写入主机内存。
主机内存配置如下:
TX挂起队列基址(TPQBA1/0) = 0x10000300
TX完成队列基址(TDQBA1/0) = 0x10000400
TX描述符基址(TDBA1/0) = 0x10000500
TX缓冲区基址= 0x10002000
RX空闲队列基址(RFQBA1/0) = 0x10000000
RX完成队列基数地址(RDQBA1/0) = 0x10000100
RX描述符基址(RDBA1/0) = 0x10000200
RX缓冲区基址= 0x10001000
接收方:
传输:
代码示例函数调用的定义
为了提高可读性,本例中的代码使用了几个函数调用。
这些函数的定义如下:
write_reg(地址、数据)
将指定的数据写入指定的DS3134寄存器地址
输入:
输出:没有
地址=要写入数据的寄存器地址
数据=要写入指定寄存器的数据
read_reg(地址、数据)
读取DS3134寄存器在指定地址的内容
输入:address =要读取的寄存器地址
输出:data =从寄存器中读取的值
write_reg_IS(地址、数据)
将指定的数据写入指定的DS3134间接选择寄存器,然后在返回之前等待该寄存器的忙位清除
输入:
输出:没有
函数代码:
Write_reg (address, data); bit_check = 0x8000; while (bit_check &0x8000) read_reg(地址,bit_check);
地址=要写入数据的间接选择寄存器
数据=要写入指定寄存器的数据
wr_dword(地址、数据)
将指定的32位数据值写入指定的32位主机内存地址
输入:
输出:没有
Address =要写入数据的主机内存地址
Data =要写入指定内存地址的数据
rd_dword(地址、数据)
从指定的32位主机内存地址中读取32位数据值
输入:address =需要读取的主机内存地址
输出:data =从主机内存中读取的32位数据值
frame_wait(计数)
提供等于帧周期计数的延迟,其中帧周期为125微秒
输入:count =等待的帧周期数
输出:没有
T1配置模式编码示例
这个应用笔记编码示例包括以下步骤:
复位DS3134
配置DS3134
开启HDLC通道
将HDLC通道设置为环回模式
对数据包进行排队、发送、接收和检查
以下各节将通过简要描述和编码示例详细介绍这些步骤。为了提高可读性,使用寄存器名代替地址。DS3134内部设备配置寄存器 对应的地址/偏移量列在附表中。另外,使用 缩写TX和RX分别表示发送端和接收端。有关更详细的信息,请参阅 DS3134数据表。
复位DS3134
重置DS3134包括两个步骤。首先,DS3134的内部RAM必须归零,
然后DS3134内部寄存器必须重置。
零DS3134内部内存
DS3134内部配置RAM不能通过复位芯片来清除,因此必须
手动调零。该任务是通过使用DS3134的适当数据和间接选择寄存器对
DS3134中的每个内部ram执行一系列写操作来完成的。具体操作步骤请参见
。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
03 xx | CP [n] rdi | 信道化端口n寄存器数据间接选择 | 5.3 |
03 xx | CP [n] RD | 信道化端口n注册数据 | 5.3 |
//所有端口的RX配置和TX配置为0port< 16;端口=港口+ 1){write_reg (CP0RD + 8 *端口0 x0000); (ds0 = 0;ds0< 128;ds0=ds0+1) { //设置位9-8 = 01选择RX配置内存 //设置位9-8 = 10选择TX配置内存 write_reg_IS(CP0RDIS + 8*port, (0x0100 + ds0)); write_reg_IS(CP0RDIS + 8*port, (0x0200 + ds0)); } }
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0400 | RHCDIS | 接收HDLC通道定义间接选择 | 6.2 |
0404 | RHCD | 接收HDLC通道定义 | 6.2 |
// 0 RX HDLC通道定义RAM write_reg(RHCD, 0x0000); for(channel=0;channel< 256;1) write_reg_IS(RHCDIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0480 | THCDIS | 传输HDLC信道定义间接选择 | 6.2 |
0484 | THCD | 传输HDLC信道定义 | 6.2 |
//调零TX HDLC通道定义RAM write_reg(THCD, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(THCDIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0900 | RFSBPIS | 接收FIFO起始块指针间接选择 | 7.2 |
0904 | RFSBP | 接收FIFO起始块指针 | 7.2 |
//将RX FIFO起始块指针归零 write_reg(RFSBP, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(RFSBPIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0910 | RFBPIS | 接收FIFO块指针间接选择 | 7.2 |
0914 | RFBP | 接收FIFO块指针 | 7.2 |
//置零RX FIFO块指针内存 write_reg(RFBP, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(RFBPIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0920 | RFHWMIS | 接收FIFO高水位间接选择 | 7.2 |
0924 | RFHWM | 收到FIFO高水位标志 | 7.2 |
//设置RX FIFO高水位为零 write_reg(RFHWM, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(RFHWMIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0980 | TFSBPIS | 传输FIFO起始块指针间接选择 | 7.2 |
0984 | TFSBP | 发送FIFO起始块指针 | 7.2 |
//设置FIFO起始块指针为零 write_reg(TFSBP, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(TFSBPIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0990 | TFBPIS | 发送FIFO块指针间接选择 | 7.2 |
0994 | TFBP | 发送FIFO块指针 | 7.2 |
//置零TX FIFO块指针内存 write_reg(TFBP, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(TFBPIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
09年a0 | TFLWMIS | 发送FIFO低水位间接选择 | 7.2 |
09年a4 | TFLWM | 发送FIFO低水位标记 | 7.2 |
//设置FIFO低水位为零 write_reg(TFLWM, 0x0000); for(channel=0;channel< 256;channel=channel+1) write_reg_IS(TFLWMIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0770 | RDMACIS | 接收DMA配置间接选择 | 8.1.5 |
0774 | RDMAC | 接收DMA配置 | 8.1.5 |
//设置RX DMA配置内存为0 write_reg(RDMAC, 0x0000); for(channel=0;channel< 256;1) write_reg_IS(RDMACIS, 0x0400 + channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0870 | TDMACIS | 传输DMA配置间接选择 | 8.2.5 |
0874 | TDMAC | 发送DMA配置 | 8.2.5 |
//调零TX DMA配置内存 write_reg(TDMAC, 0x0000); for(channel=0;channel< 256;1) write_reg_IS(TDMACIS, 0x0400 + channel);
重置DS3134内部寄存器
可以使用主复位寄存器
(MRID)对DS3134中的所有寄存器执行软件复位。当MRID寄存器的第0位设置为
1时,所有内部寄存器将被设置为默认值0。在设备被编程正常工作之前,主机必须将这个位设置回0。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0000 | MRID | 主复位&身份证登记 | 4.1 |
//使用MRID寄存器复位DS3134主控复位位。write_reg(MRID, 0x0001); write_reg(MRID, 0x0000);
配置DS3134
DS3134的配置包括以下步骤:
配置PCI寄存器
配置第一层寄存器
配置HDLC寄存器
配置FIFO寄存器
配置DMA寄存器
每个寄存器集的配置将在下面的小节中详细介绍。使用了几个变量 来提高可读性并提供更算法化的代码结构。下面的代码提供了 这些变量的初始化:
/ /这个例子使用端口1频道3端口= 1;信道= 3;/ / RX免费队列基地址rfq_base_addr = 0 x10000000; / / RX自由结束队列地址/ / - RX自由队列大小= 16 rfq_end_idx = 0 x000f; / / RX队列完成基地址rdq_base_addr = 0 x10000100; / / RX完成队列结束地址/ / - RX完成队列大小= 16 rdq_end_idx = 0 x000f; / / RX描述符基地址/ / - RX描述符表大小= 256 rdscr_base_addr = 0 x10000200; / / RX数据缓冲区基地址rx_buf_base_addr =0 x10001000; / / TX未决队列基地址tpq_base_addr = 0 x10000300; / / TX未决队列结束地址/ / - TX等待队列大小= 16 tpq_end_idx = 0 x000f; / / TX队列完成基地址tdq_base_addr = 0 x10000400; / / TX完成队列结束地址/ / - TX完成队列大小= 16 tdq_end_idx = 0 x000f; / / TX描述符基地址/ / - TX描述符表大小= 256 tdscr_base_addr = 0 x10000500; / / TX数据缓冲区基地址tx_buf_base_addr = 0 x10002000;
配置PCI寄存器
PCI桥接模式允许PCI总线上的主机访问本地总线。PCI总线用于
控制、监控DS3134并传输数据包数据。DS3134将数据从PCI
总线映射到本地总线。(请参阅DS3134数据表第10节)。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0 x004/0a04 | PCMD0 | PCI命令状态0 | 9.2 |
/ / DS3134配置寄存器映射到PCI总线基地址write_reg(颁证书,32 'h80000000); / / PCI命令/状态寄存器0 -控制DS3134 DMA功能/ /设置一些1 = 1,使访问内部设备配置寄存器通过PCI总线/ /(要求桥模式)/ /设置位2 = 1,允许总线主控在PCI总线设备操作所需(DMA) / /设置位6 = 1 / /设置奇偶校验错误行事有些8 = 1使PSERR销write_reg (PCMD0, 32 'h00000146);
配置第一层寄存器
DS3134的每个端口都包含一个1层控制器,该控制器执行多种功能,包括:
为输入和输出数据分配HDLC通道号
信道化的本地和网络环回
信道化选择64 kps, 56 kps或无数据
信道化传输DS0通道填充的所有
将数据路由到BERT函数或从BERT函数发送数据
将数据路由到V.54环路模式检测器
通过RP[n]CR、TP[n]CR、CP[n]RD和CP[n]RDIS 寄存器(其中n为需要配置的端口)以端口为基础进行层配置。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
01 xx | RP [n] CR | 接收端口n控制寄存器 | 5.2 |
02年xx | TP [n] CR | 发送端口n控制寄存器 | 5.2 |
03 xx | CP [n] rdi | 信道化端口n寄存器数据间接选择 | 5.3 |
03 xx | CP [n] RD | 信道化端口n注册数据 | 5.3 |
//设置RX端口控制寄存器 //设置2-0 = 000为时钟,数据和同步不反转 //设置5-4 = 00为同步脉冲0时钟早 //设置7-6 = 00为T1模式 //设置10 = 0为禁用本地环回 write_reg(r0cr + 4* Port, 0x0000) //设置TX端口控制寄存器 //设置2-0 = 000为时钟,数据和同步不是倒/ /设置位3 = 0,迫使所有数据在TD 1 / /设置位5 - 4 = 0 00为同步脉冲时钟早期为T1模式/ /设置位7 - 6 = 0 write_reg (TP0CR + 4 *端口0 x0000); / / RX DS0的端口配置寄存器/ / 0 - 3残疾,分配给为频道/ / CP [n] rdi位9 - 8 = 01接收配置write_reg (CP0RD + 8 *端口0 x0000 +频道);(DS0 = 0;ds0< 4;ds0=ds0+1) write_reg_IS(CP0RDIS + 8*port, 0x0100 + ds0); // TX端口配置寄存器 // ds0的0-3被禁用,分配给HDLC通道 // CP[n]RDIS位9-8 = 10的传输配置 write_reg(CP0RD + 8*port, 0x0000 + channel); for(ds0=0;ds0< 4;ds0=ds0+1) write_reg_IS(CP0RDIS + 8*port, 0x0200 + ds0);
配置HDLC寄存器
DS3134包含一个256通道的HDLC控制器,它执行第二层功能。该控制器执行的功能
包括:
零填充和去填充
标志检测和字节对齐
CRC的生成和校验
数据反转和位翻转
HDLC控制器通过RHCD、RHCDIS、THCD和THCDIS 寄存器在通道基础上进行配置。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0400 | RHCDIS | 接收HDLC通道定义间接选择 | 6.2 |
0404 | RHCD | 接收HDLC通道定义 | 6.2 |
0480 | THCDIS | 传输HDLC信道定义间接选择 | 6.2 |
0484 | THCD | 传输HDLC信道定义 | 6.2 |
/ / RX为配置/ /设置为32位CRC位3 - 2 = 10 write_reg (RHCD 0 x0008); write_reg_IS (RHCDIS、通道);/ / TX为配置/ /设置一些1 = 0到选择一个interfill字节7 e / /设置为32位CRC位3 - 2 = 10 / /为结束标志位11 - 8 = 1000 /不interfill字节/开旗write_reg (THCD 0 x0108); write_reg_IS (THCDIS、通道);
配置FIFO寄存器
DS3134包含一个16千字节的发送FIFO和一个16千字节的接收FIFO。每个FIFO被分成
1024个4字或16字节的块。FIFO内存是在HDLC信道的基础上分配的。分配给每个HDLC通道的FIFO内存的数量
是可编程的,可以是最少4块
和最多1024块。FIFO内存通过从一组块中创建一个循环
链表来分配给HDLC通道,其中每个块指向链中的下一个块,最后一个
块指向第一个块。FIFO块链表通过分配
链表中的一个块作为该通道的FIFO起始块指针来分配给特定的HDLC通道。
在这个例子中,4个TX FIFO块和4个RX FIFO块被分配给HDLC通道。这个 示例也使用RX FIFO高水位标记为3,TX FIFO低水位标记为1。RX FHFO 高水平线表示在DMA开始将数据发送到PCI总线之前,HDLC引擎应该将多少块写入RX FIFO 。对于特定通道 ,高水位标志设置必须在一个区块和比链表链中的区块数量少一个之间 。TX FIFO低水位标志表明在 DMA应该开始从PCI总线获取更多数据之前TX FIFO中应该留下多少块。FIFO内存的数量,RX FIFO高 水位线,和TX FIFO低水位线所需的HDLC通道,以防止传输底流 和接收溢出发生依赖于应用程序。 DS3134的TX FIFO和RX FIFO通过以下 表中列出的寄存器在HDLC通道上独立配置。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0910 | RFBPIS | 接收FIFO块指针间接选择 | 7.2 |
0914 | RFBP | 接收FIFO块指针 | 7.2 |
//建立RX FIFO块链表 // 0->1->2->3->0 for (block=0;block< 4;块=块+ 1){/ /位在这里9 RFBP寄存器指示哪些块是/ /下一个链表write_reg (RFBP,块+ 1);write_reg_IS (RFBPIS、块);}/ /最后一块指向第一个块创建一个循环链表write_reg (RFBP 0 x0000); write_reg_IS (RFBPIS 0 x0003); / /循环链表分配给一个特定的频道write_reg (RFSBP 0 x0000); write_reg_IS (RFSBPIS、通道);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0920 | RFHWMIS | 接收FIFO高水位间接选择 | 7.2 |
0924 | RFHWM | 收到FIFO高水位标志 | 7.2 |
//设置RX FIFO高水位为3 write_reg(RFHWM, 0x0003); write_reg_IS(RFHWMIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0990 | TFBPIS | 发送FIFO块指针间接选择 | 7.2 |
0994 | TFBP | 发送FIFO块指针 | 7.2 |
// TX FIFO块链表 // 0->1->2->3->0 for (block=0;block< 3;block=block+1) { // RFBP寄存器中的9-0位表示链表中的下一个块 write_reg(TFBP, block+1); write_reg_IS(TFBPIS, block); } //最后一个块指向第一个块创建一个循环链表 write_reg(TFBP, 0x0000); write_reg_IS(TFBPIS, 0x0003);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0980 | TFSBPIS | 传输FIFO起始块指针间接选择 | 7.2 |
0984 | TFSBP | 发送FIFO起始块指针 | 7.2 |
//指定循环链表到指定通道 write_reg(TFSBP, 0x0000); write_reg_IS(TFSBPIS, channel); //设置通道的TX FIFO低水位为1 write_reg(TFLWM, 0x0001); write_reg_IS(TFLWMIS, channel);
配置DMA寄存器
DMA块处理数据包数据从FIFO块到PCI块的传输,反之亦然。PCI块控制DS3134和外部PCI总线之间的数据传输。主机,定义为
CPU或位于PCI总线上的智能控制器,指示DS3134如何处理
传入和传出数据。
这是使用描述符完成的,这些描述符被定义为从主机 传递到DMA块的预格式化消息,反之亦然。通过这些描述符,主机通知DMA要传输的数据包数据的位置和 状态,以及在哪里放置接收到的数据包数据。DMA使用 这些描述符告诉主机已传输的数据包数据的状态,以及已接收的数据包数据的状态和 位置。
在接收端,主机将写入空闲队列描述符,通知DMA在哪里可以 放置传入的数据包数据。与每个空闲队列条目相关联的是一个接收数据缓冲区位置和 包描述符。当DS3134使用接收空闲队列条目将接收到的数据包数据写入主机 内存时,它会在RX完成队列中创建条目。这些RX完成队列项通知主机有关 位置和接收数据的状态。有关更详细的信息,请参阅DS3134数据表。 主机必须通过写入下表中的所有寄存器来配置RX DMA:
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0700 | RFQBA0 | 接收空闲队列基址0(下一个字) | 8.1.3 |
0704 | RFQBA1 | 接收空闲队列基地地址1(上一个字) | 8.1.3 |
0708 | RFQEA | 接收空闲队列结束地址 | 8.1.3 |
070 c | RFQSBSA | 接收免费的小缓冲区起始地址 | 8.1.3 |
0710 | RFQLBWP | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
0714 | RFQSBWP | 接收空闲队列小缓冲区主机写指针 | 8.1.3 |
0718 | RFQLBRP | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
071 c | RFQSBRP | 接收空闲队列小缓冲区DMA读指针 | 8.1.3 |
0730 | RDQBA0 | 接收完成队列基址0(下一个字) | 8.1.4 |
0734 | RDQBA1 | 接收完成队列基地地址1(上字) | 8.1.4 |
0738 | RDQEA | 接收完成队列结束地址 | 8.1.4 |
073 c | RDQRP | 接收完成队列主机读指针 | 8.1.4 |
0740 | RDQWP | 接收完成队列DMA写指针 | 8.1.4 |
0750 | RDBA0 | 接收描述符基址0(下一个字) | 8.1.2 |
0754 | RDBA1 | 接收描述符基址1(上一个字) | 8.1.2 |
0770 | RDMACIS | 接收DMA配置间接选择 | 8.1.5 |
0774 | RDMAC | 接收DMA配置 | 8.1.5 |
0790 | RLBS | 接收大缓冲区大小 | 8.1.1 |
// RX大缓冲区大小= 256字节 write_reg(RLBS, 0x0100); // RX空闲队列基数地址 write_reg(RFQBA0, rfq_base_addr & 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和; write_reg(RDQBA1, (rdq_base_addr >>16), // RX完成队列读写指针= 0 write_reg(RDQRP, 0x0000); write_reg(RDQWP, 0x0000); // RX完成队列结束地址 write_reg(RDQEA, rdq_end_idx); // RX描述符基址 write_reg(RDBA0, rdscr_base_addr & write_reg(RDBA1, (rdscr_base_addr >>16),0 x0000ffff); / / RX DMA通道配置/ / RDMAC寄存器中的数据写入或读取接收配置RAM / /设置位0 = 0禁用为频道/ /设置一些大型缓冲区只有/ / 201 = 00位6 = 0000 0字节抵消从第一个数据缓冲区的数据缓冲区地址/ /设置位9-7 = 000 DMA写入数据包接收完成后只做队列/ /设置为频道号码RDMACIS注册write_reg (RDMAC, write_reg_IS(RDMACIS, 0x0400 + channel);
在发送端,主机将写入挂起队列,通知DMA哪些通道有 准备传输的数据包数据。与每个挂起队列描述符相关联的是一个链表 ,其中包含一个或多个描述数据包数据的传输数据包描述符。这些传输数据包 描述符中的每个都有一个指向传输数据缓冲区的指针,该缓冲区包含HDLC 数据包的实际数据有效载荷。
当DS3134进程传输挂起队列描述符条目时,它创建传输完成队列 描述符队列条目。当DMA完成传输 完整数据包或数据缓冲区时,它将写入完成队列,这取决于DS3134的配置方式。通过这些完成队列 描述符,DMA通知主机有关传出数据包数据的状态。有关更详细的信息,请参阅DS3134 数据表。主机必须通过写入下表中 寄存器的所有寄存器来配置TX DMA:
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0800 | TPQBA0 | 传输等待队列基址0(下一个字) | 8.2.3 |
0804 | TPQBA1 | 发送等待队列基地地址1(上一个字) | 8.2.3 |
0808 | TPQEA | 传输等待队列结束地址 | 8.2.3 |
080 c | TPQWP | 传输挂起队列主机写指针 | 8.2.3 |
0810 | TPQRP | 传输挂起队列DMA读指针 | 8.2.3 |
0830 | TDQBA0 | 发送完成队列基址0(下一个字) | 8.2.4 |
0834 | TDQBA1 | 发送完成队列基址1(上一个字) | 8.2.4 |
0838 | TDQEA | 发送完成队列结束地址 | 8.2.4 |
083 c | TDQRP | 传输完成队列主机读指针 | 8.2.4 |
0840 | TDQWP | 传输完成队列DMA写指针 | 8.2.4 |
0850 | TDBA0 | 发送描述符基址0(下一个字) | 8.2.2 |
0854 | TDBA1 | 发送描述符基址1(上一个字) | 8.2.2 |
0870 | TDMACIS | 传输DMA配置间接选择 | 8.2.5 |
0874 | TDMAC | 发送DMA配置 | 8.2.5 |
// TX等待队列基地地址 write_reg(TPQBA0, tpq_base_addr & write_reg(TPQBA1, (tpq_base_addr >>16), // TX待处理队列读写指针= 0 write_reg(TPQRP, 0x0000); write_reg(TPQWP, 0x0000); // TX待处理队列结束地址 write_reg(TPQEA, tpq_end_idx); // TX待处理队列基础地址 write_reg(TDQBA0, tdq_base_addr & write_reg(TDQBA1, (tdq_base_addr >>16), // TX完成队列读写指针= 0 write_reg(TDQRP, 0x0000); write_reg(TDQWP, 0x0000); // TX完成队列结束地址 write_reg(TDQEA, tdq_end_idx); // TX描述符基址 write_reg(TDBA0, tdscr_base_addr & write_reg(TDBA1, (tdscr_base_addr >>16), // TX DMA通道配置 // TDMAC寄存器中的数据被写入或从接收配置RAM中读取 //设置位0 = 0禁用HDLC通道 //设置位1 = 0用于数据包传输后的写完成队列 //通过TDMACIS寄存器设置HDLC通道号 write_reg(TDMAC, 0x0000); write_reg_IS(TDMACIS, 0x0200 +通道);
开启HDLC通道
DS3134初始化后,下一步是启用HDLC通道。除了已经描述的
配置步骤之外,必须执行以下步骤才能使DS3134中的数据包
传输和接收:
在端口TX和RX配置RAM中启用通道
启用端口一层数据传输
使能DS3134的TX DMA和RX DMA
使能HDLC通道TX DMA和RX DMA
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0010 | MC | 主配置寄存器 | 4.2 |
02年xx | TP [n] CR | 发送端口n控制寄存器 | 5.2 |
03 xx | CP [n] rdi | 信道化端口n寄存器数据间接选择 | 5.3 |
03 xx | CP [n] RD | 信道化端口n注册数据 | 5.3 |
0770 | RDMACIS | 接收DMA配置间接选择寄存器 | 8.1.5 |
0774 | RDMAC | 接收DMA配置寄存器 | 8.1.5 |
0870 | TDMACIS | 传输DMA配置间接选择寄存器 | 8.2.5 |
0874 | TDMAC | 传输DMA配置间接选择寄存器 | 8.2.5 |
//启用端口层RX配置RAM for (ds0=0;ds0< 4;ds0=ds0+1) { //从RX配置内存中读取当前数据值 //设置CP[n]RDIS位6-0 =ds0 //设置CP[n]RDIS位14 = 1从RAM中读取数据 //设置CP[n]RDIS位9-8 = 01选择RX配置内存 write_reg_IS(CP0RDIS + 8*port, 0x4100 + ds0); read_reg(CP0RD + 8*port, 0x4100 + ds0),数据);/ /更新内存用新值/ /设置CP [n] rdi位6 - 0 = DS0 / /设置CP [n] rdi位14 = 0写数据到内存/ /设置CP [n] rdi位9 - 8 = 01选择处方配置RAM / /使DS0通过设置一些15 = 1 CP [0] RD注册write_reg (CP0RD + 8 *端口、数据| 0 x8000); write_reg_IS (CP0RDIS + 8 *端口0 x0100 + DS0);} / /使包传输端口图层1 TX配置RAM (DS0 = 0;ds0< 4;ds0=ds0+1) { //从RX配置RAM中读取当前数据值 //设置CP[n]RDIS位6-0 =ds0 //设置CP[n]RDIS位14 = 1从RAM中读取数据 //设置CP[n]RDIS位9-8 = 10选择TX配置RAM write_reg_IS(CP0RDIS + 8*port, 0x4200 + ds0); read_reg(CP0RD + 8*port, 0x4200 + ds0),bit_check); / /更新内存用新值/ /设置CP [n] rdi位6 - 0 = DS0 / /设置CP [n] rdi位14 = 0写数据到内存/ /设置CP [n] rdi位9 - 8 = 10选择TX配置RAM / /使DS0通过设置一些15 = 1 CP [0] RD注册write_reg (CP0RD + 8 *端口,bit_check | 0 x8000); write_reg_IS (CP0RDIS + 8 *端口0 x0200 + DS0);} / / TX端口控制寄存器/ /设置位3 = 1,允许数据传输正常read_reg (TP0CR + 4 *端口、数据);write_reg (TP0CR + 4 *端口,数据| 0x0008);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0010 | MC | 主配置 | 4.2 |
//在DS3134主配置寄存器中使能TX和RX DMA //设置位0 = 1使能接收DMA //设置位2-1 = 00使能突发长度最大为32个dwords //设置位3 = 1使能发送DMA //设置位6 = 1使PCI总线上的HDLC数据包数据是大端序 //设置位11-7 = 00000选择端口0有BERT专用资源 write_reg(MC, //从RX DMA配置内存中读取当前通道值 //设置RDMACIS位7-0 =通道 //设置RDMACIS位10-8 = 100读取dword 2的下一个字 //设置RDMACIS位14 = 1从RAM中读取 write_reg_IS(RDMACIS, 0x4400 +通道); read_reg(RDMAC, //启用RX DMA通道 //更新RAM的新值 //设置RDMAC位0 = 1启用HDLC通道 //设置RDMACIS位7-0 =通道 //设置RDMACIS位10-8 = 100读取dword 2的下一个字 //设置RDMACIS位14 = 1从RAM读取 write_reg(RDMAC, data | 0x0001); write_reg_IS(RDMACIS, //从TX DMA配置RAM中读取当前通道值 //设置TDMACIS位7-0 =通道 //设置TDMACIS位11-8 = 0010读取dword 1的下一个字 //设置TDMACIS位14 = 1从RAM中读取 write_reg_IS(TDMACIS, 0x4200 +通道); read_reg(TDMAC, //启用通道TX DMA //用新值更新RAM //设置TDMAC位0 = 1启用HDLC通道 //设置TDMACIS位7-0 =通道 //设置TDMACIS位11-8 = 0010读取dword 1的下一个字 //设置TDMACIS位14 = 0写入RAM write_reg((TDMAC, data | 0x0001); write_reg_IS(TDMACIS, 0x0200, + channel);
将HDLC通道设置为环回模式
在通道配置和启用后,DS3134的内部逻辑完成向新配置的转换大约需要5个帧周期,或625
微秒。一旦这个转换完成,HDLC通道就可以被置于环回模式,这样在通道上传输的所有
数据也将在该通道上被接收。在5帧等待期之前将HDLC通道置于
环回模式可能导致垃圾数据被写入
通道的RX FIFO。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
01 xx | RP [n] CR | 接收端口n控制寄存器 | 5.2 |
//等待至少5个帧周期完成DS3134内部初始化frame_wait(5); //设置bit10 = 1使环回路由将数据发送回接收端口 read_reg(r0cr + 4*端口,数据) write_reg(r0cr + 4*端口,数据| 0x0400);
对数据包进行排队、发送、接收和检查
一旦DS3134初始化完成,就可以发送和接收数据。由于
DS3134处于环回模式,在HDLC通道上传输的所有数据也将在
通道上接收。本节将描述如何在主机内存中构建数据包、发送和
接收数据包以及检查结果的过程。下面几节将详细描述这个过程。
初始化RX空闲队列
在DS3134可以DMA从其内部FIFO接收到主机内存的数据包之前,主机必须
指示DS3134将数据放在哪里。这是通过RX空闲队列完成的。RX free
队列中的每个条目都包含一个指向RX数据缓冲区的指针和一个RX包描述符索引。本例使用一个
RX空闲队列条目。这个条目包含一个RX空闲队列大缓冲区和一个RX包描述符。DS3134 RX大数据缓冲区大小已设置为256字节(RLBS = 256)。此外,DS3134
已配置为使用4字节的CRC,并将RX CRC写入RX数据缓冲区。因此,一个
RX大数据缓冲区能够容纳多达252字节的数据包数据。
//检查RX大空闲队列中是否有空间 read_reg(RFQLBWP, wr_ptr); read_reg(RFQLBRP, rd_ptr); if (rd_ptr >wr_ptr) cnt = rd_ptr - wr_ptr - 1; else cnt = rfq_end_idx - wr_ptr + rd_ptr; //如果RX空闲队列中有空间,则在队列中放入1个条目 // dword 0 = RX数据缓冲区地址 //(从RX缓冲区的基址开始使用RX数据缓冲区) // dword 1 =对应的RX描述符索引(使用RX描述符表索引0) If (cnt >0) { rx_dscr_idx = 0; wr_dword(rfq_base_addr + wr_ptr*8, rx_buf_base_addr); wr_dword(rfq_base_addr + wr_ptr*8 + 4, rx_dscr_idx); //将RX空闲队列大缓冲区写指针提前1个 write_reg(RFQLBWP, (wr_ptr + 1) % (rfq_end_idx + 1)); }
在主机内存中构建数据包
这个示例将发送一个16字节的数据包。在发送数据包之前,必须在
主机内存中构造它。此外,还必须在主机
内存中构造相应的TX数据包描述符。下面的代码详细介绍了这些任务。
/ /创建一个16字节的数据包在TX缓冲区的内存起始地址是TX缓冲区基地/ /地址wr_dword (tx_buf_base_addr 0 x01234567); wr_dword (tx_buf_base_addr + 4 0 x89abcdef); wr_dword (tx_buf_base_addr + 8,0 x02468ace); wr_dword (tx_buf_base_addr + 12,0 x13579bdf); / /创建一个TX描述符(4 dword) TX的包描述符/ / TX描述符表索引0 / / dword0 = TX缓冲区地址/ / dword1 = EOF,简历,字节数,下一个描述符指针 // dowrd2 = HDLC通道 // dword3 = PV,下一个挂起的描述符指针(设为0) tx_dscr_idx = 0 wr_dword(tdscr_base_addr + tx_dscr_idx*16 + 16, tx_buf_base_addr) wr_dword(tdscr_base_addr + tx_dscr_idx*16 + 4, 0x80100000) wr_dword(tdscr_base_addr + tx_dscr_idx*16 + 8, 0x00000000 +通道) wr_dword(tdscr_base_addr + tx_dscr_idx*16 + 12, 0x00000000);
发送和接收数据包
为了传输数据包,TX描述符必须放在传输挂起队列中,然后
传输挂起队列写指针(TPQWP)必须增加。当DS3134检测到
挂起队列不为空(TPQWP不等于TPQRP)时,它将开始处理队列条目,并传输
数据包。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0710 | RFQLBWP | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
0718 | RFQLBRP | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
抵消/地址首字母缩写注册的名字资料单张组0028SDMADMA状态寄存器4.3.2080 cTPQWP传输挂起队列主机写指针8.2.30810TPQRP传输挂起队列DMA读指针8.2.3
//读取SDMA寄存器以清除任何先前设置的状态位 read_reg(SDMA, data); //检查TX挂起队列的空闲空间 read_reg(TPQWP, wr_ptr); read_reg(TPQRP, rd_ptr); if (rd_ptr >wr_ptr) cnt = rd_ptr - wr_ptr - 1; else cnt = rfq_end_idx - wr_ptr + rd_ptr; //如果TX挂起队列中有空间为数据包创建一个条目 If (cnt >0) { wr_dword(tpq_base_addr + wr_ptr*4, 0x0000000 +(通道<< //提前TX挂起队列写指针 write_reg(TPQWP, (wr_ptr + 1) % (tpq_end_idx + 1)); }
检查结果
在等待数据包的发送和接收足够的时间后,可以执行若干检查
,以确定数据包的发送和接收是否成功。下面的代码
详细说明了这些检查。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0028 | SDMA | DMA状态寄存器 | 4.3.2 |
0710 | RFQLBWP | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
0718 | RFQLBRP | 接收空闲队列大缓冲区DMA读指针 | 8.1.3 |
073 c | RDQRP | 接收完成队列主机读指针 | 8.1.4 |
0740 | RDQWP | 接收完成队列DMA写指针 | 8.1.4 |
083 c | TDQRP | 传输完成队列主机读指针 | 8.2.4 |
0840 | TDQWP | 传输完成队列DMA写指针 | 8.2.4 |
//等待2帧周期的数据包发送/接收 frame_wait(2); //检查SDMA寄存器 //期望值= 0x6440,如果不是,则表示有错误 read_reg(SDMA, data); //检查TX完成队列中有多少条目(从TDQRP到TDQWP的距离) //期望值为1 -在TX完成队列中有一个条目对应于发送的数据包 read_reg(TDQRP, rd_ptr); read_reg(TDQWP,wr_ptr);如果(wr_ptr祝辞= rd_ptr)问= wr_ptr - rd_ptr;其他问= tdq_end_idx + 1 - rd_ptr + wr_ptr; / /检查TX完成队列描述符/ /预期值= 0 x0003000 0表示描述符指针/ / / /比特位23-16显示通道号码,应该是3在这个例子/ /位28-26指示数据包状态,所有0表示数据包传输完成,描述符 //指针字段对应于已经传输的HDLC数据包中的第一个描述符 rd_dword(tdq_base_addr + rd_ptr*4, tdq_entry); //推进TX完成队列读指针 write_reg(TDQRP,(rd_ptr + 1) % (tdq_end_idx + 1)); //检查RX大空闲队列,看看队列中有多少RX缓冲区(从RFQLBRP到RFQLBWP的距离 //) //期望的数字是0,因为队列在收到数据包之前有一个缓冲区,数据包接收 //需要1个缓冲区 read_reg(RFQLBRP, rd_ptr); read_reg(RFQLBWP,wr_ptr);如果(wr_ptr祝辞= rd_ptr)问= wr_ptr - rd_ptr;其他问= rfq_end_idx + 1 - rd_ptr + wr_ptr; / /检查RX完成队列是否收到任何数据包(距离RDQRP RDQWP) / /期望值是1 - RX完成队列中的一个条目条目对应于一个包/ /应该收到read_reg (RDQRP rd_ptr); read_reg (RDQWP,wr_ptr);如果(wr_ptr祝辞= rd_ptr)问= wr_ptr - rd_ptr;其他问= rdq_end_idx + 1 - rd_ptr + wr_ptr; / /检查RX完成队列描述符/ / = 0 x40030000期望值,0表示描述符指针/ / / /比特位23-16显示通道号码,应该是3在这个例子/ /位26-24指示缓冲区数,所有0意味着一个完整的包已经收到rd_dword (rdq_base_addr + 8 * rd_ptr,rdq_entry); / /检查相应的RX描述符字(4 dword) / / 0 = 0 x10001000期望值RX缓冲区地址/ / dword 1 = 0 x80140000期望值/ /位的是下一个结果,描述符指针/ /位28-16是存储在数据缓冲区的字节数算31 - 29显示缓冲区状态/ / / /位dword 2除外值= 0 x000b7503 / /位7表示为频道号码(应该匹配TDQ入口通道)/ /位31-8显示时间戳(不同)rdscr_idx = rdq_entry,0 x0000ffff; rd_dword (rdscr_base_addr + 16 * rdscr_idx rdscr_dword0); rd_dword (rdscr_base_addr + 16 * rdscr_idx + 4, rdscr_dword1); rd_dword (rdscr_base_addr + 16 * rdscr_idx + 8, rdscr_dword2); / /检查RX缓冲区中的数据/ / 16字节的数据+ 4字节的CRC / /预期值= 0 0 x89abcdef x01234567 / / / / 0 x02468ace / / 0 x13579bdf / / 0 x05127b09(4字节的CRC) byte_count = (rdscr_dword1祝辞祝辞16),0x00001FFF; for (addr=rdscr_dword0, addr<rdscr_dword0+byte_count;addr=addr+4) rd_dword(addr, data); //推进RX完成队列读指针 write_reg(RDQRP, (rd_ptr + 1) % (rdq_end_idx + 1));
社群二维码
关注“华强商城“微信公众号
Copyright 2010-2023 hqbuy.com,Inc.All right reserved. 服务热线:400-830-6691 粤ICP备05106676号 经营许可证:粤B2-20210308