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

add a way to query supported features and version #41

Open
soundanalogous opened this issue Nov 1, 2015 · 6 comments
Open

add a way to query supported features and version #41

soundanalogous opened this issue Nov 1, 2015 · 6 comments
Milestone

Comments

@soundanalogous
Copy link
Member

We currently have the capability query to return pin-based capabilities that sorta serves this function. An improvement however would be to add a separate query that returns the features supported by the firmware. This would open up the ability to version features separately.

Of the existing pin modes, I'd consider the following as "features" since they require multiple pins in some cases and/or represent a feature that is not integral to the microcontroller HW:

  • SERVO
  • I2C
  • ONEWIRE
  • STEPPER
  • ENCODER
  • MODE_SERIAL
  • SHIFT (even though it has never been implemented)

And the following as "pin modes" since the represent supported modes of a given pin:

  • INPUT
  • MODE_INPUT_PULLUP (new)
  • OUTPUT
  • ANALOG
  • PWM

Adding the ability to version features separately would enable updating features without requiring a bump to the protocol version. For example if the Firmata I2C implementation needed to change in a backwards compatible way (to support multiple I2C ports for example). Otherwise the protocol major version would need to be incremented each time a feature is changed in a non-backwards compatible way. It would also enable adding new features that are sysex-based without needing to update the protocol version since the new features would report their own versions. This creates a separation from the higher level Firmata core protocol and the extended feature-level protocols.

A major change (Firmata 3.0) would be to create a separation between "pin modes" and "features". But even before 3.0 it would be possible to start reporting Features and their versions separately via a new feature query. This also enables versioning of features without needing to add anything new (to query version) to existing implementation of existing features.

Here's an initial proposal:

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x62)
2  1st FEATURE_ID LSB         either a "pin mode" or the subcommand byte
3  1st FEATURE_ID MSB         use 2 bytes to ensure scalability
4  1st FEATURE_MAJOR_VERSION  (0-127)
5  1st FEATURE_MINOR_VERSION  (0-127)
6  2nd FEATURE_ID LSB
7  2nd FEATURE_ID MSB
8  2nd FEATURE_MAJOR_VERSION  (0-127)
9  2nd FEATURE_MINOR_VERSION  (0-127)
... for all supported features
n  END_SYSEX                  (0xF7)

For StandardFirmata this would return the following features:

  • SERVO
  • I2C

For StandardFirmataPlus it would return the following features:

  • SERVO
  • I2C
  • MODE_SERIAL

For ConfigurableFIrmata it could return any variation, same for other "firmatas".

@soundanalogous soundanalogous added this to the v2.6 milestone Nov 1, 2015
@soundanalogous
Copy link
Member Author

related discussion in #40

@soundanalogous
Copy link
Member Author

Since DeviceFirmata should take care of most devices, the FEATURE ID can be shortened to a single byte:

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x62)
2  1st FEATURE_ID             (the command ID, eg Serial = 0x60, Stepper = 0x72)
4  1st FEATURE_MAJOR_VERSION  (0-127)
5  1st FEATURE_MINOR_VERSION  (0-127)
6  2nd FEATURE_ID
8  2nd FEATURE_MAJOR_VERSION  (0-127)
9  2nd FEATURE_MINOR_VERSION  (0-127)
... for all supported features
n  END_SYSEX                  (0xF7)

I'm not sure yet if all features should be reported (including AnalogInput, DigitalInput, DigitalOutput, etc), or only optional-features and contributed features. The reason to exclude some core features is they will continue to be reported by the capability query, whereas features such as OneWire, Stepper, etc would no longer need to be reported by the capability query. The capability query would be reserved for reporting pin-specific capabilities. I'm not sure yet if that would still included features such as I2C and Serial that utilize multiple pins. It would probably be better to query those pins via a function of the respective feature.

@soundanalogous
Copy link
Member Author

soundanalogous commented Nov 7, 2016

