8000 stm32/mphalport.c: Set AFR first before changing GPIO mode. by iabdalkader · Pull Request #8539 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

stm32/mphalport.c: Set AFR first before changing GPIO mode. #8539

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

Conversation

iabdalkader
Copy link
Contributor
  • In mp_hal_pin_config a valid alternate function should be set first in AFR before switching GPIO MODER to GPIO_MODE_AF. This matches the GPIO configuration order in all HAL_GPIO_Init functions.

Note the actual issue that I'm trying to fix: I call mp_hal_pin_config on reset from early_init, to switch USB pins to GPIOs temporarily and then switch them back to alternate functions, and without this fix I get the following errors in dmesg:

[19250.580704] usb usb6-port1: Cannot enable. Maybe the USB cable is bad?

@dpgeorge
Copy link
Member

I can see how this is necessary when switching a GPIO to AF, that you need to select the function first.

But what about switching from AF (to eg output)? In that case wouldn't you want to leave the function as-is until after the mode is changed? Otherwise it may glitch, eg become an MCO1 pin (which is AF=0) for a brief moment before becoming an output pin.

@iabdalkader
Copy link
Contributor Author

How about this:

if (mode == MP_HAL_PIN_MODE_ALT) {
    gpio->AFR[pin >> 3] = ...;
}
gpio->MODER = ...;

If switching from IN/OUT -> AF, a valid AF will be set in AFR before changing the mode, and if switching from AF -> IN/OUT, then a valid AF will be in AFR when mode is changed.

@dpgeorge
Copy link
Member

Yes that looks good! Would be good to also add a comment to that block to explain the subtleties.

@iabdalkader
Copy link
Contributor Author

Yes that looks good! Would be good to also add a comment to that block to explain the subtleties.

Done. Side note, why does this code right shifts by 2 when all the HAL libs right shift by 4?

gpio->OTYPER = (gpio->OTYPER & ~(1 << pin)) | ((mode >> 2) << pin);
//H7
temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << position);

@dpgeorge
Copy link
Member

Side note, why does this code right shifts by 2 when all the HAL libs right shift by 4?

Because OTYPER is just one bit, whether it's push-pull or open-drain. In the HAL constants that bit is encoded in the second nibble, whereas in MicroPython's constants (eg MP_HAL_PIN_MODE_OPEN_DRAIN) it's encoded in the 3rd bit.

* To avoid any I/O glitches in mp_hal_pin_config, make sure a valid
alternate function is set in AFR first before switching the pin mode.
When switching from AF to INPUT or OUTPUT, the AF in AFR will remain
valid up until the pin mode is switched.
@dpgeorge
Copy link
Member

Merged in 71afed1

@dpgeorge dpgeorge closed this Apr 20, 2022
@iabdalkader iabdalkader deleted the gpio_afr branch April 20, 2022 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0