Spoofing Baud Rates for USB232 and USB485i

Introduction

Many Windows applications offer only a limited set of baud rates. The Windows drivers for the USB232 and USB485i (and also for the new USB232U and USB485Ui) allow some standard baud rates to be remapped to different custom baud rates. When the application uses one of the standard baud rates that has been remapped, the driver will generate the corresponding custom baud rate instead. This may be accomplished either by modifying the FTDIPORT.INF file prior to installing the driver, or by modifying a registry entry for the device after installing the driver. The first method will apply the baud rate remapping to all devices installed using the modified INF file. The second method will apply the baud rate remapping to a specific installed device (and will apply even if that device is moved to a different USB port on the PC).

Baud Rates Supported by the Driver

See Supported Baud Rates for USB232 and USB485i. These baud rates are supported using 2-byte divisor codes, which the driver uses by default in its baud rate remapping list.

See Supported Baud Rates for USB232U and USB485Ui for the baud rates supported by these newer devices using the current Windows driver. To remap to the extra baud rates (those supported by the USB232U and USB485Ui, but not by the USB232 and USB485i), 4-byte divisor codes must be used in the baud rate remapping list.

Remappable Baud Rates

The following table lists the baud rates that may be remapped in the order that they appear in the baud rate remapping list, along with the standard 'divisor' and corresponding 2-byte divisor codes. The actual baud rate generated is 3000000 / divisor. The divisor codes are presented as two hex bytes in little-endian order as they appear in the unmodified FTDIPORT.INF file. The table also shows the byte offset of each entry within the ConfigData registry value (in the registry or in the FTDIPORT.INF file) for both 2-byte and 4-byte divisor values (do not worry about this yet):

Table 1: Baud Rate Remapping List
Index Offset
[2-byte]
Offset
[4-byte]
Baud
Requested
Standard
Divisor
Standard
Divisor Code
0 4 (04h) 4 (04h) 300 10000 10,27
1 6 (06h) 8 (08h) 600 5000 88,13
2 8 (08h) 12 (0Ch) 1200 2500 C4,09
3 10 (0Ah) 16 (10h) 2400 1250 E2,04
4 12 (0Ch) 20 (14h) 4800 625 71,02
5 14 (0Eh) 24 (18h) 9600 312.5 38,41
6 16 (10h) 28 (1Ch) 19200 156.25 9C,80
7 18 (12h) 32 (20h) 38400 78.125 4E,C0
8 20 (14h) 36 (24h) 57600 52 34,00
9 22 (16h) 40 (28h) 115200 26 1A,00
10 24 (18h) 44 (2Ch) 230400 13 0D,00
11 26 (1Ah) 48 (30h) 460800 6.5 06,40
12 28 (1Ch) 52 (34h) 921600 3.25 03,80
13 30 (1Eh) 56 (38h) RESERVED 00,00
14 32 (20h) 60 (3Ch) 14400 208.25 D0,80

Determining the Divisor

The divisor for a desired baud rate is determined from the following formula:

Divisor = 3000000 / Baud

Divisor Restrictions

  1. The divisor is restricted to the following range:

    1 <= divisor < 16384

  2. For a 2-byte divisor code, the fractional part of the divisor is limited to the following values:

    0, 0.125, 0.25, 0.5.

  3. For a 4-byte divisor code, the fractional part of the divisor is limited to the following values:

    0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875.

  4. The latest digitally signed drivers support 2-byte divisor codes and 4-byte divisor codes. The older digitally signed drivers (signed on July 22, 2002) only support 2-byte divisor codes.

  5. The older USB232 and USB485i (based on the FT8U232AM USB UART) only supports divisors that can be encoded using a 2-byte divisor code.

  6. The following divisor values do not work:

    1.125, 1.25, 1.375, 1.625, 1.75, 1.875

  7. The following divisor value does not work on the older USB232 and USB485 (based on the FT8U232AM USB UART):

    1.5

Choosing a Divisor

The baud rate actually generated using a valid divisor is determined by the formula:

Baud = 3000000 / Divisor