Probably still worth allocating 2 bytes for the ID to ensure scalability:

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x65)
2  1st FEATURE_ID             (the command ID, eg Serial = 0x60, Stepper = 0x62)
3  RESERVED for 2 byte feature ID (default = 0)
4  1st FEATURE_MAJOR_VERSION  (0-127)
5  1st FEATURE_MINOR_VERSION  (0-127)
6  2nd FEATURE_ID
7  RESERVED for 2 byte feature ID (default = 0)
8  2nd FEATURE_MAJOR_VERSION  (0-127)
9  2nd FEATURE_MINOR_VERSION  (0-127)
... for all supported features
n  END_SYSEX                  (0xF7)

Bugfix version not necessary since it doesn't change anything about the API and we need to save some bytes here. Tempted to limit feature versioning to a single byte rather than semver, but then it gets tricky to track impact of change.

@soundanalogous
Copy link
Member Author

soundanalogous commented Nov 7, 2016

Another approach for versioning would be to use a single value for the version to be incremented for any backwards compatible change. If a non backwards compatible change is introduced, a new FEATURE_ID should be allocated for the feature. That would ensure that no exiting Firmata client APIs would break. In this approach the single value would essentially be the minor version. The major version would increment for each new FEATURE_ID and a bugfix version could be tracked if necessary, it just wouldn't be reported.

@soundanalogous
Copy link
Member Author

soundanalogous commented Nov 13, 2016

Rereading the sysex documentation from a midi spec book, it states that first byte in a System Exclusive message should be the ID. This was for the initial set of manufacturer IDs (1 - 127). If the ID is 0, then the next two bytes are used as extensions to the manufacturer ID (0 - 16383). So this is another approach and perhaps makes the most sense since it was the original intent and some midi parsers may even expect this structure. It could also be a way to help keep the feature report short since an ID of 0 would indicate that 2 additional ID bytes should follow, otherwise assume only a 1 byte ID. The general sysex message structure would then look like this and could be the model for all future Firmata features that use sysex:

byte 0 byte 1 bytes 2 - N-1 byte N
START_SYSEX ID (1-127) PAYLOAD END_SYSEX
START_SYSEX ID (0) EXTENDED_ID (0-16383) + PAYLOAD END_SYSEX

This is how the REPORT_FEATURES reply would look, note that because 0 signals extended ID we only need a single byte for the ID if the value is > 0.

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x65)
2  1st FEATURE_ID             (1-127, eg: Serial = 0x60, Stepper = 0x62)
3  1st FEATURE_MAJOR_VERSION  (0-127)
4  1st FEATURE_MINOR_VERSION  (0-127)
5  2nd FEATURE_ID             (1-127)
6  2nd FEATURE_MAJOR_VERSION  (0-127)
7  2nd FEATURE_MINOR_VERSION  (0-127, eg: Serial = 0x60, Stepper = 0x62)
8  3rd FEATURE_ID             (0x00 - signals extended ID)
9  3rd FEATURE_ID             (lsb)
10 3rd FEATURE_ID             (msb)
...for all supported features
n  END_SYSEX                  (0xF7)

@soundanalogous
Copy link
Member Author

soundanalogous commented Nov 16, 2016

Final draft:

REPORT_FEATURES_QUERY

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x65)
2  REPORT_FEATURES_QUERY      (0x00)
3  END_SYSEX                  (0xF7)

REPORT_FEATURES_RESPONSE

0  START_SYSEX                (0xF0)
1  REPORT_FEATURES            (0x65)
2  REPORT_FEATURES_RESPONSE   (0x01)
3  1st FEATURE_ID             (1-127, eg: Serial = 0x60, Stepper = 0x62)
4  1st FEATURE_MAJOR_VERSION  (0-127)
5  1st FEATURE_MINOR_VERSION  (0-127)
6  2nd FEATURE_ID             (1-127, eg: Serial = 0x60, Stepper = 0x62)
7  2nd FEATURE_MAJOR_VERSION  (0-127)
8  2nd FEATURE_MINOR_VERSION  (0-127)
9  3rd FEATURE_ID             (0x00, Extended ID)
10 3rd FEATURE_ID             (lsb)
11 3rd FEATURE_ID             (msb)
12 3rd FEATURE_MAJOR_VERSION  (0-127)
13 3rd FEATURE_MINOR_VERSION  (0-127)
...for all supported features
n  END_SYSEX                  (0xF7)

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

No branches or pull requests

1 participant