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

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

波特率发生器产生的波特率是通过将此输入频率除以时钟预分频器得到的,时钟预分频器可以设置为 1 到 63.875 之间的任何值(以 0.125 为增量),然后像原始 8250 一样使用通常的 16 位除数,将频率除以 1 到 65535 之间的值。最后,使用可编程的过采样率,它可以取 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 一样。此外,为了与为旧式传统 PCI 牛津半导体设备编写的旧软件兼容,向 CPR 写入任何值都会清除 CPR2,这些设备在 CPR2 中没有额外的预分频器的第 9 位,因此必须按正确的顺序编程 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 位范围。如果需要,仍然可以使用历史 spd_cust 功能,方法是将预分频器、过采样率和时钟除数 (DLM/DLL) 的值编码如下,以获得这样的速率

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

将此类编码的值用于 custom_divisor 字段,以及在通过 TIOCSSERIAL ioctl(2) 传递的 struct serial_struct 中的 flags 字段中设置的 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 Multi-Port Bridge”,牛津半导体公司,DS-0045,2008 年 11 月 10 日,“950 模式”部分,第 64-65 页

[OX952]

“OXPCIe952 PCI Express Bridge to Dual Serial & Parallel Port”,牛津半导体公司,DS-0046,2008 年 3 月 6 日,“950 模式”部分,第 20 页

[OX954]

“OXPCIe954 PCI Express Bridge to Quad Serial Port”,牛津半导体公司,DS-0047,2008 年 2 月,“950 模式”部分,第 20 页

[OX958]

“OXPCIe958 PCI Express Bridge to Octal Serial Port”,牛津半导体公司,DS-0048,2008 年 2 月,“950 模式”部分,第 20 页