Closed bartweber closed 1 year ago
The main reason for not implementing this so far is that the hardware does not support it. It has to be emulated with controling OE.
The difference with the st hal (and lots of other silicon) is that they do have support for it in hardware (see stm32f3xx reference manual page 228/1141 – 11.3 GPIO Functional description).
Ai, I should have RTFM first. Somehow I got the idea that all modern micro-controllers have no other option than to emulate the open-drain output. (I'm a software developer for many years but a beginner/hobbyist in embedded programming and electronics.)
In this case I might be better of with an I2C to 1-wire bridge (like the DS2482). No any hassle with the 1-wire protocol. (One disadvantage of this option is though, there no lib written in Rust yet for this device.)
Well, that's an opportunity to write a driver for the weekly driver initiative :-)
Seriously: @ithinuel correctly explained why there is no open-drain output implementation. But that doesn't mean that the rp2040 is unable to speak the 1-wire protocol. If the emulated InOutPin
doesn't work, we should find out why.
I actually considered adding support for open drain/open collector [by fiddling OE] when doing the conversion to the type-based GPIO, but didn't want the added complexity when the original code didn't support it.
I don't think it would be that hard to add.
I probably wouldn't call it open drain/open collector. It works similar, but electrically, it's something different. I'm not knowledgeable enough about electrical circuits to tell if it actually makes a difference, so I'd just be cautious and give it some neutral name. That's why I just called it InOutPin
in the dht11 example.
And yes, it shouldn't be hard to add. Hardest thing would be to find a good API (ie. as flexible as possible without becoming difficult to use).
For convenience, please add an open-drain output implementation. I experimented with the implementation
InOutPin
used in the examplerp2040-hal/examples/dht11.rs
for communication with the 1-wire protocol (i.c.w. a DS18B20), but it seems to be unreliable. (Or more accurately: not working at all.)As stated in the example, it is not possible to drive the pin low before changing the pin mode to output to emulate the open-drain output low state.
It seems to me this cannot be solved by a custom
DynPin
implementation (as is done in the example) and should be solved in the rp2040-hal itself. Hence this ticket.In another hals - e.g. https://github.com/stm32-rs/stm32f3xx-hal - this pin mode is implemented. I would suggest a method like
into_open_drain_output()
as used in:To sum up the requirements (please correct me if I am wrong):
OuputPin
andInputPin
;set_low
is called, the pin should be set to low and switch its internal mode by using the followingModeFields
values:funcsel=SIO_FUNCSEL
,sio_outen = true
,inen = true
and all other fields set to false;set_high
is called, the pin should switch its internal mode by using the followingModeFields
values:funcsel = SIO_FUNCSEL
,sio_outen = false
,inen = true
and all other fields set to false;