There may be a choice of two valid divisor values, generating baud rates on either side of the desired baud rate. In this case, it is best to use the divisor value that generates the baud rate closest to the desired baud rate.

For interoperability with other equipment, the generated baud rate must be within 5% of the desired baud rate, preferably closer.

Determining the Divisor Code

Here is an outline of the steps required to convert a valid divisor into a divisor code:

  1. Determine a "fraction code" from the fractional part of the divisor.
  2. Add the "fraction code" to the integral part of the divisor.
  3. Consider special cases.
  4. Convert to hexadecimal.
  5. Pad to a 2-byte or 4-byte divisor code.
  6. Arrange the bytes of the divisor code in little-endian order.

In full:

  1. Determine the fraction code from the fractional part of the divisor from the following table:

    Table 2: Fraction Codes
    Fractional
    Part
    Fraction Code
    (Decimal) (Hex)
    0 0 0h
    0.125 49152 C000h
    0.25 32768 8000h
    0.375 65536 10000h
    0.5 16384 4000h
    0.625 81920 14000h
    0.75 98304 18000h
    0.875 114688 1C000h

    Note that the only fractions that can be represented using a 2-byte divisor code are 0, 0.125, 0.25 and 0.5.

  2. Add the fraction code to the integral part of the divisor.

  3. For a couple of special case divisors, the following divisor codes should be used instead of that determined from steps 1 and 2:

    Table 3: Special Case Divisor Codes
    Divisor New Divisor Code
    (Decimal) (Hex)
    1 0 0h
    1.5 1 1h

    Note that the older USB232 and USB485i (based on the FT8U232AM USB UART) do not support a divisor value of 1.5, but the newer USB232U and USB485Ui (based on the FT232BM USB UART) do support it. This corresponds to a baud rate of 2000000.

  4. Convert the decimal divisor code to hexadecimal. (Ask a programmer, borrow their calculator or use the Windows calculator accessory in "Scientific" mode.)

  5. For a 2-byte divisor code, pad the hexadecimal number to exactly 4 digits by adding zero or more '0' digits to the left hand side (this is impossible if the fractional part of the divisor is 0.375,0.625, 0.75 or 0.875).

    For a 4-byte divisor code, pad the hexadecimal number to exactly 8 digits by adding three or more '0' digits to the left hand side.

  6. Starting from the left, split the 4-digit (2-byte) or 8-digit (4-byte) hexadecimal value into digit pairs. Each pair of digits forms a single byte value. Reverse the order of the bytes so that they are listed in little-endian order. For example, the hexadecimal divisor code 1234h (4660 in decimal) would end up as the following sequence of bytes in little-endian order: 34,12.

Example: 1250000 Baud

To generate 1250000 baud exactly would require a divisor value of 2.4. This divisor value is not supported so this baud rate cannot be generated exactly. However, it is possible to generate baud rates reasonably close to 1250000 baud.

Using 2-byte divisor codes, the closest valid divisor values on either side of 2.4 are 2.25 and 2.5. Using 4-byte divisor codes, the closest valid divisor values are 2.375 and 2.5. These three divisor values generate the following baud rates:

Table 4: Example Baud Rate Generation
Divisor Generated Baud Error
2.25 1333333 +6.67%
2.375 1263158 +1.05%
2.5 1200000 -4.00%

The divisor value of 2.25 can be rejected immediately as the error is too large. The baud rates generated by either of the divisor values 2.375 and 2.5 should be compatible with equipment operating at 1250000 baud. Of these, the divisor value of 2.375 generates the baud rate closest to that required, but this is not supported on the older USB232 and USB485i devices (based on the FT8U232AM USB UART) and is not supported by the old drivers (from July 22, 2002) as it requires the use of 4-byte divisor codes in the baud rate remapping list.

To convert a divisor value of 2.5 to a 2-byte divisor code as a sequence of bytes in little-endian order:

  1. Determine the fraction code:

    0.5 --> 16384

  2. Add fraction code to decimal part of divisor:

    2 + 16384 --> 16386

  3. Consider special cases:

    Not applicable.

  4. Convert to hexadecimal:

    16386 --> 4002h

  5. Pad to a 2-byte divisor code:

    4002h --> 4002h

  6. Arrange bytes in little-endian order:

    4002h --> 02,40

