-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
stm32: Add method for statically configuring pin alternate function #3952
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
stm32: Add method for statically configuring pin alternate function #3952
Conversation
ports/stm32/pin_static_af.h
Outdated
|
||
#define mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn, type) \ | ||
mp_hal_pin_config(pin_obj, mode, pull, STATIC_AF(pin_obj, fn, type)); \ | ||
_Static_assert(STATIC_AF(pin_obj, fn, type) != -1, "Missing AF") |
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.
It would be good to use MP_STATIC_ASSERT
here. _Static_assert
is a C11 feature and we only require C99.
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.
Hadn't seen that macro, thanks for the heads up
c2d13e9
to
682cb20
Compare
Unfortunately it doesn't seem to work, because the ST HAL defines constants like |
ports/stm32/boards/make-pins.py
Outdated
for af in named_pin.pin().alt_fn: | ||
func = "%s%d" % (af.func, af.fn_num) if af.fn_num else af.func | ||
pin_type = (af.pin_type or "NULL").split('(')[0] | ||
STATIC_AF.add(" (pin_obj) == (pin_%s) && STATIC_AF_ ## fn ## _ ## type == STATIC_AF_%s_%s ? (%d) : \\" % ( |
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'd suggest to change it to just STATIC_AF_ ## fn_type
, and pass in fn and type as one entity, eg SDIO_D0
.
ports/stm32/boards/make-pins.py
Outdated
print(" STATIC_AF_%s_%s," % (func, pin_type), file=af_defs_file) | ||
|
||
print("};\n", file=af_defs_file) | ||
print("#define STATIC_AF(pin_obj, fn, type) \\", file=af_defs_file) |
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.
Would work if changed to STATIC_AF(pin_obj, fn_type)
I was trying to use the macro with sdcard.c, lines 153-158. |
Oh, are the fn tokens being expanded before they get joined to the unit for you? I did wonder if it would be better to just pass in the entire enum value |
Yes. I think with FMC it wasn't, but other periphs are.
Maybe that is a better idea. Less macro magic, less things to go wrong. At the expense of more typing. But it's not much more typing. |
0d3d068
to
c26e2ec
Compare
Ok it's set up to pass the enum as the arg now, looks to be working well on my end. I've updated&rebased the sdram pr to suit as well. |
ports/stm32/pin_static_af.h
Outdated
|
||
#define mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn, type) \ | ||
mp_hal_pin_config(pin_obj, mode, pull, STATIC_AF(pin_obj, fn, type)); \ | ||
MP_STATIC_ASSERT(STATIC_AF(pin_obj, fn, type) != -1) |
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.
It looks like this is not updated to take just the single arg fn/type arg...?
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.
darn, I had fixed that.... I'm going to claim it as a rebase fail
c26e2ec
to
fb5965b
Compare
I was about to merge, and double checking it, but unfortunately it still has some problems! The point is that the compiler doesn't know that pin objects have distinct addresses. So it can't optimise something like this: &pin_A1_obj == &pin_A0_obj ? 1 :
&pin_A1_obj == &pin_A1_obj ? 2 :
-1 The first check may succeed if |
Doesn't having the |
ok, to test I've updated
This still compiles, so I'm pretty sure |
Two ways: 1) inspect the assembly output; 2) use I found this issue when converting sdcard.c to use the new macro, the SDMMC2 path. It only happens when the same AF is available on more than one pin. |
Yep thanks, I've confirmed the issue. Not yet sure how to resolve this one, I've tried a few games with casting / const'ing in the auto-generated table to no avail.... not sure I fully understand the root cause yet, need more investigation. |
fb5965b
to
32373a3
Compare
I reckon I've got it sorted. Turns out the compiler is happy to coimpile-time calculate strcmp. I've left the (#defined out) version of the macro/function used to confirm that it is statically constant and working, looks good for the sdcard on the 769disc target too. I've lost track of the number of trials it took to get this far... geez I hate macro magic. Why can't they just bring constexpr from c++ back into c! The autogenerated file however is now a much simpler format, similar to your other initial suggestion. The stringify's are more efficient again, but at the expense of being more strict about the format of the pin definition being passed in. I don't see this being a problem though? |
Thanks a lot for working on this, it does look a lot better now. Really glad you found a way to fix it! But still one minor thing: the This could possibly be fixed by making As a workaround, I tried changing the
It should be ok. It does mean though that you must have the correct number of parenthesis, so this won't work: mp_hal_pin_config_alt_static(pyb_pin_SD_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_CK); it instead needs to be (not extra parenthesis): mp_hal_pin_config_alt_static((pyb_pin_SD_CK), MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_CK); But I'd say that's acceptable. These pin definitions should anyway be specified in mpconfigboard.h where everything uses parenthesis. And it'll give an error if the parenthesis are wrong because it won't match any of the strings. In summary: if you're happy changing -1 to 0xffffffffffffffffULL then it's good to go (and I can do this during merge if you like). |
Works with pins declared normally in mpconfigboard.h, eg. (pin_XX) Provides new mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn, type) function declared in pin_static_af.h to allow configuring pin alternate functions by name
32373a3
to
a48a18e
Compare
Ah, I forgot to test that it still worked with Yeah I do feel a little uncomfortable about the somewhat-hidden restriction on pin label/defining format this this macro magic enforces. Perhaps it would be possible to spin the macro's more to be slightly more flexible on brackets, but nothing really comes to mind. Do you have any objection to two ps. thanks so much for building a platform with enforced no-warnings, it's fantastic to see that in an open-source project of this size! |
That's ok. I checked the latest version of this PR and verified that it all works as expected now. And I've now merged it in 4343c93 . sdcard.c was switched to use this new function/macro in 4201f36 Thanks for the effort on this!
You're welcome! |
Some ports need an extra operation to ensure that the main task is awoken so that a queued background task will execute during an ongoing light sleep. This removes the need to enable supervisor ticks while I2SOut is operating. Closes: micropython#3952
Works with pins declared normally in mpconfigboard.h, eg. (pin_XX)
Provides new
mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn, type)
functiondeclared in
pin_static_af.h
to allow configuring pin alternate functions by nameeg.
For a full usage example see: #3940