关于牛津半导体 PCIe (Tornado) 950 串口设备的说明

牛津半导体 PCIe (Tornado) 950 串口设备由固定的 62.5MHz 时钟输入驱动,该时钟输入源自 100MHz PCI Express 时钟。

波特率生成器产生的波特率从该输入频率获得,方法是将其除以时钟分频器(clock prescaler),该分频器可设置为 1 到 63.875 之间的任意值,步长为 0.125;然后使用与原始 8250 相同的常规 16 位除数(divisor),将频率除以 1 到 65535 之间的一个值。最后,使用一个可编程的过采样率(oversampling rate),它可以取 4 到 16 之间的任意值,以进一步分频并确定实际使用的波特率。通过这种方式,可以获得从 15625000bps 到 0.933bps 的波特率。

默认情况下,过采样率设置为 16,时钟分频器设置为 33.875,这意味着用作常规 16 位除数参考的频率是 115313.653,这与原始 8250 使用的 115200 频率足够接近,以便不了解额外时钟控制的软件可以使用相同的除数来获得所需的波特率。

过采样率通过 TCR 寄存器编程,时钟分频器通过 CPR/CPR2 寄存器对编程[OX200] [OX952] [OX954] [OX958]。然而,要改变分频器 33.875 的默认值,必须通过设置 EFR 的第 4 位来显式启用增强模式。在该模式下,设置 MCR 中的第 7 位会启用分频器,否则它将被旁路,如同使用了值 1。此外,向 CPR 写入任何值都会清除 CPR2,以兼容为没有 CPR2 中额外分频器第 9 位的老式传统 PCI 牛津半导体设备编写的旧软件,因此 CPR/CPR2 寄存器对必须按正确的顺序编程。

通过使用这些参数,可以获得从 15625000bps 到 1bps 的速率,对于标准和许多非标准速率,可以获得精确或高精度的实际比特率。

以下是标准和一些非标准波特率(包括牛津半导体文档中引用的波特率)的数值,给出了请求速率 (r)、实际产生的速率 (a) 及其与请求速率的偏差 (d),以及由新的 get_divisor 处理器产生的过采样率 (tcr)、时钟分频器 (cpr) 和除数 (div) 的值

r: 15625000, a: 15625000.00, d:  0.0000%, tcr:  4, cpr:  1.000, div:     1
r: 12500000, a: 12500000.00, d:  0.0000%, tcr:  5, cpr:  1.000, div:     1
r: 10416666, a: 10416666.67, d:  0.0000%, tcr:  6, cpr:  1.000, div:     1
r:  8928571, a:  8928571.43, d:  0.0000%, tcr:  7, cpr:  1.000, div:     1
r:  7812500, a:  7812500.00, d:  0.0000%, tcr:  8, cpr:  1.000, div:     1
r:  4000000, a:  4000000.00, d:  0.0000%, tcr:  5, cpr:  3.125, div:     1
r:  3686400, a:  3676470.59, d: -0.2694%, tcr:  8, cpr:  2.125, div:     1
r:  3500000, a:  3496503.50, d: -0.0999%, tcr: 13, cpr:  1.375, div:     1
r:  3000000, a:  2976190.48, d: -0.7937%, tcr: 14, cpr:  1.500, div:     1
r:  2500000, a:  2500000.00, d:  0.0000%, tcr: 10, cpr:  2.500, div:     1
r:  2000000, a:  2000000.00, d:  0.0000%, tcr: 10, cpr:  3.125, div:     1
r:  1843200, a:  1838235.29, d: -0.2694%, tcr: 16, cpr:  2.125, div:     1
r:  1500000, a:  1492537.31, d: -0.4975%, tcr:  5, cpr:  8.375, div:     1
r:  1152000, a:  1152073.73, d:  0.0064%, tcr: 14, cpr:  3.875, div:     1
r:   921600, a:   919117.65, d: -0.2694%, tcr: 16, cpr:  2.125, div:     2
r:   576000, a:   576036.87, d:  0.0064%, tcr: 14, cpr:  3.875, div:     2
r:   460800, a:   460829.49, d:  0.0064%, tcr:  7, cpr:  3.875, div:     5
r:   230400, a:   230414.75, d:  0.0064%, tcr: 14, cpr:  3.875, div:     5
r:   115200, a:   115207.37, d:  0.0064%, tcr: 14, cpr:  1.250, div:    31
r:    57600, a:    57603.69, d:  0.0064%, tcr:  8, cpr:  3.875, div:    35
r:    38400, a:    38402.46, d:  0.0064%, tcr: 14, cpr:  3.875, div:    30
r:    19200, a:    19201.23, d:  0.0064%, tcr:  8, cpr:  3.875, div:   105
r:     9600, a:     9600.06, d:  0.0006%, tcr:  9, cpr:  1.125, div:   643
r:     4800, a:     4799.98, d: -0.0004%, tcr:  7, cpr:  2.875, div:   647
r:     2400, a:     2400.02, d:  0.0008%, tcr:  9, cpr:  2.250, div:  1286
r:     1200, a:     1200.00, d:  0.0000%, tcr: 14, cpr:  2.875, div:  1294
r:      300, a:      300.00, d:  0.0000%, tcr: 11, cpr:  2.625, div:  7215
r:      200, a:      200.00, d:  0.0000%, tcr: 16, cpr:  1.250, div: 15625
r:      150, a:      150.00, d:  0.0000%, tcr: 13, cpr:  2.250, div: 14245
r:      134, a:      134.00, d:  0.0000%, tcr: 11, cpr:  2.625, div: 16153
r:      110, a:      110.00, d:  0.0000%, tcr: 12, cpr:  1.000, div: 47348
r:       75, a:       75.00, d:  0.0000%, tcr:  4, cpr:  5.875, div: 35461
r:       50, a:       50.00, d:  0.0000%, tcr: 16, cpr:  1.250, div: 62500
r:       25, a:       25.00, d:  0.0000%, tcr: 16, cpr:  2.500, div: 62500
r:        4, a:        4.00, d:  0.0000%, tcr: 16, cpr: 20.000, div: 48828
r:        2, a:        2.00, d:  0.0000%, tcr: 16, cpr: 40.000, div: 48828
r:        1, a:        1.00, d:  0.0000%, tcr: 16, cpr: 63.875, div: 61154