To convert a divisor value of 2.375 to a 4-byte divisor code as a sequence of bytes in little-endian order:

  1. Determine the fraction code:

    0.375 --> 65536

  2. Add fraction code to decimal part of divisor:

    2 + 65536 --> 65538

  3. Consider special cases:

    Not applicable.

  4. Convert to hexadecimal:

    65538 --> 10002h

  5. Pad to a 4-byte divisor code:

    10002h --> 00010002h

  6. Arrange bytes in little-endian order:

    00010002h --> 02,00,01,00

Modifying the FTDIPORT.INF File

The FTDIPORT.INF file may be modified prior to driver installation to alter the baud rate remapping list for devices subsequently installed using the file. The alternative is to modify the registry settings for a particular device after it has been installed.

If the driver has already been installed, it should be uninstalled using the FTDIUINI.EXE program prior to modification and then the devices may be installed again using the modified version of the file.

Note that any modification to the FTDIPORT.INF file will render its digital signature invalid, if it has one. This may result in a warning about unsigned drivers being displayed during subsequent device installation, or may prevent device driver installation altogether if that is the system policy.

There are two places in the FTDIPORT.INF file where the baud rate remapping list is set. One of these places is for Windows 98 / ME and looks like this:

[FtdiPort232.HW.AddReg]
HKR,,ConfigData,1,01,00,3F,3F,10,27,88,13,C4,09,\
E2,04,71,02,38,41,9c,80,4E,C0,34,00,1A,00,0D,00,\
06,40,03,80,00,00,d0,80

(Note that the backslash (\) line-continuation character has been added to the above INF file extract and to the following extracts for presentation purposes, and are not part of the original file.)

(The first byte of the ConfigData value is 01 in the above, but in some "beta" versions of the file, this byte is 09 instead. In the latest version, this has been changed back to 01.)

The other place is for Windows 2000 / XP and looks similar to the above:

[FtdiPort232.NT.HW.AddReg]
HKR,,"UpperFilters",0x00010000,"serenum"
HKR,,"ConfigData",1,01,00,3F,3F,10,27,88,13,C4,09,\
E2,04,71,02,38,41,9c,80,4E,C0,34,00,1A,00,0D,00,\
06,40,03,80,00,00,d0,80

In each case, the ConfigData line holds the baud rate remapping list, amongst other things. The baud rate remapping list begins with the byte at offset 4 and uses 2-byte divisor codes (beginning with "10,27") in the standard version.

It is advisable to copy and paste the original ConfigData line, comment out the original line with a semicolon and edit the new version of the line. It is also advisable to change both ConfigData lines (for Windows 98 / ME and Windows 2000 / XP) in the same way.

Substituting one 2-byte divisor code for another is straightforward. Refer to Table 1 for the byte offset within the ConfigData value to make the change. For example, to generate 1200000 baud (divisor code "02,40") when 14400 is specified, change the bytes at offset 32 from "d0,80" to "02,40".

To use 4-byte divisor codes, the existing 2-byte format ConfigData line needs to be modified to 4-byte format as follows:

  1. Set bit 4 of the first byte to "1" to indicate that the following baud rate remapping list uses 4-byte divisor codes. For example, the first byte should be changed to "11" if it was previously set to "01".
  2. Append ",00,00" to each 2-byte divisor code to turn it into the corresponding 4-byte divisor code.

Here is a version of the ConfigData line using 4-byte divisor codes:

HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,\
88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,\
38,41,00,00,9c,80,00,00,4E,C0,00,00,34,00,00,00,\
1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,\
00,00,00,00,d0,80,00,00

It is now straightforward to substitute one 4-byte divisor code with another. For example, to generate 1263158 baud (divisor code "02,00,01,00") when 14400 is specified, change the bytes at offset 60 from "d0,80,00,00" to "02,00,01,00".

Note that 4-byte divisor codes may only be used with the later versions of the driver and that the extra baud rates that can be specified using 4-byte divisor codes only work on the newer USB232U and USB485Ui devices, based on the FT232BM USB UART.

