- 
  Notifications
 You must be signed in to change notification settings 
- Fork 48
[DNM] zephyrCommon: Changing pin numbering rules #134
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
Conversation
93e11fa to
 084197c  
 Compare
 
 0747e08 to
 014a6ed  
 Compare
 
 7ca4da5 to
 b009050  
 Compare
 
 26d967e to
 bb1ef24  
 Compare
 
 bb1ef24 to
 e8dced1  
 Compare
 
 Just chiming in for the Arduino side to say, please don't drop custom pin numbering.
The technical implementation is great 👍 and it removes the need for bulky pin lists 💛, but AFAICS also makes it "impossible" to assign specific numbers to pins, and this is something that is really important for backwards compatibility with traditional Arduino sketches.
[ OTOH, I do hate having to write those lists; tried several alternative DTS mappings myself but haven't yet found one that is flexible enough and/or enough of an improvement... 🙁 ]
Just chiming in for the Arduino side to say, please don't drop custom pin numbering.
The technical implementation is great 👍 and it removes the need for bulky pin lists 💛, but AFAICS also makes it "impossible" to assign specific numbers to pins, and this is something that is really important for backwards compatibility with traditional Arduino sketches.
[ OTOH, I do hate having to write those lists; tried several alternative DTS mappings myself but haven't yet found one that is flexible enough and/or enough of an improvement... 🙁 ]
The main purpose of this change is to make pins that are not exposed on the connector usable.
The pin change itself is necessary to deal with edge cases, so it needs to remain.
My current idea is to use the zephyrproject-rtos/zephyr#87595 change to extract pin information from the gpio-nexus node that is labeled as arduino_header.
With this method, as long as the connector is defined on the devicetree, I think it will be possible to make it behave like an "Arduino" without writing any additional config. For edge cases that still cannot be solved, I think we'll have to deal with them with the current settings, but some consideration may be needed to find the best way to handle them.
By the way, zephyrproject-rtos/zephyr#87595 is stalled because only a few people reviewed it.
If you can review this part, please help with this PR review.
e8dced1 to
 199421c  
 Compare
 
 199421c to
 934a931  
 Compare
 
 The technical implementation is great 👍 and it removes the need for bulky pin lists 💛, but AFAICS also makes it "impossible" to assign specific numbers to pins, and this is something that is really important for backwards compatibility with traditional Arduino sketches.
Does this mean you want to freely map the direct values passed to digitalOut?
I understand that traditionally, Arduino's D1-based values were logical pin numbers,
while values like digitalOut argument were physical pin numbers (i.e., implementation-dependent).
Until now, the gsoc-2022-arduino-core implementation has assumed logical = physical due to various constraints. (i.e., D0 = 0, D1 = 1)
In this implementation, only mapped pins are usable, so the intention of this PR is to introduce physical pin numbers to handle all pins on the board.
If the answer to the initial question is yes, I think this can be addressed by adding one more LUT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen the PR, and have some catching up to do on the new zephyr commit that has been mentioned. I will need some more time to actually go through since this seems to have a large impact overall. Please excuse the delay!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it me or is the alignment really messed up on this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ayush1325 if possible can you test for any regressions on the Beagleconnect freedom?
I am ok with the general idea here, and it does seem like an improvement for handling gpio ports.
Just need to be careful about the code though, and hence giving some comments from maintenance and debugging perspective.
I'll merge this as soon as I am done fixing the CI failures. Please excuse the delay
@Ayush1325 if possible can you test for any regressions on the Beagleconnect freedom? I am ok with the general idea here, and it does seem like an improvement for handling gpio ports. Just need to be careful about the code though, and hence giving some comments from maintenance and debugging perspective.
Apologies for the late reply. Seems to be working fine on bcf.
@soburi, apologies for getting back so late, was derailed by the linked PR and most importantly all of this week's chaos. 😅
Does this mean you want to freely map the direct values passed to digitalOut?
I understand that traditionally, Arduino's D1-based values were logical pin numbers, while values like digitalOut argument were physical pin numbers (i.e., implementation-dependent).
In fact, and very unfortunately, the "official" way of referring to pins is by number. Some cores don't even define Dx symbols; all samples use integers to access pins, so do 99% of sketches out there... for existing boards, numbers are the standard we need to maintain compatibility with.
In [the current] implementation, only mapped pins are usable, so the intention of this PR is to introduce physical pin numbers to handle all pins on the board.
Understood; with this change you assign a number for any "GPIO bit" (even if unconnected or not even exposed by the SOC!), and then map Dx=x.
If the answer to the initial question is yes, I think this can be addressed by adding one more LUT.
My issue with a LUT is that it will create two sets of indistinguishable integers : the "logical" ones (inputs to the LUT) and the "physical" ones (after the LUT is applied).
Now, 🥁, when a sketch then calls digitalWrite(4, HIGH), does 4 refer to a logical or physical pin?
Surely it must be logical (otherwise, what's the point of the LUT?), but it must also be physical (otherwise, the objective of this PR is broken!). ❓ 🫤
We have been bitten HARD by this with the Arduino Nano ESP32 - the GPIO controller there already uses numbers, but we need to map them to keep "standard Nano" pin layout. We added a LUT so that APIs would input logical and address physical. Chaos ensued, and 2 years later this is still a raw topic on the Arduino Forums.
(brainstorming)
There MAY be a way out. The default index pin type pin_size_t is 8-bit unsigned, and very few targets exceed that (but we do have a 32-bit option by defining EXTENDED_PIN_MODE). What if you enabled that and made your physical mapping in some high enough range? Numbers below, say, 32k would be logical, the others physical.
- All APIs with pin numbers would accept an uint32_tand, if it's logical, apply the LUT to get a physical index.
- As long as you use intor the more correctpin_size_tto store a pin number, you have no problems.
- Existing sketches that use uint8_twork fine on existing boards, because numbers < 256 are definitely logical and thus mapped by the LUT.
- The only issue is if you want to use an existing sketch on previously unmapped physical pins, but then you're breaking new ground, might as well fix the sketch.
(all of this needs a constant LUT, probably magically generated from the DT in some way. Would the recent maps help?)
Let me know what you guys think!
Zephyr's ba48d83b changes make it easy to configure pin numbering at compile, so we'll change the pin numbers to be based on the GPIO pin numbers. This is same as the traditional Arduino, using the GPIO numbers as pin numbers. Pin names written on the board, such as D1 and D2, are aliases for these pin numbers. When using multiple GPIO ports, pin numbers are numbered consecutively from the beginning. For example, if you have two 16-port GPIOs, 16 refers to the first pin (idx=0) of the second port. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Now that GPIO can be specified generically, we will discontinue the definition generation of LED_BUILTIN from builtin_led_gpios. Delete this definition where automatic generation from led0 is not an issue, and define it in variant.h in all other cases. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
934a931 to
 4abaf6a  
 Compare
 
 Sorry for my late response.
@soburi, apologies for getting back so late, was derailed by the linked PR and most importantly all of this week's chaos. 😅
I know it was a difficult situation. You must be tired.
In fact, and very unfortunately, the "official" way of referring to pins is by number. Some cores don't even define
Dxsymbols; all samples use integers to access pins, so do 99% of sketches out there... for existing boards, numbers are the standard we need to maintain compatibility with.
I understood what that means is "all is device dependent'.
And there is a requirement to make it compatible with it.
My issue with a LUT is that it will create two sets of indistinguishable integers : the "logical" ones (inputs to the LUT) and the "physical" ones (after the LUT is applied).
Now, 🥁, when a sketch then calls
digitalWrite(4, HIGH), does4refer to a logical or physical pin? Surely it must be logical (otherwise, what's the point of the LUT?), but it must also be physical (otherwise, the objective of this PR is broken!). ❓ 🫤
In my opinion, they are distinct clearly.
First, there is a need to clarify the terminology.
physical pin number: The number statically derived from the hardware configuration. The 'serialized GPIO pin number' in the my proposal can be derived from the GPIO port and the pin number, so it is a type of "physical pin number".
Logical Pin Number = The number defined by the rule.
Usually, that is ruled by the API specification.
(It is not required in the term definition, but) and it is expected to map to the physical pin number without contradiction.
Of course, "use as is" rule can also be applied in this context.
digitalWrite() (And all other APIs) must take a logical pin number.
The physical pin number is derived via LUT from the logical pin number.
In other words, the physical pin number is just an internal representation. and the logical pin number is an alias for it.
All API must use the logical pin numbering system.
If we keep this principle, it will not cause a serious problem.
We have been bitten HARD by this with the Arduino Nano ESP32 - the GPIO controller there already uses numbers, but we need to map them to keep "standard Nano" pin layout. We added a LUT so that APIs would input logical and address physical. Chaos ensued, and 2 years later this is still a raw topic on the Arduino Forums.
I couldn't understand the details, I need to check a little more carefully.
But as far as I understood,
This seems to be a problem caused by two different numbering systems existing concurrently.
- The API numbering system should always be based on a single rule.
This is the principal.
- In situations where this rule is not followed, individual, topical handling should be taken.
On that basis,
- It is possible to create comprehensive pin mapping.
(brainstorming)
There MAY be a way out. The default index pin type
pin_size_tis 8-bit unsigned, and very few targets exceed that (but we do have a 32-bit option by definingEXTENDED_PIN_MODE). What if you enabled that and made your physical mapping in some high enough range? Numbers below, say, 32k would be logical, the others physical.
Zephyr's pin numbers are specified in 32 bits, so I don't think there's any problem with this policy.
I also think it's a good idea to make EXTENDED_PIN_MODE the default.
Uh oh!
There was an error while loading. Please reload this page.
Zephyr's ba48d83b
changes make it easy to configure pin numbering at compile,
so we'll change the pin numbers to be based on the GPIO pin numbers.
This is same as the traditional Arduino, using the GPIO numbers as
pin numbers. Pin names written on the board, such as D1 and D2,
are aliases for these pin numbers.
When using multiple GPIO ports, pin numbers are numbered consecutively
from the beginning. For example, if you have two 16-port GPIOs,
16 refers to the first pin (idx=0) of the second port.