stm32-rs / stm32l0xx-hal

A hardware abstraction layer (HAL) for the STM32L0 series microcontrollers written in Rust
BSD Zero Clause License
96 stars 60 forks source link

GPIO Pin#downgrade doesn't fully erase Port identifier #189

Closed blakesmith closed 3 years ago

blakesmith commented 3 years ago

Hi friends!

If you need to gather an array of GPIO pins, that have different types (including different port numbers), the suggested approach is to use something like PA0.downgrade() to erase the underlying pin identifier and port from the type.

When using the stm32f0xx-hal crate, this fully erases the pin number and port from the type. Notice how the struct returned is just a Pin struct, allowing pins with different ports and pin numbers to be used in an array.

The stm32l0xx-hal crate also implements downgrade, but it only erases the pin number, and not the port. Because it doesn't erase the port identifier, it prevents storing an array of pins with different types. Storing a separate array for each port identifier type would eliminate a single ordering across all pins.

I'm considering two ways to fix this:

  1. Change downgrade to return a fully erased Pin type, instead of a port specific one. This would be a breaking change for anyone who's depending on downgrade to return port specific types.
  2. Add a new downgrade_fully method, or something similarly named to return the fully erased Pin. Upside is: No breaking API changes with outstanding users who are dependent on the types being stable, downside is: the downgrade_fully would deviate from other stm32-hal implementations.

I can make choice 1 work for a private fork of stm32l0xx-hal, but would ideally love to be able to push this upstream so I don't need to run on a private fork anymore. I'd love to get people's weigh-in on this.

Thanks so much for the crate!

dbrgn commented 3 years ago

I'd tend towards number 1, but are there any use cases where an erased pin but a non-erased port would be important?

jamwaffles commented 3 years ago

My vote goes for number 1 as well

blakesmith commented 3 years ago

Thanks for the weigh-in everyone! I'll work on a PR to change downgrade to remove port typing.

are there any use cases where an erased pin but a non-erased port would be important?

The only one I've encountered is when I need to change multiple GPIO pins on a single port, that share a common register (changing multiple bits in a single GPIO register to affect multiple pins). This use-case isn't really possible with these Pin APIs in most MCU hal crates... We'd need some sort of PortPinGroup type that could wrap the GPIO register(s) for each port.

blakesmith commented 3 years ago

Closed by #190. Thanks everyone!