Modifying the Registry

The registry settings for an installed device may be modified after driver installation to alter the baud rate remapping list for that device. The alternative is to modify the FTDIPORT.INF file prior to driver installation.

For Windows 2000 and Windows XP, the logged-in user needs to be in the Administrators group to change the registry settings.

Run REGEDIT. For Windows 98 and Windows ME, open the following registry key:

HKEY_LOCAL_MACHINE/ Enum/ FTDIBUS/ VID_0403+PID_6001+MV??????A/ 0000

For Windows 2000 and Windows XP, open the following registry key:

HKEY_LOCAL_MACHINE/ SYSTEM/ CurrentControlSet/ Enum/ FTDIBUS/ VID_0403+PID_6001+MV??????A/ 0000/ Device Parameters

The portion marked ?????? in the above registry keys is a unique serial number for the device. If several devices have been installed, there will be a registry key for each one. The PortName registry value contains the COM-port number for the device and may be used to distinguish it from other devices.

Once the correct registry key has been found, the baud rate remapping list may be changed by editing the ConfigData registry value. This is a binary registry value (REG_BINARY). When double-clicked within REGEDIT, a hex editor is opened to allow the value to be modified.

The baud rate remapping list starts at offset 4 within the ConfigData value. If bit 4 of the first byte is 0 (if the first hex digit of the first byte is even), the baud rate remapping list contains 2-byte divisor codes. If bit 4 of the first byte is 1 (if the first hex digit of the first byte is odd), the baud rate remapping list contains 4-byte divisor codes.

If the baud rate remapping list currently contains 2-byte divisor codes and it is desired to use 4-byte divisor codes, the registry value may be converted to use 4-byte divisor codes by setting bit 4 of the first byte to 1 and appending "00 00" after each 2-byte divisor code. For example, if the ConfigData registry value contains the following before conversion:

0000  01 00 3F 3F 10 27 88 13
0008  C4 09 E2 04 71 02 38 41
0010  9C 80 4E C0 34 00 1A 00
0018  0D 00 06 40 03 80 00 00
0020  D0 80

it should contain the following after conversion to use 4-byte divisor codes:

0000  11 00 3F 3F 10 27 00 00
0008  88 13 00 00 C4 09 00 00
0010  E2 04 00 00 71 02 00 00
0018  38 41 00 00 9C 80 00 00
0020  4E C0 00 00 34 00 00 00
0028  1A 00 00 00 0D 00 00 00
0030  06 40 00 00 03 80 00 00
0038  00 00 00 00 D0 80 00 00
0040

Note that the hex editor used to modify the registry value operates in insert mode, so changing a byte involves inserting a new byte and deleting the old one.

It is straightforward to substitute one 2-byte divisor code with another, or to substitute one 4-byte divisor code with another. Refer to Table 1 to find the byte offset of the entry to be changed (use the hexadecimal offsets shown in parentheses), insert the new divisor code at the correct position (depending on the index within the baud rate remapping list and the format of the divisor codes) and delete the old one. To replace a 4-byte divisor code with a 2-byte divisor code, first convert the 2-byte divisor code to a 4-byte divisor code first by appending "00 00".

Note that 4-byte divisor codes may only be used with the later versions of the driver and that the extra baud rates that can be specified using 4-byte divisor codes only work on the newer USB232U and USB485Ui devices, based on the FT232BM USB UART.

The baud rate remapping list change will take effect the next time the device is connected.

Bugs

Version 1.00.2115 of the unsigned Windows 2000 / XP driver (and possibly some earlier versions) have a bug in the Advanced Settings dialog (accessible via the Advanced button on the Port Settings property sheet for the device in Device Manager. The bug causes bit 4 of the first byte to be set to 0 when the OK button or the Return key is used to accept new settings. This will cause the baud rate remapping list to misbehave if 4-byte divisor codes are used. This can be corrected by editing the ConfigData registry value for the device using REGEDIT. (See Modifying the Registry for the location of the ConfigData registry value.) The Windows 98 / ME driver does not have this bug. The problem may be prevented by only using 2-byte divisor codes or by installing the latest drivers.