====== x86 EApi Windows ======
==== EApi Installation ====
Open the Windows command prompt as administrator and navigate to the folder that is containing the installation files.\\
Execute the file **install.batch** from the command prompt.\\
\\
**TqDriver** must be unistalled from the Device manager first, before reinstalling the software!
\\
==== EApi Initialisation ====
The ''EApiLibInitialize'' function has to be called at the beginning of every application.\\ An error will be returned if TQ driver is not installed on the system.\\
\\
The ''EApiLibUnInitialize'' function has to be called at the end of every application.
\\
==== EApi Board Information ====
== EApiBoardGetStringA ==
++++ Example |
> TqApp.exe EApiBoardGetStringA 0
Board Manufacturer Name = TQ-Group
| ''0'' | Board Manufacturer Name |
| ''1'' | Board Name |
| ''2'' | Board Revision |
| ''3'' | Serial Number |
| ''4'' | Board BIOS Revision |
| ''5'' | Board HW Revision |
| ''6'' | Platform ID |
++++
== EApiBoardGetValue ==
++++ Example |
> TqApp.exe EApiBoardGetValue 7
CPU Temperature = 30.5
| ''0'' | EAPI Specification Version |
| ''1'' | Boot Counter |
| ''2'' | Running Time Meter |
| ''3'' | Board vendor PNPID |
| ''4'' | Platform Specification Version |
| ''5'' | Vendor Specific Driver Version |
| ''6'' | Vendor Specific Library Version |
| ''7'' | CPU Temperature in °C |
| ''8'' | Chipset Temperature in °C |
| ''9'' | System Temperature in °C |
| ''10'' | CPU Core Voltage |
| ''11'' | 2.5V Voltage |
| ''12'' | 3.3V Voltage |
| ''13'' | Battery Voltage |
| ''14'' | 5V Voltage |
| ''15'' | 5V Standby Voltage |
| ''16'' | 12V Voltage |
| ''17'' | CPU Fan in RPM |
| ''18'' | System Fan in RPM |
++++
\\
==== Display Backlight ====
Backlight Functions are only available if a suitable display is connected.\\
Latest Intel(R) HD Graphics driver has be installed on the system.
| ''EApiVgaBacklightEnable'' | Enable Backlight |
| ''EApiVgaGetBacklightBrightness'' | Get Backlight Brightness Value (0-255) |
| ''EApiVgaSetBacklightBrightness'' | Set Backlight Brightness Value (0-255) |
\\
==== EEPROM ====
There are 2 available EEPROMs available on the TQ x86 Starterkits
* 0 - Module EEPROM (0xA0 address on I2C bus)
* 1 - Carrier EEPROM (0xAE address on I2C bus)
==EApiStorageCap==
* Supported. Functions returns Storage Size and Block Length value. It is needed to calculate write block alignment and size for EApiStorageAreaWrite function.
==EApiStorageAreaRead==
^ EApiStorageAreaRead ^ ID ^ Offset ^ Bytecnt ^
^ Datatype ^ dec ^ hex ^ dec ^
++++ Example: |
TqApp.exe EApiStorageAreaRead 0 0 32
EApiStorageAreaRead() successfully read data:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
0010 | 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................
++++
==EApiStorageAreaWrite==
* Function’s Offset and ByteCnt parameters must be a multiple of Block Length value that is returned by EApiStorageCap function.
^ EApiStorageAreaWrite ^ ID ^ Offset ^ Data ^
^ Datatype ^ dec ^ hex ^ hex .... hex ^
++++ Example: |
> EApiStorageAreaWrite 0 0x20 " 0 1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31"
> TqApp.exe EApiStorageAreaWrite 0 0x20 "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
++++
===== I2C =====
The current frequency is defined in Windows registry:
HKLM\SYSTEM\CurrentControlSet\Services\TqDrv\Parameters\I2cBusSpeed
Default Frequency is 100KHz, the following frequencies are available for the primary CPLD I2C Bus:
* 50KHz
* 100KHz
* 400KHz
After changing I2C frequency in Windows registry, you need to reset Tq driver in Windows Device Manager:
* Open Windows Device Manager and find System Devices/ TqDriver
* Right Click on TqDriver and choose "Disable", then reenable it
==EApiI2CWriteReadRawr==
^ EApiI2CWriteReadRaw ^ bus_id ^ i2c_addr ^ string_to_write ^ bytes_to_read ^
^ Datatype ^ dec ^ hex ^ hex ... hex ^ dec ^
To ignore write operation: = ""\\
To ignore read operation: = 0
++++ Example: |
Write 2 bytes: 0x00 0x00; Read 10 bytes
> TqApp.exe EApiI2CWriteReadRaw 0 AE "0 0" 10
EApiI2CWriteReadRaw() completed successfully
WriteData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 00 00 ..
ReadData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 00 01 02 03 04 05 06 07 08 09 ..........
Read 5 bytes:
> TqApp EApiI2CWriteReadRaw 0 AE "" 5
EApiI2CWriteReadRaw() completed successfully
ReadData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 0a 0b 0c 0d 0e .....
Write 6 bytes: 0x00 0x03 0x45 0xA7 0xB8 0x12
> TqApp.exe EApiI2CWriteReadRaw 0 AE "0 3 45 A7 B8 12" 0
EApiI2CWriteReadRaw() completed successfully
WriteData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 00 03 45 a7 b8 12 ..Eº+.
++++
==EApiI2CReadTransfer | EApiI2CWriteTransfer==
^ EApiI2CReadTransfer ^ bus_id ^ i2c_addr ^ cmd ^ type ^ bytes_to_read ^
^ EApiI2CWriteTransfer ^ bus_id ^ i2c_addr ^ cmd ^ type ^ bytes_to_write ^
^ Datatype ^ dec ^ hex ^ hex ^ hex ^ dec ^
where 'type' = 0/1/2 (No Command/ Standard Command/ Extended Command)
++++ Examples |
Read 12 bytes with No Command
> TqApp.exe EApiI2CReadTransfer 0 AE 0 0 12
EApiI2CReadTransfer() completed successfully
ReadData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 ............
Read 3 bytes with Extended Command = 0x10F3
> TqApp.exe EApiI2CReadTransfer 0 AE 1B2 2 3
EApiI2CReadTransfer() completed successfully
ReadData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | f3 f4 f5 =()
Write 1 byte 0x17 with No Command
> TqApp.exe EApiI2CWriteTransfer 0 AE 0 2 "A B C D E"
EApiI2CWriteTransfer(): completed successfully
WriteData:
| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----|-----------------------------------------------
0000 | 0a 0b 0c 0d 0e .....
++++
==== Watchdog Functions ====
==EApiWDogStart==
Delay mode is not supported. Event mode and Reset mode are supported.
++++ List of possible Watchdog timeout values |
* 0.125s
* 0.250s
* 0.500s
* 1s
* 2s
* 4s
* 8s
* 16s
* 32s
* 64s
* 128s
* 256s
* 512s
* 1024s
* 2048s
* 4096s
++++
If timeout falls between these values, the closest top value will be used: For Example:\\
For 10 seconds - 16 secnds will be used.\\
For 683 seconds - 1024 seconds will be used.
== Event Mode ==
Event timeout must be defined, other Timeout values must be 0.\\
2 interrupt lines are supported: 10 and 11.\\
Default line is 11.\\
Interrupt number must be defined in 2 places:
* Windows registry: HKLM\SYSTEM\CurrentControlSet\Services\TqDrv\Parameters\WdtInterrupt
* TQ driver resources in Device Manager
To change IRQ line you need to change it in 2 places. After that you need to reset Tq driver in Windows Device Manager:
* Open Windows Device Manager and find System Devices/ TqDriver
* Right Click on TqDriver and choose "Disable", then reenable it
== Reset mode ==
Reset timeout must be defined, other Timeout values must be 0.\\
Following reset modes are supported:\\
1 = watchdog reset output triggers hard reset signal\\
0 = watchdog reset output triggers power-on button\\
Reset mode is definded in Windows Registry, default value is 1.
HKLM\SYSTEM\CurrentControlSet\Services\TqDrv\Parameters\WdtReset
== Dual-Stage Mode ==
In dual-stage mode (Event + Reset) Event timeout will be used for both stages. Event timeout must be defined, reset timeout must not equal zero.\\
EApiWDogStart \\
Time must be specified in ms.\\
Example:
EApiWDogStart 0 15200 1000
==== GPIO ====
ON TQ Boards, 8 GPIO's are available, all of which can be input or output. The EApi library defines two different mechanisms to address GPIO: pin addressing and bank addressing. EAPI_GPIO_BANK_ID(GPIO_NUM) is used to define the GPIO bank.
== EApiGPIOGetDirection ==
EApiGPIOGetDirection uses bank addressing, where is a group of 32 pins addressed simultaneously.
Example:
> TqApp.exe EApiGPIOGetDirection 0
Bank 0: DIRECTION = 0xff
== EApiGPIOSetDirection ==
EApiGPIOSetDirection uses pin addressing. == 0 means Output, otherwise Input\\
Example:\\
Setting pin 2 to output
> TqApp.exe EApiGPIOSetDirection 2 0
== EApiGPIOSetLevel ==
EApiGPIOSetLevel uses bank addressing, where is a group of 32 pins addressed simultaneously.
Example:
> TqApp.exe EApiGPIOsetLevel 4 1
== EApiGPIOGetLevel ==
EApiGPIOGetLevel uses bank addressing, where is a group of 32 pins addressed simultaneously.
Example:
> TqApp.exe EApiGPIOGetLevel 0
Bank 0: LEVEL = 0xfb
==== TQ Library Functions ====
== TqWdtWaitForInterrupt ==
This function detects Watchdog interrupts, there is a standalone application for TqWdtWaitForInterrupt because it’s not part of EAPI.
++++ Examples |
CMD1:
> WdtWaitForInterrupt.exe
CMD2:
> TqApp.exe EApiWDogStart 0 10000 0
After 16 seconds CMD1 will output "Watchdog interrupt was caught"
++++
\\
\\
====== Linux version ======
==== Installation ====
First you have to unpack tqmx86-dist-0.1.tar.gz and deploy packages with dpkg, which is part of the dkms package.
$ sudo dpkg -i package-name.deb
Then install additional test and developer tools, drivers package and corresponding dependencies:
$ sudo apt-get i2c-tools lm-sensors
$ sudo apt-get install dkms linux-headers --> $(uname -r)
$ sudo dpkg -i tqmx86-drivers_0.1_amd64.deb
Now copy configs/sensors.tqmx to /etc/sensors.d/ and configs/tqmx86.conf to /lib/modules-load.d/ .\\
After that you have to edit the /etc/default/grub file by adding 'acpi_enforce_resources=lax' parameter to 'GRUB_CMDLINE_LINUX_DEFAULT', then reboot.\\
After the reboot check the output of "$ lsmod", the following Kernel Modules/ Drivers must have loaded automatically.
++++$ lsmod |
* tqmx86
* i2c-machxo2
* tqmx86_wdt
* gpio_tqmx86
* at24
* nct7802
* i2c-i801
++++
If any of these drivers have not been loaded automatically, load them manually with modprobe:
$ sudo modprobe
Lastly check config: these Device special- and sysfs files and directories must be present:
++++ config |
* /dev/watchdog
* /dev/watchdog0
* /sys/devices/platform/tqmx86/
* /sys/devices/platform/tqmx86/i2c-machxo2/
* /sys/devices/platform/tqmx86/tqmx86-wdt/
* /sys/devices/platform/tqmx86/tqmx86-gpio/
* /sys/devices/pci0000:00/0000:00:1f.3/i2c-X/X-002c/hwmon/hwmonY
* /sys/devices/platform/tqmx86/i2c-machxo2/i2c-Z/Z-0050/
('X', 'Y' and 'Z' variables depend on modules load order)
++++
==== Board and System Information ====
== Board Manufacturer ==
$ cat /sys/class/dmi/id/sys_vendor
TQ-Group
== Board Name ==
$ cat /sys/devices/platform/tqmx86/board_id
TQMxE38C
== Board Hardware Revision ==
$ cat /sys/devices/platform/tqmx86/board_version
1
== Board BIOS Revision ==
$ cat /sys/class/dmi/id/bios_version
TQMxE38C.5.4.48.0025.02
==== Watchdog ====
Source code for watchdog test program ('wdtest') is provided in "examples"
directory. To compile it, use the following command:
$ gcc wdtest.c -o wdtest
Intended usage of this program is to run as daemon and periodically ping watchdog. The following command pings watchdog every 20 seconds, this is short enough for the default timeout period of 32 seconds.
$ sudo sh -c
$ ./wdtest -p 20 &
The wdtest command can also print watchdog info and set timeout. The following sequence of commands will kill the running daemon, provide watchdog info and start a new daemon:
$ ps ax |grep wdtest
1686 pts/8 S 0:00
$ ./wdtest -p 20
$ sudo kill -9 1686 ;sudo
$ ./wdtest -i
$ sudo sh -c
$ ./wdtest -p 20 &
Options: 8080, Version: 0, Id: TQMx86 Watchdog
Status: 0
Timeout: 32
The process of changing the watchdog timeout is similar. Make sure the delay between 'kill' and 'start is short as to not allow the watchdog to reset the board.
$ ps ax |grep wdtest
1703 pts/8 S 0:00
$ ./wdtest -p 20
$ sudo kill -9 1703;
$ sudo ./wdtest -t 800
Timeout set to 1024sec
$ sudo sh -c
$ ./wdtest -p 500 &
Once the watchdog is first accessed it is started and cannot be stopped by any means, it can only be restarted by 'wdtest' or a similar watchdog daemon program. Alternatively simply write a charecter into /dev/watchdog (dev/watchdog0) file
==== GPIO ====
GPIO functionality can be tested with the gpio-test.sh shell script provided in the "examples" directory.\\
The program requires root priviliges to export a pin and to change the output value.
Pins 0-3 are hardwired as output only and pins 4-7 as input only. Their direction cannot be changed.
With a single pin argument the program reports pin status (direction and
value). When a second argument is provided it changes the state of the pin
accordingly:
$ sudo ./gpio-test.sh 2
Direction: out
Value: 0
$ sudo ./gpio-test.sh 5
Direction: in
Value: 1
$ sudo ./gpio-test.sh 2 1
$ ./gpio-test.sh 2
Direction: out
Value: 1
==== I2C ====
== Read module EEPROM ==
You can read "on-module" EEPROM at address 0x50 (* are variables in the file-path). You can also read/ write EEPROM as a regular file.
$ sudo hexdump -C /sys/devices/platform/tqmx86/i2c-machxo2/i2c-*/*-0050/eeprom
00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000010 54 51 4d 78 45 33 38 4d 0a ff ff ff ff ff ff ff |TQMxE38M........|
00000020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000002a0 ff a1 ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
000002b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001000
== Accessing PCA9538 GPIO Chip using i2c-tools ==
You can also access the GPIO chip PCA9538 using i2c-tools:\\
First you have to determine the number of the i2c-machxo2 bus.
++++ $ i2cdetect -1 |
$ i2cdetect -l
i2c-0 unknown i915 gmbus ssc N/A
i2c-1 unknown i915 gmbus vga N/A
i2c-2 unknown i915 gmbus panel N/A
i2c-3 unknown i915 gmbus dpc N/A
i2c-4 unknown i915 gmbus dpb N/A
i2c-5 unknown i915 gmbus dpd N/A
i2c-6 unknown DPDDC-B N/A
i2c-7 unknown DPDDC-C N/A
i2c-8 unknown i2c-machxo2 N/A
i2c-9 unknown SMBus I801 adapter at 3000 N/A
According to the output above, it's 8.
++++
Then read all 4 GPIO ports of PCA9538 located on this I2C bus:
++++ i2cdump |
$ sudo i2cdump -r 0-3 8 0x70
[part of the output skipped]
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 05 ff 00 ff
All pins are configured as input, pins 0 and 2 are pulled up to 3.3V.
++++
Now configure pins 0 - 3 as outputs:
$ sudo i2cset 8 0x70 3 0xf0
$ sudo i2cdump -r 0-3 8 0x70
00: 0f ff 00 f0
Lastly you have to change the output state for pins 0-1 (pins 4-7 are not affected as they are hardwired inputs).\\
Setting pin 0 to 0 output should turn on an LED.
$ sudo i2cset 8 0x70 1 0x06
$ sudo i2cdump -r 0-3 8 0x70
00: 06 06 00 f0
== Accessing EEPROM on carrier using i2c-rw program ==
Source code for i2c-rw test program is provided in the "examples" directory. Use the following command to compile it:
$ gcc i2c-rw.c -o i2c-rw
Examples:
++++ Read EEPROM at address 0x57 with offset 0 and size 64 |
$ sudo ./i2c-rw -s 8 0x57 0 0x40
Time: 6344 usec
0000: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................
0010: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................
0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
++++
++++
Read EEPROM at address 0x57 with offset 0xa00 and size 512 |
$ sudo ./i2c-rw -s 8 0x57 0xa00 0x200
Time: 47233 usec
0a00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
[skipped]
0af0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0b00: 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b ................
0b10: 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b ................
0b20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
[skipped]
0bf0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
++++
++++ Write "Hello!" to the same EEPROM at offset 0x30 |
$ echo -n "Hello!" |sudo ./i2c-rw -s -w 8 0x57 0x30
Time: 978 usec
$ sudo ./i2c-rw -s 8 0x57 0x20 0x20
Time: 3400 usec
0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
0030: 48 65 6c 6c 6f 21 ff ff ff ff ff ff ff ff ff ff Hello!..........
++++
==== HWMon Sensors ====
Standard linux '$ sensors' command can read NCT7802 and coretemp(MSR registers of
CPU) hardware monitor data:
$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Core 0: +30.0°C (high = +110.0°C, crit = +110.0°C)
Core 1: +30.0°C (high = +110.0°C, crit = +110.0°C)
Core 2: +31.0°C (high = +110.0°C, crit = +110.0°C)
Core 3: +31.0°C (high = +110.0°C, crit = +110.0°C)
soc_dts0-virtual-0
Adapter: Virtual device
temp1: +29.0°C
soc_dts1-virtual-0
Adapter: Virtual device
temp1: +30.0°C
nct7802-i2c-9-2c
Adapter: SMBus I801 adapter at 3000
3V3: +3.37 V (min = +0.00 V, max = +4.09 V)
RTC-bat: +3.02 V
5VSB: +5.08 V (min = +0.00 V, max = +6.24 V)
COMe-input: +12.38 V (min = +0.00 V, max = +21.99 V)
CPU-fan: 0 RPM (min = 0 RPM)
COMe-fan: 3936 RPM (min = 0 RPM)
CPU-temp: +30.2°C (low = +0.0°C, high = +85.0°C)
(crit = +100.0°C)
SYS-temp: +30.0°C (low = +0.0°C, high = +85.0°C)
(crit = +100.0°C)
====== Known Issues ======
==== Windows ====
* I2C EEPROM may be unstable if I2C bus speed is set to 400KHz. Recommended I2C bus speed is 100KHz.
* EEPROM access is unstable, e.g. when some data is written to I2C EERPOM it may get written to wrong offset. Usually it happens after large number (thousands) of successive write operations to the EEPROM, or while reading EEPROM in big chunks. Most likely it is a h/w issue of particular model of EEPROM.
==== Linux ====
* Due to BIOS incompatibility ACPI SMBus driver (i2c-scmi) does not work and legacy i801 SMBus driver reports "resource conflict". To resolve the issue "acpi_enforce_resources=lax" needs to be added to the kernel command line.
* Setting I2C bus speed is possible only on driver startup. Default speed is 100KHz. If 50 or 400KHz is desired, specify that in driver parameters: $ sudo modprobe tqmx86 i2c_speed=50 | This parameter may be also added to a file in /lib/modprobe.d/ as: install tqmx86 i2c_speed=50
* The I2C driver is designed to work in interrupt mode on boards that support configuring the IRQ number in PLD. The IRQ number can be specified in tqmx86 driver parameters as "i2c_irq=7" (i2c_irq=0 selects polling mode). However, this was not tested and is not guaranteed to work.
* I2C driver operation in 'poll' mode at 400KHz speed is sometimes unstable.