Problems with I2C on ArmHF | LabJack
 

Problems with I2C on ArmHF

10 posts / 0 new
Last post
Einar Jón
einarjon's picture
Problems with I2C on ArmHF

I have been trying to run a LabJack T7 with Linux ARMv7 (Angstrom).
I'm having constant problems with the I2C. 

On an i386 machine I can read and write I2C without issues - using labjack_ljm_software_2017_05_02_i386.tar.gz.
On an AM335 (same as the BeagleBone) the I2C_ACK always returns zero, and the values are not read/written.
I have tried versions LabJackM-1.1406-Angstrom-Linux-ARMv7.tar.gz and LabJackM-1.1500-Angstrom-Linux-ARMv7.tar.gz

Running lj.py 127 on i386:

Opened a LabJack with Device type: 7, Connection type: 1,
Max bytes per MB: 64
Writing User Memory [0] = 127
Write acks is 3
Read User Memory [0] = 127
Read acks is 1

Running lj.py 34 on AM355:

Opened a LabJack with Device type: 7, Connection type: 3,
Max bytes per MB: 1040
Writing User Memory [0] = 34
Write acks is 0
Read User Memory [0] = 200
Read acks is 0

File Attachment: 
LabJack Support
labjack support's picture
I was not able to get your

was not able to get your example script to read the same value as was written. Python_LJM/Examples/I2C/i2c_eeprom.py example worked for me on BeagleBoard, but that requires an LJTick-DAC, so I'll get someone more familiar with I2C to look at your example.

Einar Jón
einarjon's picture
I guess that depends on the

I guess that depends on the setup.
My example is just i2c_eeprom.py modified for a single register and new SDA/SCL pin numbers + taking the value from the command line.

But after investigating a bit deeper, the TCP packets sent to the LabJack (modbus) are actually different. Attached are "identical" pcap binary dumps from an i386 (actually working) and the ARM (which does not work). Load them up side-by-side in Wireshark and look inside the Modbus packets:

The shorter commands are all identical, but the I2C commands contain different data. Example from packet 18 in both pcap files:
I386 transmission: write(5100, LJM_UINT16, 17): inside the 76 function: 0113ec010011
ARM transmission: write(5100, LJM_UINT16, 17): inside the 76 function: 0113ec010000

This happens on every I2C packet write on ARM - all writes are 0.
See also packets 21,23,25,etc... in both Pcap files
.
C++/python code sends these 0-value writes, and USB transmissions behave the same, so I think this is a bug in the library. 

HW specs: Arm AM335 cpu (same as BeagleBone), Kernel 3.14.26.
Using libLabJackM.so.1.15.0 from LabJackM-1.1500-Angstrom-Linux-ARMv7.tar.gz

LabJack Support
labjack support's picture
I wasn't able to reproduce

I wasn't able to reproduce the issue on a BeagleBoard with kernel 2.6.32, but I will acquire a BeagleBone and try with that. I will update this thread when I've done so.

Are you able to reproduce this error on USB, or does it only occur via Ethernet? Note that you can get output of the LJM USB packets via the method described here:

https://labjack.com/support/software/api/ljm/function-reference/debugging-functions

Einar Jón
einarjon's picture
The problem is pretty

The problem is pretty consistent on our kernel 3.14.26. The values are just set to 0 before transmitting to the LabJack.
Logfiles given a *.h extension to bypass your stupid filters.

i added the following to top of the python script and re-ran it, both on USB and serial.
ljm.writeLibraryConfigS("LJM_DEBUG_LOG_MODE", 2)
ljm.writeLibraryConfigStringS("LJM_DEBUG_LOG_FILE", "/tmp/py.log")

Also added a tcp log from i386 (no issues there) and some arm C++ code (slightly different commands, but same issue).
The logs also show some issues with your MAC address fields in the ljm_constants.json (UINT64), and the LJM version number is messed up.

Should I be trying the Raspberry library instead?

LabJack Support
labjack support's picture
Good point about the filters.

Good point about the filters. I've added .log as an allowable file extension now, at least.

The UINT64 errors are expected. I've never seen the LJM version number being messed up like that, though. My BeagleBone should arrive today or tomorrow, but in the meantime:

1. What is the output of `uname -a`? Please try installing LabJackM-1.1500-Raspbian-Linux-armhf.tar.gz.

2. Try re-installing or installing older versions, if you haven't already.

3. What happens in the log if you use LJM_WriteRaw? For example, in C:

	const unsigned char rawBytes[14] = {
		0x12, 0x34,
		0x00, 0x00,
		0x00, 0x08,
		0x01, 0x4C,
		0x01, 0x13, 0xEC, 0x01, 0x00, 0x11
	};
	err = LJM_WriteRaw(handle, rawBytes, 14);
	ErrorCheck(err, "LJM_WriteRaw");

You shouldn't have to use LJM_WriteRaw even if it's the only thing that works—it sounds like something is more deeply wrong.

4. If you have another BeagleBone, please try to replicate the issue on it.

In regards to Raspberry Pi, we have tested LJM on Pis more thoroughly, but I do hope to get LJM working for you on your BeagleBone.

