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

New command: digital read port (A, B) #62

Open
rwaldron opened this issue Jul 8, 2015 · 6 comments
Open

New command: digital read port (A, B) #62

rwaldron opened this issue Jul 8, 2015 · 6 comments
Assignees

Comments

@rwaldron
Copy link
Contributor

rwaldron commented Jul 8, 2015

To make digital pin reading more efficient:

  • allowing a client to request the values of the entire port, encoded as an 8-bit unsigned int byte
  • "port value" is determined by these parameters:
    • 0 for pins that are enabled for I2C, SPI or UART use
    • 0 for pins that are input or output and currently "low"
    • 1 for pins that are input or output and currently "high"

Pins correspond to bits as:

B7 B6 B5 B4 B3 B2 B1 B0
7 6 5 4 3 2 1 0

For example, if all pins on a given port were in use as digital i/o pins and currently pin 7 is "high" and pins 0-6 are "low", then the port value would be 128:

B7 B6 B5 B4 B3 B2 B1 B0
1 0 0 0 0 0 0 0
@Frijol
Copy link
Member

Frijol commented Jul 8, 2015

I don't understand– can you give an example scenario for using this?

@rwaldron
Copy link
Contributor Author

rwaldron commented Jul 8, 2015

This is actually an optimization taken from the Firmata protocol, it allows client code to get the current value/state of all pins in a given port (port = set of 8 pins) at once, instead of requiring 8 separate reads with 8 corresponding responses. This is also how most IO expansion chips are designed, 8 pins = 1 (8-bit unsigned int) byte. It's a cheap (and very efficient) way to see the state of all 8 pins in a port at once.

I'm going to work on a draft patch

@kevinmehall
Copy link
Member

You could accomplish this without firmware changes by doing a batched sequence of 8 commands to read the 8 pins, which would be one round-trip instead of 8. It would still involve 16 bytes in each direction and dispatching 8 instructions, but that's negligible compared to latency and bridge overhead.

Note that with cork/uncork nonfunctional on domain sockets in the current io.js you can't guarantee that it will go out as a single batch.

@rwaldron
Copy link
Contributor Author

rwaldron commented Jul 9, 2015

I'll try both ways and see which results in the best end-to-end performance

@rwaldron rwaldron self-assigned this Jul 18, 2015
@rwaldron
Copy link
Contributor Author

As part of a larger effort to exploit the async IO potential of an onboard co-processor, I'm going to start working on this again, with a slight change to the plan: it should not be necessary to constantly send requests for pin values or port state. Realistically, a program should be able to send a one time request for any or all of the following:

  • send me the entire port state every N milliseconds.
  • send me the analog input value of pin P, every N milliseconds
  • send me K bytes read from I2C register at address, every N milliseconds

@kevinmehall
Copy link
Member

My original plan was to do this with macro-like sequences that execute multiple times, by adding opcodes like:

BEGIN: start recording a macro. subsequent commands until LOOP are buffered as they are executed.
LOOP: jump back to the preceding BEGIN
CANCEL: the only command legal to be sent after LOOP, makes the loop exit
PERIOD: delays until the specified time has elapsed since the start of this iteration of the loop
GPIO_WAIT: delays until the pin is high/low (to wait for interrupt / "data ready" pins)

with that, you can accomplish all of those and more.

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

3 participants