Skip to content

Remove delays #40

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

Closed
wants to merge 1 commit into from
Closed

Conversation

dunkmann00
Copy link
Contributor

This fixes #39.

I tested this code on an itsybitsy m4 express and everything worked as expected. It was even returning the firmware version on the first attempt.

@@ -83,7 +83,6 @@ def _wait_ready(self, timeout=1):
with self._i2c:
self._i2c.readinto(status)
except OSError:
self._wakeup()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that when you issue a command to the PN532 _wait_ready is called before it is ready to respond, which results in an OSError. I tried to check in CP what error was being triggered and it was a NACK. When I removed this line it ends up only taking a few milliseconds to send the ready status. But with this line, it got stuck sleeping for half a second. And if there is no _req pin setup, the only thing that self._wakeup does is sleep for half a second, which is overkill for here.

It is also worth noting that this problem didn't present itself on older versions of CP for me. I think some of the newer performance improvements are the reason this is surfacing. _wait_ready was never called fast enough after a command to cause the OSError to be thrown like it is now. Sooo that's kind of cool lol.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that when you issue a command to the PN532 _wait_ready is called before it is ready to respond, which results in an OSError. I tried to check in CP what error was being triggered and it was a NACK. When I removed this line it ends up only taking a few milliseconds to send the ready status. But with this line, it got stuck sleeping for half a second. And if there is no _req pin setup, the only thing that self._wakeup does is sleep for half a second, which is overkill for here.

Why not return early from _wakeup if _req isn't available? Seems like we do want the ability to sleep and wake the device.

It is also worth noting that this problem didn't present itself on older versions of CP for me. I think some of the newer performance improvements are the reason this is surfacing. _wait_ready was never called fast enough after a command to cause the OSError to be thrown like it is now. Sooo that's kind of cool lol.

🎉 Does the OSError vary depending on whether it's asleep or waking up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not return early from _wakeup if _req isn't available? Seems like we do want the ability to sleep and wake the device.

That seems like a good idea.

🎉 Does the OSError vary depending on whether it's asleep or waking up?

It doesn't seem to matter. I'm not 100% sure, but when running one of the simple examples each time you loop through it you always get the same OSError.

I've been looking through the PN532 manual, and while I definitely am not familiar with reading this kind of thing, so I could be wrong, but I think the issue doesn't have to do with waking up. At least not the problem I was seeing.

Screen Shot 2020-08-25 at 8 51 00 PM

I think waking up happens in between I2C address Write and COMMAND frame. The OSError is being thrown when we try to read in between COMMAND frame and I2C address Read + Acknowledge frame. So wouldn't calling _wakeup be unnecessary?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know anything about the sensor itself. Does it power down automatically or can we track when the driver shuts it down?

@dunkmann00
Copy link
Contributor Author

In the event that we do have _req connected I think we are supposed to call it first, before any command is sent.

Here is another excerpt from the manual:

Fig 43. Handshake in case of I2C link – case 2

And the relevant text that follows:

  • The PN532 is in Power Down mode (T_PD1),
    The host controller wants to send a frame to the PN532, and so it asserts the H_REQ line. That makes the PN532 waking up (1) and it acknowledges with P70_IRQ pin (2),
  • Then before sending the command frame (3), the host controller has 2 possibilities:
    • either the host controller waits for a defined delay (twup) which guarantees in that case that the PN532 will be waken up when the I2C frame will be sent,
    • or the host controller monitors the P70_IRQ pin to check when the PN532 is woken up (with a maximum timeout of twup). This option can optimize the overall waiting time if the PN532 was not asleep; there is no need to wait the maximum wakeup time (tready < twup).

@dunkmann00
Copy link
Contributor Author

Closing this in favor of #41.

@dunkmann00 dunkmann00 closed this Sep 10, 2020
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

Successfully merging this pull request may close these issues.

I2C delays slowing down code
3 participants