在波特率基数设置为 15625000 且受 serial8250_get_baud_rate 强制执行的无符号 16 位 UART_DIV_MAX 限制下,低于 300bps 的标准波特率无法以常规方式获得,例如,200bps 的速率需要将波特率基数除以 78125,这超出了无符号 16 位的范围。如果需要,仍可以通过以下方式编码分频器、过采样率和时钟除数(DLM/DLL)的值来使用历史的 spd_cust 功能以获得此类速率

 31 29 28             20 19   16 15                            0
+-----+-----------------+-------+-------------------------------+
|0 0 0|    CPR2:CPR     |  TCR  |            DLM:DLL            |
+-----+-----------------+-------+-------------------------------+

使用为 custom_divisor 字段编码的值,以及在通过 TIOCSSERIAL ioctl(2) 传递的 struct serial_structflags 字段中设置的 ASYNC_SPD_CUST 标志,例如使用 setserial(8) 工具及其 divisorspd_cust 参数,然后选择 38400bps 的波特率。请注意,TCR 中的值 0 会将过采样率设置为 16,而 CPR2/CPR 中小于 1 的分频器值将被驱动程序钳位为 1。

例如,值 0x1f4004e2 将分别把 CPR2/CPR、TCR 和 DLM/DLL 设置为 0x1f4、0x0 和 0x04e2,分别选择分频器值 62.500、过采样率 16 和时钟除数 1250。这些参数将把串口的波特率设置为 62500000 / 62.500 / 1250 / 16 = 50bps。

Maciej W. Rozycki <macro@orcam.me.uk>

[OX200]

“OXPCIe200 PCI Express 多端口桥接器”,牛津半导体公司,DS-0045,2008 年 11 月 10 日,“950 模式”部分,第 64-65 页

[OX952]

“OXPCIe952 PCI Express 双串口和并口桥接器”,牛津半导体公司,DS-0046,2008 年 3 月 6 日,“950 模式”部分,第 20 页

[OX954]

“OXPCIe954 PCI Express 四串口桥接器”,牛津半导体公司,DS-0047,2008 年 2 月,“950 模式”部分,第 20 页

[OX958]

“OXPCIe958 PCI Express 八串口桥接器”,牛津半导体公司,DS-0048,2008 年 2 月,“950 模式”部分,第 20 页