TS-4900 FPGA Functionality
The Lattice ICE40 FPGA provides auto TX enable for RS-485 half duplex, a few more DIO, the UART MUX, and it can generate clocks for use on a baseboard. Most of these registers are controlled using tshwctl in the ts4900-utils repository. The DIO can be accessed using the sysfs GPIOs 224 to 255 using the "ts4900gpio" driver. See the #GPIO section for more information on the recommended GPIO access. The below examples will communicate directly over i2c.
Usage: tshwctl [OPTIONS] ... Technologic Systems TS-4900 Utility -p, --getin <dio> Returns the input value of an FPGA DIO -e, --setout <dio> Sets an FPGA DIO output value high -l, --clrout <dio> Sets an FPGA DIO output value low -d, --ddrout <dio> Set FPGA DIO to an output -r, --ddrin <dio> Set FPGA DIO to an input -f, --bten <1|0> Switches ttymxc2 to bluetooth -n, --bbclk12 <1|0> Adds a 12MHz CLK on CN1_87 -o, --bbclk14 <1|0> Adds a 14.3MHz CLK on CN1_87 -u, --uart2en <1|0> Switches ttymxc1 to cn2-78/80 -a, --uart4en <1|0> Muxes ttymxc3 to cn2_86/88 -s, --pushsw Returns the value of the push switch -h, --help This message
On every poweron the FPGA is programmed using the file in /boot/ts4900-fpga.bin. U-boot copies this into memory, and runs the "ice40" command to reprogram the FPGA. Without this file the FPGA will not do anything. This FPGA interfaces to the i.MX6 using the first CPU I2C bus. The userspace i2c commands can be used to manipulate these registers as well:
# Read 0x1f(31) Push SW
i2cget -y 0 0x28 0x1f w
# Set CN1_63 as a high output
i2cset -y 0 0x28 0x0 0x1 w
Note: | The I2C bus can change depending on the baseboard. See the ts4900-utils code for an example of autodetecting this to work on multiple baseboards, but the I2C bus will not change between boots on the same baseboard. |
For custom boards, the "ts4900gpio" device tree platform data can be used to enable certain clocks and uarts by default. See the TS-8150 device tree for an example.
Addr | Bits | Function |
---|---|---|
00 | 0 | CN1_63 Output Enable |
1 | CN1_63 Output Data | |
2 | CN1_63 Input Data | |
01 | 0 | CN1_67 Output Enable |
1 | CN1_67 Output Data | |
2 | CN1_67 Input Data | |
02 | 0 | CN1_87 Output Enable |
1 | CN1_87 Output Data | |
2 | CN1_87 Input Data | |
03 | 0 | mux_ad_15 Output Enable |
1 | mux_ad_15 Output Data | |
2 | mux_ad_15 Input Data | |
04 | 0 | CN2_54 Output Enable |
1 | CN2_54 Output Data | |
2 | CN2_54 Input Data | |
05 | 0 | CN2_78 Output Enable |
1 | CN2_78 Output Data | |
2 | CN2_78 Input Data | |
06 | 0 | CN2_80 Output Enable |
1 | CN2_80 Output Data | |
2 | CN2_80 Input Data | |
07 | 0 | CN2_86 Output Enable |
1 | CN2_86 Output Data | |
2 | CN2_86 Input Data | |
08 | 0 | CN2_88 Output Enable |
1 | CN2_88 Output Data | |
2 | CN2_88 Input Data | |
09 | 0 | CN2_94 Output Enable |
1 | CN2_94 Output Data | |
2 | CN2_94 Input Data | |
10 | 0 | CN2_96 Output Enable |
1 | CN2_96 Output Data | |
2 | CN2_96 Input Data | |
11 | 0 | CN2_98 Output Enable |
1 | CN2_98 Output Data | |
2 | CN2_98 Input Data | |
12 | 0 | CN2_100 Output Enable |
1 | CN2_100 Output Data | |
2 | CN2_100 Input Data | |
13 | 0 | BT_EN Output Enable |
14 | 0 | WL_EN Output Enable |
31 | 0 | Push switch Input Data |
32 | 7:0 | RS485_CNT0 bits 23:16 |
33 | 7:0 | RS485_CNT0 bits 15:8 |
34 | 7:0 | RS485_CNT0 bits 7:0 |
35 | 7:0 | RS485_CNT1 bits 23:16 |
36 | 7:0 | RS485_CNT1 bits 15:8 |
37 | 7:0 | RS485_CNT1 bits 7:0 |
38 | 7:0 | RS485_CNT2 bits 23:16 |
39 | 7:0 | RS485_CNT2 bits 15:8 |
40 | 7:0 | RS485_CNT2 bits 7:0 |
41 | 7:0 | RS485_CNT3 bits 23:16 |
42 | 7:0 | RS485_CNT3 bits 15:8 |
43 | 7:0 | RS485_CNT3 bits 7:0 |
44 | 0 | Auto-485 EN0 |
45 | 0 | Auto-485 EN1 |
46 | 0 | UART to Bluetooth [1] |
47 | 0 | Enable 12MHz on CN1_87 [2] |
48 | 0 | Enable 14.3MHz on CN1_87 [3] |
49 | 0 | UART2_EN |
50 | 0 | UART4_EN |
51 | 8:0 | Build strap values |
52 | 0 | Multiply CN1_87 clock x2 |
The FPGA crossbar allows almost any of the FPGA pins to be rerouted on the carrier board. All of the above registers that have a crossbar mux value can be written with these values to change the output value. When using the crossbar pins that are outputs, bit 1 should also be set to allow output enables.
Crossbar Value | Selected Function |
---|---|
0 | Do not change |
1 | BT_RTS |
2 | BT_TXD |
3 | CN1_63 |
4 | CN1_67 |
5 | CN2_100 |
6 | ttymxc1 RTS# |
7 | CN2_78 |
8 | CN2_80 |
9 | CN2_86 |
10 | CN2_88 |
11 | CN2_94 |
12 | CN2_96 |
13 | CN2_98 |
14 | ttymxc3 TXD |
15 | ttymxc1 TXD |
16 | SPIUART0_TX |
17 | SPIUART0_TXEN |
18 | SPIUART0_RTS |
19 | SPIUART1_TX |
20 | SPIUART1_TXEN |
21 | SPIUART1_RTS |
22 | SPIUART2_TX |
23 | SPIUART2_TXEN |
24 | SPIUART2_RTS |
25 | ttymxc1 TXEN |
26 | ttymxc3 TXEN |
27 | 12MHz clock |
28 | 14MHz clock |
29 | 24MHz clock |
30 | 28.88MHz clock |
31 | GPIO |
On startup these are the default values:
Pad | Default Mapping | FGPA Addr | Crossbar Reset Value |
---|---|---|---|
CN1_63 | SPIUART1_TXEN | 0 | 0xa1 |
CN1_67 | SPIUART0_TXEN | 1 | 0x89 |
CN1_87 | GPIO 226 | 2 | 0xf8 |
UART4_RXD | CN2_88 | 3 | 0x80 |
ttymxc1 CTS | BT_RTS | 4 | 0x8 |
CN2_78 | SPIUART0_TXD | 5 | 0x81 |
CN2_80 | GPIO [1] | 6 | 0xf8 |
CN2_86 | UART4_TXD | 7 | 0x71 |
CN2_88 | GPIO [2] | 8 | 0xf8 |
CN2_94 | SPIUART1_TXD | 9 | 0x99 |
CN2_96 | GPIO | 10 | 0xf8 |
CN2_98 | SPIUART2_TXD | 11 | 0xb1 |
CN2_100 | GPIO [3] | 12 | 0xf8 |
BT_CTS | ttymxc1 RTS | 16 | 0x31 |
BT_RXD | ttymxc1 TXD | 17 | 0x78 |
ttymxc1 RXD | BT_TXD | 18 | 0x10 |
SPIUART0 RX | CN2_80 | 44 | 0x40 |
SPIUART1 RX | CN2_96 | 45 | 0x60 |
SPIUART2 RX | CN2_100 | 46 | 0x28 |
SPIUART0 CTS | GPIO [4] | 53 | 0xf8 |
SPIUART1 CTS | GPIO [5] | 54 | 0xf8 |
SPIUART2 CTS | GPIO [6] | 55 | 0xf8 |