Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i2cdriver hardware hangs up #30

Closed
codehero opened this issue Jan 20, 2020 · 18 comments
Closed

i2cdriver hardware hangs up #30

codehero opened this issue Jan 20, 2020 · 18 comments

Comments

@codehero
Copy link

There should be no issue at all receiving echo responses. i2cdriver fails to respond.
I am not a MyForth expert nor will I ever be, but I don't see that the watchdog timer is used. I don't see any exception vectors handled either. This looks like it could be a 5 star product but it needs the basics covered!

openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2) = 2
read(3,

@jamesbowman
Copy link
Owner

Right, I see this:

$ strace ./build/i2ccl /dev/ttyUSB3 i
...
openat(AT_FDCWD, "/dev/ttyUSB3", O_RDWR|O_NOCTTY) = 4
ioctl(4, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(4, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(4, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(4, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(4, "eA", 2)                       = 2
read(4, "A", 1)                         = 1

This might just be a bad unit. So please can you confirm the basics:

  • has it ever connected, or has it got into some hung state before this?
  • that port /dev/ttyUSB0 is your I2CDriver, and not some other device
  • that nothing is plugged into the I2CDriver's I2C ports, at least to begin with

The firmware does catch failures, using the SiLabs EFM8 system of timers and interrupts.

@codehero
Copy link
Author

I have only tested with an I2C slave microcontroller. I have connected to this microcontroller before with Linux GPIO I2C.

I am 100% sure /dev/ttyUSB0 is the I2CDriver FT230X device

I am not sure what you mean by "that nothing is plugged into the I2CDriver's I2C ports, at least to begin with"? Do you mean on power up, on i2c_connect()? Please provide specific context.

You say the FW catches failures, but if it does they are not reported to the user via serial. For example if there is a watchdog failure, a brownout condition or some other exceptional HW condition this should be reported via serial. There is no bootup message sent out over UART when the unit starts. There is no pulse from the unit. There isn't even a blinking light on the OLED display.

@jamesbowman
Copy link
Owner

At startup, the display should look like this:

image

To clarify, by "nothing plugged in" I mean no I2C peripherals are connected. So the full procedure:

  1. Take I2CDriver, with no I2C peripherals connected
  2. connect USB cable
  3. confirm that the I2CDriver display lights up, as shown above
  4. confirm the USB port as /dev/ttyUSBx
  5. Use "i2ccl /dev/ttyUSBx i" to confirm that the I2CDriver is alive

Or have you already reached this point?

@codehero
Copy link
Author

codehero commented Jan 20, 2020

This point has worked for me before. I have tried a few more times and got this

openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2) = 2
read(3, "A", 1) = 1
write(3, "e\r", 2) = 2
read(3, "\r", 1) = 1
write(3, "e\n", 2) = 2
read(3, "\n", 1) = 1
write(3, "e\0", 2) = 2
read(3, "\0", 1) = 1
write(3, "?", 1) = 1

@codehero
Copy link
Author

openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1996592, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb7fde41000
mmap(NULL, 2004992, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fb7fdc57000
mprotect(0x7fb7fdc79000, 1826816, PROT_NONE) = 0
mmap(0x7fb7fdc79000, 1511424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7fb7fdc79000
mmap(0x7fb7fddea000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x193000) = 0x7fb7fddea000
mmap(0x7fb7fde37000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1df000) = 0x7fb7fde37000
mmap(0x7fb7fde3d000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fb7fde3d000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fb7fde42540) = 0
mprotect(0x7fb7fde37000, 16384, PROT_READ) = 0
mprotect(0x559d19931000, 4096, PROT_READ) = 0
mprotect(0x7fb7fde80000, 4096, PROT_READ) = 0
munmap(0x7fb7fde43000, 78628) = 0
openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2) = 2
read(3,

@codehero
Copy link
Author

So sometimes I get a hangup and sometimes I don't. When it does hangup I have to power cycle and the Voltage reading never changes.

@jamesbowman
Copy link
Owner

OK, I think what you are saying is that the I2CDriver display and communications are working, and that after some communication with a microcontroller I2C Slave, the I2CDriver can hang.

Can you provide any more details on the I2C transaction that leads to the hang?

@codehero
Copy link
Author

codehero commented Jan 20, 2020

New information here!

Three program invocations.
The first shows code with no bugs. This runs fine.
The second has the following bugs: Single character strings are mistyped as single characters ("a" vs 'a'). This shows an address error in strace
The third invocation the code is run without the bug and exhibits the no response behaviour.

This is quite possible a bug in the Linux ftdi driver. Or it is a bug in your FW. I don't know which. I think I have given you enough to reproduce it. Please ask more questions if needed.

TRACES

This runs fine

openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B9600 opost isig icanon echo ...}) = 0
ioctl(3, TCGETS, {B9600 opost isig icanon echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2)                       = 2
read(3, "A", 1)                         = 1
write(3, "e\r", 2)                      = 2
read(3, "\r", 1)                        = 1
write(3, "e\n", 2)                      = 2
read(3, "\n", 1)                        = 1
write(3, "e\0", 2)                      = 2
read(3, "\0", 1)                        = 1
write(3, "?", 1)                        = 1
read(3, "[i2cdriver1 DO01JT5U 000000013 4"..., 80) = 80
close(3)                                = 0
openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2)                       = 2
read(3, "A", 1)                         = 1
write(3, "e\r", 2)                      = 2
read(3, "\r", 1)                        = 1
write(3, "e\n", 2)                      = 2
read(3, "\n", 1)                        = 1
write(3, "e\0", 2)                      = 2
read(3, "\0", 1)                        = 1
write(3, "?", 1)                        = 1
read(3, "[i2cdriver1 DO01JT5U 000000013 4"..., 80) = 80
write(3, "x", 1)                        = 1
write(3, "r", 1)                        = 1
write(3, "1", 1)                        = 1
write(3, "i", 1)                        = 1
write(3, "sb", 2)                       = 2
read(3, "3", 1)                         = 1
write(3, "\300\1", 2)                   = 2
read(3, "\0", 1)                        = 1
write(3, "p", 1)                        = 1
exit_group(0)                           = ?

This does not

openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2)                       = 2
read(3, "A", 1)                         = 1
write(3, "e\r", 2)                      = 2
read(3, "\r", 1)                        = 1
write(3, "e\n", 2)                      = 2
read(3, "\n", 1)                        = 1
write(3, "e\0", 2)                      = 2
read(3, "\0", 1)                        = 1
write(3, "?", 1)                        = 1
read(3, "[i2cdriver1 DO01JT5U 000000095 4"..., 80) = 80
close(3)                                = 0
openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2)                       = 2
read(3, "A", 1)                         = 1
write(3, "e\r", 2)                      = 2
read(3, "\r", 1)                        = 1
write(3, "e\n", 2)                      = 2
read(3, "\n", 1)                        = 1
write(3, "e\0", 2)                      = 2
read(3, "\0", 1)                        = 1
write(3, "?", 1)                        = 1
read(3, "[i2cdriver1 DO01JT5U 000000095 4"..., 80) = 80
write(3, 0x78, 1)                       = -1 EFAULT (Bad address)
write(3, 0x72, 1)                       = -1 EFAULT (Bad address)
write(3, 0x31, 1)                       = -1 EFAULT (Bad address)
write(3, 0x69, 1)                       = -1 EFAULT (Bad address)
write(3, "sb", 2)                       = 2

This is the error I was seeing:

openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1996592, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa155353000
mmap(NULL, 2004992, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fa155169000
mprotect(0x7fa15518b000, 1826816, PROT_NONE) = 0
mmap(0x7fa15518b000, 1511424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7fa15518b000
mmap(0x7fa1552fc000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x193000) = 0x7fa1552fc000
mmap(0x7fa155349000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1df000) = 0x7fa155349000
mmap(0x7fa15534f000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fa15534f000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fa155354540) = 0
mprotect(0x7fa155349000, 16384, PROT_READ) = 0
mprotect(0x55d7700c8000, 4096, PROT_READ) = 0
mprotect(0x7fa155392000, 4096, PROT_READ) = 0
munmap(0x7fa155355000, 78628)           = 0
openat(AT_FDCWD, "/dev/ttyUSB0", O_RDWR|O_NOCTTY) = 3
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B1000000 -opost -isig -icanon -echo ...}) = 0
write(3, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"..., 64) = 64
write(3, "eA", 2)                       = 2
read(3,

@codehero
Copy link
Author

I should note that I am running on an osboxes ubuntu VM

Linux osboxes 4.18.0-25-generic #26-Ubuntu SMP Mon Jun 24 09:32:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

@jamesbowman
Copy link
Owner

Aha, thanks. What is running this on the Linux box? I assume it is C code that you have for driving the I2CDriver, but want to confirm.

@codehero
Copy link
Author

This is all C code. Not sure I understand why I would need 2 separate reads after 'a N' (read N bytes with ack). It seems I need 1 call for the status and 1 for the data. Why is this so?

@jamesbowman
Copy link
Owner

Looking at the trace... first observation is that the 'x' (bus reset) command sends a response bye back, with the state of SDA,ACL lines in the two low bits.
Am updating the C sample code to include reset now.

@codehero
Copy link
Author

Thanks for patching, but can you please just fix up the documentation with precise definitions of what commands are accepted and precisely what responses are sent back.

First off page 24 talks about toggling a CS??? line with commands not even in the table.
Apparently '_' is a command in the code and it's not in the DOCS???

Please go back and fix the documentation so someone skilled in the art can write a proper C API for it. The only reason I haven't tossed this product in the junk bin is because I think it is fundamentally good and just needs some rigorous attention.

@jamesbowman
Copy link
Owner

Agreed, on it.

@jamesbowman
Copy link
Owner

Updated doc, section 7.4 has all the core commands:

https://i2cdriver.com/i2cdriver.pdf

Capture mode is TBD.

@jamesbowman
Copy link
Owner

Did you get a chance to look at the updated docs? They should have enough detail to write an API.

Reading through the C reference code, I notice that it is incorrect for long (>64 byte) reads, and have raised #34 for the fix.

@codehero
Copy link
Author

Yes I have and it makes more sense now. I am going forward with my own C code from scratch given your docs. I am looking forward to monitor mode!

jamesbowman added a commit to jamesbowman/datasheets that referenced this issue Jan 25, 2020
@jamesbowman
Copy link
Owner

OK to close this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants