摘要: 应用说明369提供了如何在DS3134非信道化端口上以环回模式构造、发送、接收和检查数据包的示例。讨论了一个编码示例,以便于适应最终用户应用程序。
本应用说明描述了如何在配置模式下为DS3134上的非通道化操作配置单个端口的示例。此外,本示例还描述了如何在该端口上以环回模式构造、发送、 接收和检查数据包。本应用程序说明是作为编码示例提供的,以便于适应最终用户应用程序。
有一个勘误表,将有助于参考:内部芯片时序在非信道化模式。目前,(die rev B2)芯片不能正确处理非通道化模式。勘误表 描述了周围的工作,本应用说明也将根据勘误表配置部件。解决方法是将芯片配置为认为它在信道化模式下运行(本笔记将使用8MHz)。
DS3134的本地总线可以在两种模式下工作:
PCI桥接模式
配置模式
在配置模式下,本地总线仅用于控制和监视DS3134,而 HDLC数据包数据将通过PCI总线传输。在这种模式下,数据不能从本地总线传递到PCI 总线。(请参阅DS3134数据表第10节)。
本例配置如下:
DS3134的端口1作为非信道化端口操作。也就是说,端口接收/发送时钟,但没有同步脉冲。其他所有端口未被使用。
DS3134的端口1 DS0的0-127分配给HDLC通道3。DS3134的HDLC通道3被分配了10个RX FIFO块,10个TX FIFO块,RX FIFO高水位为8,TX低水位为4。
在主机内存中使用10个TX缓冲区、10个TX描述符和一个TX等待队列条目构建10个16字节的数据包。TX挂起队列入口指向一个描述符,该包描述符通过下一个描述符指针字段链接到总共10个描述符,并设置EOF和CV(参见数据表第130页)。
由于DS3134处于环回模式,当数据包被传输时,它也将被DS3134接收。接收到的数据包使用10个RX缓冲区、10个RX描述符和10个RX完成队列条目写入主机内存。
主机内存配置如下:
TX待处理队列基址(TPQBA1/0) = 0x10059084
TX完成队列基址(TDQBA1/0) = 0x10059604
TX描述符基址(TDBA1/0) = 0x10059B84
TX缓冲区基址= 0x1005B184
RX空闲队列基址(RFQBA1/0) = 0x10000000
RX完成队列基数地址(RDQBA1/0) = 0x10000B00
RX描述符基址(RDBA1/0) = 0x10001080
RX缓冲区基址= 0x10002680
接收方:
传输:
代码示例函数调用的定义
为了提高可读性,本例中的代码使用了几个函数调用。
这些函数的定义如下:
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 =等待的帧周期数
输出:没有
非信道化配置模式编码示例
这个应用程序笔记编码示例包括以下步骤:
复位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 x10000b00; / / RX完成队列结束地址/ / - RX完成队列大小= 16 rdq_end_idx = 0 x000f; / / RX描述符基地址/ / - RX描述符表大小= 256 rdscr_base_addr = 0 x10001080; / / RX数据缓冲区基地址rx_buf_base_addr =0 x10002680; / / TX未决队列基地址tpq_base_addr = 0 x10059084; / / TX未决队列结束地址/ / - TX等待队列大小= 16 tpq_end_idx = 0 x000f; / / TX队列完成基地址tdq_base_addr = 0 x10059604; / / TX完成队列结束地址/ / - TX完成队列大小= 16 tdq_end_idx = 0 x000f; / / TX描述符基地址/ / - TX描述符表大小= 256 tdscr_base_addr = 0 x10059b84; / / TX数据缓冲区基地址tx_buf_base_addr = 0 x1005b184;
配置PCI寄存器
在配置模式下,当
执行DMA操作时,PCI寄存器控制DS3134如何与PCI总线接口。PCI寄存器配置依赖于系统,因此下面的编码
示例可能需要修改以支持特定的用户应用程序。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0 x004/0a04 | PCMD0 | PCI命令状态0 | 9.2 |
// PCI命令/状态寄存器0 -控制DS3134 DMA功能 //设置位2 = 1允许设备在PCI总线上作为总线主操作(DMA需要) //设置位6 = 1对奇偶校验错误起作用 //设置位8 = 1启用PSERR引脚 write_reg(PCMD0, 0x0144);
配置第一层寄存器
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 = 11 8mhz模式 //设置比特10 = 0禁用本地环回 write_reg(r0cr + 4*端口,0x00C0) //设置TX端口控制寄存器 //设置比特2-0 = 000时钟,数据和同步不是倒/ /设置位3 = 0,迫使所有数据在TD 1 / /设置位5 - 4 = 0 00为同步脉冲时钟/ /设置位7 = 11年初8 MHz模式write_reg (TP0CR + 4 *端口0 x0c00); / / RX DS0的端口配置寄存器/ / 0 - 126残疾人,分配给为频道/ / CP [n] rdi位9 - 8 = 01接收配置write_reg (CP0RD + 8 *端口0 x0000 +频道);(DS0 = 0;ds0< 127;ds0=ds0+1) write_reg_IS(CP0RDIS + 8*port, 0x0100 + ds0); // TX端口配置寄存器 // ds0的0-126被禁用,分配给HDLC通道 // CP[n]RDIS位9-8 = 10的传输配置 write_reg(CP0RD + 8*port, 0x0000 + channel); for(ds0=0;ds0< 127;ds0 ds0 + 1) = write_reg_IS (CP0RDIS + 8 *端口0 x0200 + ds0); / / Unchannelized ds0到一个单独的解决方案/ /设置一个为频道/ /城堡初始化后,将其设置为一样的其他127个ds0 127(完成后)/ /设置为4频道/ / RX港口write_reg (CP0RD + 8 *端口0 x0000 +(+ 1)频道);write_reg_IS (CP0RDIS + 8 *端口0 x0100 + 127); / / TX港口write_reg (CP0RD + 8 *端口0 x0000 +(+ 1)频道);write_reg_IS (CP0RDIS + 8 *端口0 x0200 + 127);
配置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 = 0000分享关闭和打开标志write_reg (THCD 0 x0008); write_reg_IS (THCDIS、通道);
配置FIFO寄存器
DS3134包含一个16k字节的发送FIFO和一个16k字节的接收FIFO。每个FIFO被分成
1024个4字或16字节的块。FIFO内存是在HDLC信道的基础上分配的。分配给每个HDLC通道的FIFO内存的数量
是可编程的,可以是最少4块
和最多1024块。FIFO内存通过从一组块中创建一个循环
链表来分配给HDLC通道,其中每个块指向链中的下一个块,最后一个块指向第一个块。FIFO块链表通过在链表中分配一个块作为该通道的FIFO起始块指针来分配给特定的HDLC通道。
在这个例子中,十个TX FIFO块和十个RX FIFO块被分配到HDLC通道。这个 示例也使用RX FIFO高水位为8,TX FIFO低水位为4。RX FIFO 高水平线表示在DMA开始将数据发送到PCI总线之前,HDLC引擎应该将多少块写入RX FIFO 。对于所涉及的特定通道,高水位标志设置必须在一个块到比链表链中的块数少一个之间。TX FIFO低水位标志表明在DMA应该开始从PCI总线获得更多数据之前,TX FIFO应该留下多少块。HDLC通道为防止发送欠流和接收溢出发生所需的FIFO内存、RX FIFO高水位和TX FIFO低水位的数量取决于应用程序。DS3134的TX FIFO和RX FIFO通过下表中列出的寄存器在HDLC通道上独立配置。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0910 | RFBPIS | 接收FIFO块指针间接选择 | 7.2 |
0914 | RFBP | 接收FIFO块指针 | 7.2 |
//建立RX FIFO块链表 // 0->1->2->3->4 ....9->0 for (block=0;block< 9;块=块+ 1){/ /位在这里9 RFBP寄存器指示哪些块是/ /下一个链表write_reg (RFBP,块+ 1);write_reg_IS (RFBPIS、块);}/ /最后一块指向第一个块创建一个循环链表write_reg (RFBP 0 x0000); write_reg_IS (RFBPIS 0 x0009); / /循环链表分配给一个特定的频道write_reg (RFSBP 0 x0000); write_reg_IS (RFSBPIS、通道);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0920 | RFHWMIS | 接收FIFO高水位间接选择 | 7.2 |
0924 | RFHWM | 收到FIFO高水位标志 | 7.2 |
//设置RX FIFO高水位为8 write_reg(RFHWM, 0x0008); write_reg_IS(RFHWMIS, channel);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0990 | TFBPIS | 发送FIFO块指针间接选择 | 7.2 |
0994 | TFBP | 发送FIFO块指针 | 7.2 |
/ / TX FIFO块链表/ / 0→1→2→3→4…9->0 for (block=0;block< 9;block=block+1) { // RFBP寄存器中的9-0位表示链表中的下一个块 write_reg(TFBP, block+1); write_reg_IS(TFBPIS, block); } //最后一个块指向第一个块创建一个循环链表 write_reg(TFBP, 0x0000); write_reg_IS(TFBPIS, 0x0009);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0980 | TFSBPIS | 传输FIFO起始块指针间接选择 | 7.2 |
0984 | TFSBP | 发送FIFO起始块指针 | 7.2 |
//指定循环链表到指定通道 write_reg(TFSBP, 0x0000); write_reg_IS(TFSBPIS, channel); //设置通道的TX FIFO低水位为4 write_reg(TFLWM, 0x0004); write_reg_IS(TFLWMIS, channel);
配置DMA寄存器
DMA块处理数据包数据从FIFO块到PCI块的传输,反之亦然。PCI块控制DS3134和外部PCI总线之间的数据传输。主机被定义为位于PCI总线上的CPU或智能控制器,它指示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 | FQSBWP | 接收空闲队列小缓冲区主机写指针 | 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< 128;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),数据);/ /激活组个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< 128;ds0=ds0+1) { //从TX配置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),数据);/ /激活组个DS0 / / 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 *端口、数据| 0 x8000); write_reg_IS (CP0RDIS + 8 *端口0 x0200 + DS0);} / / TX端口控制寄存器/ /设置位3 = 1,允许数据传输正常read_reg (TP0CR + 4 *端口、数据);write_reg (TP0CR + 4 *端口、数据| 0 x0008);
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
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 = 0,写入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 +通道);
将HDLC通道设置为环回模式
在通道配置和启用后,DS3134的内部逻辑完成向新配置的转换大约需要5个帧周期,或625
微秒。一旦这个转换完成,HDLC通道就可以被置于环回模式,这样在该通道上传输的所有数据也将在该通道上接收。在5帧等待期之前将HDLC通道置于环回模式可能导致垃圾数据被写入通道的RX FIFO。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
01 xx | RP [n] CR | 接收端口n控制寄存器 | 5.2 |
//等待至少5个帧周期来完成内部DS3134初始化 frame_wait(5);
Unchannelized Workaraound重新分配ds0127以纠正HDLC通道
DS0 127为频道3 / /设置/ / 15的CP(港口)RD必须一个DS0 / / RX端口激活write_reg (CP0RD + 8 *端口0 x8000 +频道);write_reg_IS (CP0RDIS + 8 *端口0 x0100 + 127); / / TX港口write_reg (CP0RD + 8 *端口,0 x8000 +频道);write_reg_IS (CP0RDIS + 8 *端口0 x0200 + 127); / /等待5帧时间允许新的初始化完成frame_wait(5); / /设置一些10 = 1,使回路——线路传输数据到接收端口read_reg (RP0CR + 4 *端口, write_reg(r0cr + 4*port, data | 0x0400);
对数据包进行排队、发送、接收和检查
一旦DS3134初始化完成,就可以发送和接收数据。由于
DS3134处于环回模式,在HDLC通道上传输的所有数据也将在
通道上接收。本节将描述如何在主机内存中构建数据包、发送和接收数据包以及检查结果的过程。下面几节将详细描述这个过程。
初始化RX空闲队列
在DS3134可以将收到的数据包从其内部FIFO传输到主机内存之前,主机必须
指示DS3134将数据放在哪里。这是通过RX空闲队列完成的。RX空闲队列中的每个条目都包含一个指向RX数据缓冲区的指针和一个RX包描述符索引。本例使用十个RX空闲队列条目。每个条目包含一个RX空闲队列大缓冲区和一个RX包描述符。DS3134 RX大数据缓冲区大小已设置为256字节(RLBS = 256)。此外,DS3134已配置为使用4字节的CRC,并将RX CRC写入RX数据缓冲区。因此,一个RX大数据缓冲区能够容纳多达252字节的数据包数据。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0710 | RFQLBWP | 接收空闲队列大缓冲区主机写指针 | 8.1.3 |
0718 | RFQLBRP | 接收空闲队列大缓冲区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; else cnt = rfq_end_idx - wr_ptr + rd_ptr; //如果RX空闲队列中有空间,则在队列中放入10个条目 // dword 0 = RX数据缓冲区地址 //(从RX缓冲区的基址开始使用RX数据缓冲区) // dword 1 =对应的RX描述符索引(使用RX描述符表索引0) If (cnt >9) {rx_dscr_idx = 0;(指数= 0,index< 10日指数+ +){wr_dword (rfq_base_addr + wr_ptr * 8, rx_buf_base_addr +指数* 256);wr_dword (rfq_base_addr + wr_ptr * 8 + 4,指数);如果(wr_ptr = = rfq_end_idx) wr_ptr = 0;否则wr_ptr ++; } // 推进RX免费队列大型缓冲区写指针10 write_reg (RFQLBWP wr_ptr);}
在主机内存中构建数据包
这个示例将发送一个16字节的数据包。在发送数据包之前,它必须在主机内存中构造。此外,还必须在主机
内存中构造相应的TX数据包描述符。下面的代码详细介绍了这些任务。
//在TX缓冲区的内存中创建一个16字节的数据包,其起始地址是TX缓冲区的基数 //地址 wr_dword(tx_buf_base_addr, 0x01234567); 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 +4, 0x4D5E6F70); wr_dword(tx_buf_base_addr +256 +8, 0x8192A3B4); wr_dword(tx_buf_base_addr +256 +12, 0xC5D6E7F8); //再创建8个数据包,每个数据包中包含唯一的数据。
创建10个TX描述符(每个4字)
/ / TX描述符表索引0 / / dword0 = TX缓冲区地址/ / dword1 = EOF,简历,字节数(10 h),下一个描述符指针/ / dword2 =为通道/ / dword3 = PV,接下来等待描述符指针(设置为0)tx_dscr_idx = 0;为(指数= 0,index< 10日指数+ +){wr_dword (tx_buf_base_addr tdscr_base_addr +指数* 16日+指数* 256);如果(指数= = 9)wr_dword (tdscr_base_addr +指数* 16 + 4 0 x80100000);//链结束,CV设为0 else 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)时,它将开始处理队列条目,并传输
数据包。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
0028 | SDMA | DMA状态寄存器 | 4.3.2 |
080 c | TPQWP | 传输挂起队列主机写指针 | 8.2.3 |
0810 | TPQRP | 传输挂起队列DMA读指针 | 8.2.3 |
//读取SDMA寄存器,清除之前设置的状态位 read_reg(SDMA, data);
写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; else cnt = rfq_end_idx - wr_ptr + rd_ptr; //如果TX挂起队列中有空间为数据包创建一个条目 If (cnt >0) { //比特0-15描述符指针(0000h) //比特16-23 HDLC通道-(通道<<16) wr_dword(tpq_base_addr + wr_ptr*4, 0x0000000 + (channel <<) //提前TX挂起队列写指针 if (wr_ptr == tpq_end_idx) wr_ptr = 0; else wr_ptr = wr_ptr + 1; write_reg(TPQWP, wr_ptr); }
检查结果
在等待数据包的发送和接收足够的时间后,可以执行若干检查
,以确定数据包的发送和接收是否成功。下面的代码
详细说明了这些检查。
抵消/地址 | 首字母缩写 | 注册的名字 | 资料单张组 |
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的距离) //期望值为0Ah -在TX完成队列中对应10个发送的数据包 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数据包中的第一个描述符 for (index=0;index< 10;指数+ +){rd_dword (tdq_base_addr + rd_ptr * 4, tdq_entry); / /推进TX完成队列读取指针如果(rd_ptr = = tdq_end_idx) rd_ptr = 0;其他rd_ptr = rd_ptr + 1; write_reg (TDQRP rd_ptr);} / / RX大型免费队列查看有多少RX缓冲区队列(RFQLBWP RFQLBRP / /距离)/ /预期数量是0自接收报文队列之前10缓冲区和包/ /接待需要10缓冲区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) / /预期值是10 - 10项RX完成队列条目对应于10包/ /应该收到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表示收到完整的报文 //位30 EOF=1表示接收方描述符是链中的最后一个 for (index=0;index<10;index++) //检查所有10个条目 { rd_dword(rdq_base_addr + 8*rd_ptr,rdq_entry); / /检查相应的RX描述符字(4 dword) / / 0 = 0 x10002680期望值RX缓冲区地址/ / dword 1 = 0 x80140000期望值/ /位的是下一个结果,描述符指针/ /位28-16是存储在数据缓冲区的字节数算31 - 29显示缓冲区状态/ / / /位dword 2预期值= 0 xxxxxxx03 / /位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完成队列读指针 if (rd_ptr == rdq_end_idx) rd_ptr = 0; else rd_ptr = rd_ptr + 1; write_reg(RDQRP, rd_ptr); }
社群二维码
关注“华强商城“微信公众号
Copyright 2010-2023 hqbuy.com,Inc.All right reserved. 服务热线:400-830-6691 粤ICP备05106676号 经营许可证:粤B2-20210308