Einar Jón
einarjon's picture
Hi again.

Hi again.

We have 2 ARM AM335 machines that have the same issue. the Raspberry library is better, but still does not work 100%.
If the library is called with python, the first write after a LabJack reboot usually fails (value unchanged and 0 in the ack result), but subsequent reads and writes work. 
If the library is called from C++, the values at least get written correctly in the LabJack log, but the acks are always 0. The writes do nothing and the read result is always 0xFF (in the other library the read buffer in untouched). 

I tried  a basic readRaw like so: 

    unsigned char rawBytesRx[100];
    const unsigned char rawBytesTx[14] = {
        uint8_t(transId >> 8), uint8_t(transId),
        0x00, 0x00,
        0x00, 0x08,
        0x01, 0x4C,
        0x01, uint8_t(addr >> 8), uint8_t(addr), 0x01, uint8_t(value>>8), uint8_t(value)    };
    err = LJM_WriteRaw(ljm_handle, rawBytesTx, 14);
    err = LJM_ReadRaw(ljm_handle, rawBytesRx, 8);

But it is not enough. The values do get sent (written to the LabJack log), but the the ack is always 0. Tested on Angstrom 1406, 1500 and raspberry 1500. 

Enclosed are more logs:
It looks like the commands LJM_eReadAddressArray/LJM_eWriteAddressArray don't send anything in C programs on the Angstrom - which would explain why the read buffer is untouched. I tried to use LJM_eWriteAddress(h, addr, LJM_UINT16, int(buffer[0])<<8) instead of LJM_eWriteAddressArray in the log raw_Angstrom1500_manual.log_.h, and then the commands get sent. But still the ack is 0 and nothing happens on the I2C bus.

Naming:
normal -> Uses normal  LJM_eWriteAddress, calls LJM_eWriteAddressArray.
raw -> uses  LJM_WriteRaw instead of LJM_eWriteAddress, calls LJM_eWriteAddressArray
raw_*_manual ->uses  LJM_WriteRaw, uses LJM_eWriteAddress (...., double(rawBuffer[0]<<8)) instead of LJM_eWriteAddressArray 
py* -> uses python. The first run of python Raspberry fails on write, but read works (py1_*). Any subsequent reads/writes are OK. Angstrom python has the same 0 write issue as the C++ code.

Sidenote: 
We're using custom hardware using the AM335 CPU, not an actual BeagleBone.
uname -a
Linux armxl 3.14.26 #1 Wed May 24 20:21:49 CEST 2017 armv7l GNU/Linux

cat /proc/cpuinfo 
processor : 0
model name : ARMv7 Processor rev 2 (v7l)
Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x3
CPU part : 0xc08
CPU revision : 2
Hardware : Generic AM33XX (Flattened Device Tree)
Revision : 0000
Serial : 0000000000000000

LabJack Support
labjack support's picture
On my BeagleBone, I'm able to

On my BeagleBone, I'm able to get i2c_eeprom.c (from here https://labjack.com/support/software/examples/ljm/c) to work correctly on the initial attempt subsequent to device power-cycle.

It looks like you've accidentally swapped your I2C_SDA_DIONUM and I2C_SCL_DIONUM on C++:

"...01 13 EC 01 00 11" and "...01 13 ED 01 00 10" in py1_Raspberry1500.log_.h, but 
"...01 13 EC 01 00 10" and "...01 13 ED 01 00 11" in normal_Raspberry1500.log_.h.

If you're not already using the latest beta firmware version, please update using the Kipling updater on a non-ARM computer and please let me know if that fixes the issue.

My BeagleBone's stats:

uname -a
Linux beaglebone 3.8.13-bone70 #1 SMP Fri Jan 23 02:15:42 UTC 2015 armv7l GNU/Linux

cat /proc/cpuinfo processor : 0 model name : ARMv7 Processor rev 2 (v7l) BogoMIPS : 298.24 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc08 CPU revision : 2 Hardware : Generic AM33XX (Flattened Device Tree) Revision : 0000 Serial : 0000000000000000
LabJack Support
labjack support's picture
Just to say explicitly: the

Just to say explicitly: the LabJackM-*-Raspbian-Linux-armhf.tar.gz builds are the correct LJM build for your arm device.

Also, just wanted to make sure you're aware of our I2C app note:

https://labjack.com/support/app-notes/i2c

and the I2C section of the T7 datasheet:

https://labjack.com/support/datasheets/t7/digital-io/i2c

Note: writing 1 to bit 0 of I2C_OPTIONS will reset the I2C bus before attempting communication.

Einar Jón
einarjon's picture
OK. After a firmware upgrade

OK. After a firmware upgrade and using the correct library (LabJackM-*-Raspbian-Linux-armhf.tar.gz), this seems to be working fine in both python and C++.

As I posted on Tue, 05/23/2017 - 07:31, correct setting for me is I2C_SDA_DIONUM = 17 and I2C_SCL_DIONUM = 16.
I must have tried to swap them along the way in the C code and forgot to set them back.